Merge master into fh/mymaster

This commit is contained in:
Flyinghead 2018-08-13 18:01:24 +02:00
commit 04b84b90e3
220 changed files with 6402 additions and 4721 deletions

7
.gitignore vendored
View File

@ -6,11 +6,6 @@ bin/
gen/
obj/
newdc/android/libnewdc/bin/libnewdc.jar
newdc/android/libnewdc/bin/classes/com/example/newdc/JNIdc.class
shell/android/assets/build
# iOS/Xcode general stuff
.DS_Store
*/build/*
@ -57,4 +52,4 @@ reicast-ios.xccheckout
.idea
*.iml
.externalNativeBuild
shell/android-studio/app/src/main/assets/build
shell/android-studio/reicast/src/main/assets/build

6
.travis.yml Normal file → Executable file
View File

@ -44,14 +44,16 @@ install:
- test -z "$encrypted_c726d225a9d9_key" || mv debug.keystore ~/.android/debug.keystore
before_script:
script:
- git fetch --unshallow
- cd shell/android-studio
- export NUMBER_OF_PROCESSORS=2
- "./gradlew build"
- sudo chmod 755 travis-build.sh
- "./travis-build.sh"
- test -z "$encrypted_c726d225a9d9_key" || ./travis-release.sh
before_deploy:
- cd ../../
- mkdir -p artifacts/$GIT_BUILD/
- cp shell/android-studio/app/build/outputs/apk/debug/app-debug.apk artifacts/$GIT_BUILD/reicast-android-debug-$GIT_HASH.apk
- cp shell/android-studio/reicast/build/outputs/apk/debug/reicast-debug.apk artifacts/$GIT_BUILD/reicast-android-debug-$GIT_HASH.apk
deploy:
provider: s3
access_key_id: AKIAJR5J3OHAQUP5BHHQ

View File

@ -139,7 +139,7 @@ Development/Beta versions
| Platform | Status | Downloads
| -------------------------------------------------- | -------------- | ---------
| ![Android](http://i.imgur.com/nK9exQe.jpg) Android | [![Build Status](https://travis-ci.org/reicast/reicast-emulator.svg?branch=master)](https://travis-ci.org/reicast/reicast-emulator) | [Reicast CI Builds](http://builds.reicast.com)
| ![iOS](http://i.imgur.com/6bvAUUj.png) iOS | [![Build Status](https://app.ship.io/jobs/ttUMMV6QrHOy4_yx/build_status.png)](https://app.ship.io/dashboard#/jobs/9843/history) | *TODO*
| ![iOS](http://i.imgur.com/6bvAUUj.png) iOS | [![Build Status](https://app.bitrise.io/app/d082ed2fb1bdeeef.svg?token=39zhSBFh-b9YVJw8q91omw) | *TODO*
| ![Windows](http://i.imgur.com/hAuMmjF.png) Windows | [![Build status](https://ci.appveyor.com/api/projects/status/353mwl73ki74tb58/branch/master?svg=true)](https://ci.appveyor.com/project/skmp/reicast-emulator/branch/master) | [Reicast CI Builds](http://builds.reicast.com)
| ![Linux](http://i.imgur.com/19aAoQD.png) Linux | [![wercker status](https://app.wercker.com/status/bcabca642a2de044c6f58203b975878b/s/master "wercker status")](https://app.wercker.com/project/bykey/bcabca642a2de044c6f58203b975878b) | *TODO*
| ![OSX](http://i.imgur.com/0YoI5Vm.png) OSX | *TODO* | *TODO*

54
bitrise.yml Normal file
View File

@ -0,0 +1,54 @@
---
format_version: '5'
default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git
project_type: ios
trigger_map:
- push_branch: "*"
workflow: primary
- pull_request_source_branch: "*"
workflow: primary
workflows:
deploy:
steps:
- activate-ssh-key@3.1.1:
run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'
- git-clone@4.0.11: {}
- cache-pull@2.0.1: {}
- script@1.1.5:
title: Do anything with Script step
- certificate-and-profile-installer@1.9.3: {}
- recreate-user-schemes@1.0.2:
inputs:
- project_path: "$BITRISE_PROJECT_PATH"
- xcode-archive@2.4.8:
inputs:
- project_path: "$BITRISE_PROJECT_PATH"
- scheme: "$BITRISE_SCHEME"
- export_method: "$BITRISE_EXPORT_METHOD"
- deploy-to-bitrise-io@1.3.12: {}
- cache-push@2.0.5: {}
primary:
steps:
- activate-ssh-key@3.1.1:
run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'
- git-clone@4.0.11: {}
- cache-pull@2.0.1: {}
- script@1.1.5:
title: Do anything with Script step
- certificate-and-profile-installer@1.9.2: {}
- recreate-user-schemes@1.0.2:
inputs:
- project_path: "$BITRISE_PROJECT_PATH"
- deploy-to-bitrise-io@1.3.10: {}
- cache-push@2.0.5: {}
app:
envs:
- opts:
is_expand: false
BITRISE_PROJECT_PATH: shell/apple/emulator-ios/reicast-ios.xcodeproj
- opts:
is_expand: false
BITRISE_SCHEME: reicast-ios
- opts:
is_expand: false
BITRISE_EXPORT_METHOD: ad-hoc

View File

@ -1,9 +1,9 @@
/* arm_init.c - NEON optimised filter functions
*
* Copyright (c) 2014 Glenn Randers-Pehrson
* Copyright (c) 2014,2016 Glenn Randers-Pehrson
* Written by Mans Rullgard, 2011.
* Last changed in libpng 1.6.16 [December 22, 2014]
* Last changed in libpng 1.6.22 [May 26, 2016]
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@ -66,6 +66,7 @@ png_init_filter_functions_neon(png_structp pp, unsigned int bpp)
* wrong order of the 'ON' and 'default' cases. UNSET now defaults to OFF,
* as documented in png.h
*/
png_debug(1, "in png_init_filter_functions_neon");
#ifdef PNG_ARM_NEON_API_SUPPORTED
switch ((pp->options >> PNG_ARM_NEON) & 3)
{

View File

@ -1,9 +1,9 @@
/* filter_neon.S - NEON optimised filter functions
*
* Copyright (c) 2014 Glenn Randers-Pehrson
* Copyright (c) 2014,2017 Glenn Randers-Pehrson
* Written by Mans Rullgard, 2011.
* Last changed in libpng 1.6.16 [December 22, 2014]
* Last changed in libpng 1.6.31 [July 27, 2017]
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@ -16,7 +16,7 @@
#define PNG_VERSION_INFO_ONLY
#include "../pngpriv.h"
#if defined(__linux__) && defined(__ELF__)
#if (defined(__linux__) || defined(__FreeBSD__)) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits /* mark stack as non-executable */
#endif

View File

@ -1,11 +1,11 @@
/* filter_neon_intrinsics.c - NEON optimised filter functions
*
* Copyright (c) 2014 Glenn Randers-Pehrson
* Copyright (c) 2014,2016 Glenn Randers-Pehrson
* Written by James Yu <james.yu at linaro.org>, October 2013.
* Based on filter_neon.S, written by Mans Rullgard, 2011.
*
* Last changed in libpng 1.6.16 [December 22, 2014]
* Last changed in libpng 1.6.22 [May 26, 2016]
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@ -47,6 +47,8 @@ png_read_filter_row_up_neon(png_row_infop row_info, png_bytep row,
png_bytep rp_stop = row + row_info->rowbytes;
png_const_bytep pp = prev_row;
png_debug(1, "in png_read_filter_row_up_neon");
for (; rp < rp_stop; rp += 16, pp += 16)
{
uint8x16_t qrp, qpp;
@ -72,6 +74,8 @@ png_read_filter_row_sub3_neon(png_row_infop row_info, png_bytep row,
uint8x8x4_t vdest;
vdest.val[3] = vdup_n_u8(0);
png_debug(1, "in png_read_filter_row_sub3_neon");
for (; rp < rp_stop;)
{
uint8x8_t vtmp1, vtmp2;
@ -113,6 +117,8 @@ png_read_filter_row_sub4_neon(png_row_infop row_info, png_bytep row,
uint8x8x4_t vdest;
vdest.val[3] = vdup_n_u8(0);
png_debug(1, "in png_read_filter_row_sub4_neon");
for (; rp < rp_stop; rp += 16)
{
uint32x2x4_t vtmp = vld4_u32(png_ptr(uint32_t,rp));
@ -148,6 +154,8 @@ png_read_filter_row_avg3_neon(png_row_infop row_info, png_bytep row,
vrpt = png_ptr(uint8x8x2_t,&vtmp);
vrp = *vrpt;
png_debug(1, "in png_read_filter_row_avg3_neon");
for (; rp < rp_stop; pp += 12)
{
uint8x8_t vtmp1, vtmp2, vtmp3;
@ -207,6 +215,8 @@ png_read_filter_row_avg4_neon(png_row_infop row_info, png_bytep row,
uint8x8x4_t vdest;
vdest.val[3] = vdup_n_u8(0);
png_debug(1, "in png_read_filter_row_avg4_neon");
for (; rp < rp_stop; rp += 16, pp += 16)
{
uint32x2x4_t vtmp;
@ -280,6 +290,8 @@ png_read_filter_row_paeth3_neon(png_row_infop row_info, png_bytep row,
vrpt = png_ptr(uint8x8x2_t,&vtmp);
vrp = *vrpt;
png_debug(1, "in png_read_filter_row_paeth3_neon");
for (; rp < rp_stop; pp += 12)
{
uint8x8x2_t *vppt;
@ -339,6 +351,8 @@ png_read_filter_row_paeth4_neon(png_row_infop row_info, png_bytep row,
uint8x8x4_t vdest;
vdest.val[3] = vdup_n_u8(0);
png_debug(1, "in png_read_filter_row_paeth4_neon");
for (; rp < rp_stop; rp += 16, pp += 16)
{
uint32x2x4_t vtmp;

View File

@ -59,7 +59,7 @@
#define PACKAGE_NAME "libpng"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "libpng 1.6.18"
#define PACKAGE_STRING "libpng 1.6.34"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libpng"
@ -68,7 +68,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "1.6.18"
#define PACKAGE_VERSION "1.6.34"
/* Turn on ARM Neon optimizations at run-time */
/* #undef PNG_ARM_NEON_API_SUPPORTED */
@ -77,7 +77,29 @@
/* #undef PNG_ARM_NEON_CHECK_SUPPORTED */
/* Enable ARM Neon optimizations */
/* #undef PNG_ARM_NEON_OPT */
/* #define PNG_ARM_NEON_OPT 0 */
/* Forcefully removed for non-compliance */
/* Enable Intel SSE optimizations */
#define PNG_INTEL_SSE_OPT 0
/* Turn on MIPS MSA optimizations at run-time */
/* #undef PNG_MIPS_MSA_API_SUPPORTED */
/* Check for MIPS MSA support at run-time */
/* #undef PNG_MIPS_MSA_CHECK_SUPPORTED */
/* Enable MIPS MSA optimizations */
/* #undef PNG_MIPS_MSA_OPT */
/* Turn on POWERPC VSX optimizations at run-time */
/* #undef PNG_POWERPC_VSX_API_SUPPORTED */
/* Check for POWERPC VSX support at run-time */
/* #undef PNG_POWERPC_VSX_CHECK_SUPPORTED */
/* Enable POWERPC VSX optimizations */
/* #undef PNG_POWERPC_VSX_OPT */
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
@ -86,7 +108,7 @@
/* #undef TM_IN_SYS_TIME */
/* Version number of package */
#define VERSION "1.6.18"
#define VERSION "1.6.34"
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */

View File

@ -0,0 +1,39 @@
/* contrib/arm-neon/android-ndk.c
*
* Copyright (c) 2014 Glenn Randers-Pehrson
* Written by John Bowler, 2014.
* Last changed in libpng 1.6.10 [March 6, 2014]
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*
* SEE contrib/arm-neon/README before reporting bugs
*
* STATUS: COMPILED, UNTESTED
* BUG REPORTS: png-mng-implement@sourceforge.net
*
* png_have_neon implemented for the Android NDK, see:
*
* Documentation:
* http://www.kandroid.org/ndk/docs/CPU-ARM-NEON.html
* https://code.google.com/p/android/issues/detail?id=49065
*
* NOTE: this requires that libpng is built against the Android NDK and linked
* with an implementation of the Android ARM 'cpu-features' library. The code
* has been compiled only, not linked: no version of the library has been found,
* only the header files exist in the NDK.
*/
#include <cpu-features.h>
static int
png_have_neon(png_structp png_ptr)
{
/* This is a whole lot easier than the linux code, however it is probably
* implemented as below, therefore it is better to cache the result (these
* function calls may be slow!)
*/
PNG_UNUSED(png_ptr)
return android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM &&
(android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0;
}

View File

@ -0,0 +1,120 @@
/* contrib/arm-neon/linux-auxv.c
*
* Copyright (c) 2014 Glenn Randers-Pehrson
* Written by Mans Rullgard, 2011.
* Last changed in libpng 1.6.10 [March 6, 2014]
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*
* SEE contrib/arm-neon/README before reporting bugs
*
* STATUS: COMPILED, TESTED
* BUG REPORTS: png-mng-implement@sourceforge.net
*
* png_have_neon implemented for Linux versions which allow access to
* /proc/self/auxv. This is probably faster, cleaner and safer than the code to
* read /proc/cpuinfo in contrib/arm-neon/linux, however it is yet another piece
* of potentially untested code and has more complex dependencies than the code
* to read cpuinfo.
*
* This generic __linux__ implementation requires reading /proc/self/auxv and
* looking at each element for one that records NEON capabilities.
*/
#include <unistd.h> /* for POSIX 1003.1 */
#include <errno.h> /* for EINTR */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <elf.h>
#include <asm/hwcap.h>
/* A read call may be interrupted, in which case it returns -1 and sets errno to
* EINTR if nothing was done, otherwise (if something was done) a partial read
* may result.
*/
static size_t
safe_read(png_structp png_ptr, int fd, void *buffer_in, size_t nbytes)
{
size_t ntotal = 0;
char *buffer = png_voidcast(char*, buffer_in);
while (nbytes > 0)
{
unsigned int nread;
int iread;
/* Passing nread > INT_MAX to read is implementation defined in POSIX
* 1003.1, therefore despite the unsigned argument portable code must
* limit the value to INT_MAX!
*/
if (nbytes > INT_MAX)
nread = INT_MAX;
else
nread = (unsigned int)/*SAFE*/nbytes;
iread = read(fd, buffer, nread);
if (iread == -1)
{
/* This is the devil in the details, a read can terminate early with 0
* bytes read because of EINTR, yet it still returns -1 otherwise end
* of file cannot be distinguished.
*/
if (errno != EINTR)
{
png_warning(png_ptr, "/proc read failed");
return 0; /* I.e., a permanent failure */
}
}
else if (iread < 0)
{
/* Not a valid 'read' result: */
png_warning(png_ptr, "OS /proc read bug");
return 0;
}
else if (iread > 0)
{
/* Continue reading until a permanent failure, or EOF */
buffer += iread;
nbytes -= (unsigned int)/*SAFE*/iread;
ntotal += (unsigned int)/*SAFE*/iread;
}
else
return ntotal;
}
return ntotal; /* nbytes == 0 */
}
static int
png_have_neon(png_structp png_ptr)
{
int fd = open("/proc/self/auxv", O_RDONLY);
Elf32_auxv_t aux;
/* Failsafe: failure to open means no NEON */
if (fd == -1)
{
png_warning(png_ptr, "/proc/self/auxv open failed");
return 0;
}
while (safe_read(png_ptr, fd, &aux, sizeof aux) == sizeof aux)
{
if (aux.a_type == AT_HWCAP && (aux.a_un.a_val & HWCAP_NEON) != 0)
{
close(fd);
return 1;
}
}
close(fd);
return 0;
}

View File

@ -0,0 +1,161 @@
/* contrib/arm-neon/linux.c
*
* Last changed in libpng 1.6.31 [July 27, 2017]
* Copyright (c) 2014, 2017 Glenn Randers-Pehrson
* Written by John Bowler, 2014, 2017.
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
* and license in png.h
*
* SEE contrib/arm-neon/README before reporting bugs
*
* STATUS: SUPPORTED
* BUG REPORTS: png-mng-implement@sourceforge.net
*
* png_have_neon implemented for Linux by reading the widely available
* pseudo-file /proc/cpuinfo.
*
* This code is strict ANSI-C and is probably moderately portable; it does
* however use <stdio.h> and it assumes that /proc/cpuinfo is never localized.
*/
#include <stdio.h>
static int
png_have_neon(png_structp png_ptr)
{
FILE *f = fopen("/proc/cpuinfo", "rb");
if (f != NULL)
{
/* This is a simple state machine which reads the input byte-by-byte until
* it gets a match on the 'neon' feature or reaches the end of the stream.
*/
static const char ch_feature[] = { 70, 69, 65, 84, 85, 82, 69, 83 };
static const char ch_neon[] = { 78, 69, 79, 78 };
enum
{
StartLine, Feature, Colon, StartTag, Neon, HaveNeon, SkipTag, SkipLine
} state;
int counter;
for (state=StartLine, counter=0;;)
{
int ch = fgetc(f);
if (ch == EOF)
{
/* EOF means error or end-of-file, return false; neon at EOF is
* assumed to be a mistake.
*/
fclose(f);
return 0;
}
switch (state)
{
case StartLine:
/* Match spaces at the start of line */
if (ch <= 32) /* skip control characters and space */
break;
counter=0;
state = Feature;
/* FALLTHROUGH */
case Feature:
/* Match 'FEATURE', ASCII case insensitive. */
if ((ch & ~0x20) == ch_feature[counter])
{
if (++counter == (sizeof ch_feature))
state = Colon;
break;
}
/* did not match 'feature' */
state = SkipLine;
/* FALLTHROUGH */
case SkipLine:
skipLine:
/* Skip everything until we see linefeed or carriage return */
if (ch != 10 && ch != 13)
break;
state = StartLine;
break;
case Colon:
/* Match any number of space or tab followed by ':' */
if (ch == 32 || ch == 9)
break;
if (ch == 58) /* i.e. ':' */
{
state = StartTag;
break;
}
/* Either a bad line format or a 'feature' prefix followed by
* other characters.
*/
state = SkipLine;
goto skipLine;
case StartTag:
/* Skip space characters before a tag */
if (ch == 32 || ch == 9)
break;
state = Neon;
counter = 0;
/* FALLTHROUGH */
case Neon:
/* Look for 'neon' tag */
if ((ch & ~0x20) == ch_neon[counter])
{
if (++counter == (sizeof ch_neon))
state = HaveNeon;
break;
}
state = SkipTag;
/* FALLTHROUGH */
case SkipTag:
/* Skip non-space characters */
if (ch == 10 || ch == 13)
state = StartLine;
else if (ch == 32 || ch == 9)
state = StartTag;
break;
case HaveNeon:
/* Have seen a 'neon' prefix, but there must be a space or new
* line character to terminate it.
*/
if (ch == 10 || ch == 13 || ch == 32 || ch == 9)
{
fclose(f);
return 1;
}
state = SkipTag;
break;
default:
png_error(png_ptr, "png_have_neon: internal error (bug)");
}
}
}
#ifdef PNG_WARNINGS_SUPPORTED
else
png_warning(png_ptr, "/proc/cpuinfo open failed");
#endif
return 0;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
/* pngconf.h - machine configurable file for libpng
*
* libpng version 1.6.18, July 23, 2015
* libpng version 1.6.34, September 29, 2017
*
* Copyright (c) 1998-2015 Glenn Randers-Pehrson
* Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
@ -63,7 +63,7 @@
*/
#define PNG_CONST const /* backward compatibility only */
/* This controls optimization of the reading of 16 and 32 bit values
/* This controls optimization of the reading of 16-bit and 32-bit values
* from PNG files. It can be set on a per-app-file basis - it
* just changes whether a macro is used when the function is called.
* The library builder sets the default; if read functions are not
@ -188,27 +188,27 @@
* compatible with GCC or Visual C because of different calling conventions.
*/
# if PNG_API_RULE == 2
/* If this line results in an error, either because __watcall is not
* understood or because of a redefine just below you cannot use *this*
* build of the library with the compiler you are using. *This* build was
* build using Watcom and applications must also be built using Watcom!
*/
/* If this line results in an error, either because __watcall is not
* understood or because of a redefine just below you cannot use *this*
* build of the library with the compiler you are using. *This* build was
* build using Watcom and applications must also be built using Watcom!
*/
# define PNGCAPI __watcall
# endif
# if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800))
# define PNGCAPI __cdecl
# if PNG_API_RULE == 1
/* If this line results in an error __stdcall is not understood and
* PNG_API_RULE should not have been set to '1'.
*/
/* If this line results in an error __stdcall is not understood and
* PNG_API_RULE should not have been set to '1'.
*/
# define PNGAPI __stdcall
# endif
# else
/* An older compiler, or one not detected (erroneously) above,
* if necessary override on the command line to get the correct
* variants for the compiler.
*/
/* An older compiler, or one not detected (erroneously) above,
* if necessary override on the command line to get the correct
* variants for the compiler.
*/
# ifndef PNGCAPI
# define PNGCAPI _cdecl
# endif
@ -225,10 +225,10 @@
# if (defined(_MSC_VER) && _MSC_VER < 800) ||\
(defined(__BORLANDC__) && __BORLANDC__ < 0x500)
/* older Borland and MSC
* compilers used '__export' and required this to be after
* the type.
*/
/* older Borland and MSC
* compilers used '__export' and required this to be after
* the type.
*/
# ifndef PNG_EXPORT_TYPE
# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP
# endif
@ -244,9 +244,9 @@
# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
# define PNGAPI _System
# else /* !Windows/x86 && !OS/2 */
/* Use the defaults, or define PNG*API on the command line (but
* this will have to be done for every compile!)
*/
/* Use the defaults, or define PNG*API on the command line (but
* this will have to be done for every compile!)
*/
# endif /* other system, !OS/2 */
#endif /* !Windows/x86 */
@ -267,7 +267,7 @@
*/
#ifndef PNG_IMPEXP
# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT)
/* This forces use of a DLL, disallowing static linking */
/* This forces use of a DLL, disallowing static linking */
# define PNG_IMPEXP PNG_DLL_IMPORT
# endif
@ -340,7 +340,7 @@
* less efficient code.
*/
# if defined(__clang__) && defined(__has_attribute)
/* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */
/* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */
# if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__)
# define PNG_USE_RESULT __attribute__((__warn_unused_result__))
# endif
@ -480,7 +480,7 @@
#if CHAR_BIT == 8 && UCHAR_MAX == 255
typedef unsigned char png_byte;
#else
# error "libpng requires 8 bit bytes"
# error "libpng requires 8-bit bytes"
#endif
#if INT_MIN == -32768 && INT_MAX == 32767
@ -488,7 +488,7 @@
#elif SHRT_MIN == -32768 && SHRT_MAX == 32767
typedef short png_int_16;
#else
# error "libpng requires a signed 16 bit type"
# error "libpng requires a signed 16-bit type"
#endif
#if UINT_MAX == 65535
@ -496,7 +496,7 @@
#elif USHRT_MAX == 65535
typedef unsigned short png_uint_16;
#else
# error "libpng requires an unsigned 16 bit type"
# error "libpng requires an unsigned 16-bit type"
#endif
#if INT_MIN < -2147483646 && INT_MAX > 2147483646
@ -504,15 +504,15 @@
#elif LONG_MIN < -2147483646 && LONG_MAX > 2147483646
typedef long int png_int_32;
#else
# error "libpng requires a signed 32 bit (or more) type"
# error "libpng requires a signed 32-bit (or more) type"
#endif
#if UINT_MAX > 4294967294
#if UINT_MAX > 4294967294U
typedef unsigned int png_uint_32;
#elif ULONG_MAX > 4294967294
#elif ULONG_MAX > 4294967294U
typedef unsigned long int png_uint_32;
#else
# error "libpng requires an unsigned 32 bit (or more) type"
# error "libpng requires an unsigned 32-bit (or more) type"
#endif
/* Prior to 1.6.0 it was possible to disable the use of size_t, 1.6.0, however,

View File

@ -2,7 +2,7 @@
/* pngdebug.h - Debugging macros for libpng, also used in pngtest.c
*
* Last changed in libpng 1.6.8 [December 19, 2013]
* Copyright (c) 1998-2013 Glenn Randers-Pehrson
* Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*

View File

@ -1,8 +1,8 @@
/* pngerror.c - stub functions for i/o and memory allocation
*
* Last changed in libpng 1.6.15 [November 20, 2014]
* Copyright (c) 1998-2014 Glenn Randers-Pehrson
* Last changed in libpng 1.6.31 [July 27, 2017]
* Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
@ -26,7 +26,7 @@ static PNG_FUNCTION(void, png_default_error,PNGARG((png_const_structrp png_ptr,
#ifdef PNG_WARNINGS_SUPPORTED
static void /* PRIVATE */
png_default_warning PNGARG((png_const_structrp png_ptr,
png_const_charp warning_message));
png_const_charp warning_message));
#endif /* WARNINGS */
/* This function is called whenever there is a fatal error. This function
@ -37,14 +37,14 @@ png_default_warning PNGARG((png_const_structrp png_ptr,
#ifdef PNG_ERROR_TEXT_SUPPORTED
PNG_FUNCTION(void,PNGAPI
png_error,(png_const_structrp png_ptr, png_const_charp error_message),
PNG_NORETURN)
PNG_NORETURN)
{
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
char msg[16];
if (png_ptr != NULL)
{
if ((png_ptr->flags &
(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0
(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0)
{
if (*error_message == PNG_LITERAL_SHARP)
{
@ -65,18 +65,18 @@ png_error,(png_const_structrp png_ptr, png_const_charp error_message),
else
error_message += offset;
}
else
{
if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
{
msg[0] = '0';
msg[1] = '\0';
error_message = msg;
}
}
}
else
{
if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
{
msg[0] = '0';
msg[1] = '\0';
error_message = msg;
}
}
}
}
#endif
if (png_ptr != NULL && png_ptr->error_fn != NULL)
@ -110,7 +110,7 @@ png_err,(png_const_structrp png_ptr),PNG_NORETURN)
*/
size_t
png_safecat(png_charp buffer, size_t bufsize, size_t pos,
png_const_charp string)
png_const_charp string)
{
if (buffer != NULL && pos < bufsize)
{
@ -131,7 +131,7 @@ png_safecat(png_charp buffer, size_t bufsize, size_t pos,
*/
png_charp
png_format_number(png_const_charp start, png_charp end, int format,
png_alloc_size_t number)
png_alloc_size_t number)
{
int count = 0; /* number of digits output */
int mincount = 1; /* minimum number required */
@ -163,7 +163,7 @@ png_format_number(png_const_charp start, png_charp end, int format,
case PNG_NUMBER_FORMAT_02u:
/* Expects at least 2 digits. */
mincount = 2;
/* FALL THROUGH */
/* FALLTHROUGH */
case PNG_NUMBER_FORMAT_u:
*--end = digits[number % 10];
@ -173,7 +173,7 @@ png_format_number(png_const_charp start, png_charp end, int format,
case PNG_NUMBER_FORMAT_02x:
/* This format expects at least two digits */
mincount = 2;
/* FALL THROUGH */
/* FALLTHROUGH */
case PNG_NUMBER_FORMAT_x:
*--end = digits[number & 0xf];
@ -233,7 +233,7 @@ png_warning(png_const_structrp png_ptr, png_const_charp warning_message)
}
if (png_ptr != NULL && png_ptr->warning_fn != NULL)
(*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr),
warning_message + offset);
warning_message + offset);
else
png_default_warning(png_ptr, warning_message + offset);
}
@ -245,7 +245,7 @@ png_warning(png_const_structrp png_ptr, png_const_charp warning_message)
*/
void
png_warning_parameter(png_warning_parameters p, int number,
png_const_charp string)
png_const_charp string)
{
if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT)
(void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string);
@ -253,7 +253,7 @@ png_warning_parameter(png_warning_parameters p, int number,
void
png_warning_parameter_unsigned(png_warning_parameters p, int number, int format,
png_alloc_size_t value)
png_alloc_size_t value)
{
char buffer[PNG_NUMBER_BUFFER_SIZE];
png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value));
@ -261,7 +261,7 @@ png_warning_parameter_unsigned(png_warning_parameters p, int number, int format,
void
png_warning_parameter_signed(png_warning_parameters p, int number, int format,
png_int_32 value)
png_int_32 value)
{
png_alloc_size_t u;
png_charp str;
@ -282,7 +282,7 @@ png_warning_parameter_signed(png_warning_parameters p, int number, int format,
void
png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p,
png_const_charp message)
png_const_charp message)
{
/* The internal buffer is just 192 bytes - enough for all our messages,
* overflow doesn't happen because this code checks! If someone figures
@ -391,10 +391,10 @@ png_benign_error(png_const_structrp png_ptr, png_const_charp error_message)
void /* PRIVATE */
png_app_warning(png_const_structrp png_ptr, png_const_charp error_message)
{
if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0)
png_warning(png_ptr, error_message);
else
png_error(png_ptr, error_message);
if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0)
png_warning(png_ptr, error_message);
else
png_error(png_ptr, error_message);
# ifndef PNG_ERROR_TEXT_SUPPORTED
PNG_UNUSED(error_message)
@ -404,10 +404,10 @@ png_app_warning(png_const_structrp png_ptr, png_const_charp error_message)
void /* PRIVATE */
png_app_error(png_const_structrp png_ptr, png_const_charp error_message)
{
if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0)
png_warning(png_ptr, error_message);
else
png_error(png_ptr, error_message);
if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0)
png_warning(png_ptr, error_message);
else
png_error(png_ptr, error_message);
# ifndef PNG_ERROR_TEXT_SUPPORTED
PNG_UNUSED(error_message)
@ -478,7 +478,7 @@ png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp
#if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
PNG_FUNCTION(void,PNGAPI
png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message),
PNG_NORETURN)
PNG_NORETURN)
{
char msg[18+PNG_MAX_ERROR_TEXT];
if (png_ptr == NULL)
@ -573,7 +573,7 @@ png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),PNG_NORETURN)
{
# define fixed_message "fixed point overflow in "
# define fixed_message_ln ((sizeof fixed_message)-1)
int iin;
unsigned int iin;
char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT];
memcpy(msg, fixed_message, fixed_message_ln);
iin = 0;
@ -620,7 +620,7 @@ png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn,
else
{
png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *,
png_malloc_warn(png_ptr, jmp_buf_size));
png_malloc_warn(png_ptr, jmp_buf_size));
if (png_ptr->jmp_buf_ptr == NULL)
return NULL; /* new NULL return on OOM */
@ -709,7 +709,7 @@ png_free_jmpbuf(png_structrp png_ptr)
*/
static PNG_FUNCTION(void /* PRIVATE */,
png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
PNG_NORETURN)
PNG_NORETURN)
{
#ifdef PNG_CONSOLE_IO_SUPPORTED
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
@ -768,7 +768,7 @@ png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN)
/* If control reaches this point, png_longjmp() must not return. The only
* choice is to terminate the whole process (or maybe the thread); to do
* this the ANSI-C abort() function is used unless a different method is
* this the ANSI-C abort() function is used unless a different method is
* implemented by overriding the default configuration setting for
* PNG_ABORT().
*/
@ -883,7 +883,7 @@ png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode)
*/
PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI
png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message),
PNG_NORETURN)
PNG_NORETURN)
{
const png_const_structrp png_ptr = png_nonconst_ptr;
png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
@ -906,7 +906,7 @@ png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message),
/* Missing longjmp buffer, the following is to help debugging: */
{
size_t pos = png_safecat(image->message, (sizeof image->message), 0,
"bad longjmp: ");
"bad longjmp: ");
png_safecat(image->message, (sizeof image->message), pos,
error_message);
}

View File

@ -1,8 +1,8 @@
/* pngget.c - retrieval of values from info struct
*
* Last changed in libpng 1.6.17 [March 26, 2015]
* Copyright (c) 1998-2015 Glenn Randers-Pehrson
* Last changed in libpng 1.6.32 [August 24, 2017]
* Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
@ -338,7 +338,7 @@ ppi_from_ppm(png_uint_32 ppm)
png_fixed_point result;
if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127,
5000) != 0)
return result;
return (png_uint_32)result;
/* Overflow. */
return 0;
@ -456,11 +456,11 @@ png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr,
return (retval);
}
#endif /* pHYs */
#endif /* INCH_CONVERSIONS */
#endif /* INCH_CONVERSIONS */
/* png_get_channels really belongs in here, too, but it's been around longer */
#endif /* EASY_ACCESS */
#endif /* EASY_ACCESS */
png_byte PNGAPI
@ -486,7 +486,7 @@ png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr)
#ifdef PNG_bKGD_SUPPORTED
png_uint_32 PNGAPI
png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
png_color_16p *background)
png_color_16p *background)
{
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_bKGD) != 0 &&
@ -526,28 +526,28 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr,
if (white_x != NULL)
*white_x = png_float(png_ptr,
info_ptr->colorspace.end_points_xy.whitex, "cHRM white X");
info_ptr->colorspace.end_points_xy.whitex, "cHRM white X");
if (white_y != NULL)
*white_y = png_float(png_ptr,
info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y");
info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y");
if (red_x != NULL)
*red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx,
"cHRM red X");
"cHRM red X");
if (red_y != NULL)
*red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy,
"cHRM red Y");
"cHRM red Y");
if (green_x != NULL)
*green_x = png_float(png_ptr,
info_ptr->colorspace.end_points_xy.greenx, "cHRM green X");
info_ptr->colorspace.end_points_xy.greenx, "cHRM green X");
if (green_y != NULL)
*green_y = png_float(png_ptr,
info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y");
info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y");
if (blue_x != NULL)
*blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex,
"cHRM blue X");
"cHRM blue X");
if (blue_y != NULL)
*blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey,
"cHRM blue Y");
"cHRM blue Y");
return (PNG_INFO_cHRM);
}
@ -556,42 +556,42 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr,
png_uint_32 PNGAPI
png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr,
double *red_X, double *red_Y, double *red_Z, double *green_X,
double *green_Y, double *green_Z, double *blue_X, double *blue_Y,
double *blue_Z)
double *red_X, double *red_Y, double *red_Z, double *green_X,
double *green_Y, double *green_Z, double *blue_X, double *blue_Y,
double *blue_Z)
{
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
(info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
{
png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)");
if (red_X != NULL)
*red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X,
"cHRM red X");
"cHRM red X");
if (red_Y != NULL)
*red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y,
"cHRM red Y");
"cHRM red Y");
if (red_Z != NULL)
*red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z,
"cHRM red Z");
"cHRM red Z");
if (green_X != NULL)
*green_X = png_float(png_ptr,
info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X");
info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X");
if (green_Y != NULL)
*green_Y = png_float(png_ptr,
info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y");
info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y");
if (green_Z != NULL)
*green_Z = png_float(png_ptr,
info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z");
info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z");
if (blue_X != NULL)
*blue_X = png_float(png_ptr,
info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X");
info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X");
if (blue_Y != NULL)
*blue_Y = png_float(png_ptr,
info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y");
info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y");
if (blue_Z != NULL)
*blue_Z = png_float(png_ptr,
info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z");
info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z");
return (PNG_INFO_cHRM);
}
@ -681,8 +681,8 @@ png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
png_debug1(1, "in %s retrieval function", "gAMA");
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
file_gamma != NULL)
(info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
file_gamma != NULL)
{
*file_gamma = info_ptr->colorspace.gamma;
return (PNG_INFO_gAMA);
@ -704,7 +704,7 @@ png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr,
file_gamma != NULL)
{
*file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma,
"png_get_gAMA");
"png_get_gAMA");
return (PNG_INFO_gAMA);
}
@ -773,6 +773,35 @@ png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr,
}
#endif
#ifdef PNG_eXIf_SUPPORTED
png_uint_32 PNGAPI
png_get_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
png_bytep *exif)
{
png_warning(png_ptr, "png_get_eXIf does not work; use png_get_eXIf_1");
PNG_UNUSED(info_ptr)
PNG_UNUSED(exif)
return 0;
}
png_uint_32 PNGAPI
png_get_eXIf_1(png_const_structrp png_ptr, png_const_inforp info_ptr,
png_uint_32 *num_exif, png_bytep *exif)
{
png_debug1(1, "in %s retrieval function", "eXIf");
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_eXIf) != 0 && exif != NULL)
{
*num_exif = info_ptr->num_exif;
*exif = info_ptr->exif;
return (PNG_INFO_eXIf);
}
return (0);
}
#endif
#ifdef PNG_hIST_SUPPORTED
png_uint_32 PNGAPI
png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
@ -901,7 +930,7 @@ png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
*/
*width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width");
*height = png_fixed(png_ptr, atof(info_ptr->scal_s_height),
"sCAL height");
"sCAL height");
return (PNG_INFO_sCAL);
}
@ -1142,19 +1171,19 @@ png_get_compression_buffer_size(png_const_structrp png_ptr)
return 0;
#ifdef PNG_WRITE_SUPPORTED
if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
#endif
{
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
return png_ptr->IDAT_read_size;
return png_ptr->IDAT_read_size;
#else
return PNG_IDAT_READ_SIZE;
return PNG_IDAT_READ_SIZE;
#endif
}
#ifdef PNG_WRITE_SUPPORTED
else
return png_ptr->zbuffer_size;
else
return png_ptr->zbuffer_size;
#endif
}

View File

@ -2,7 +2,7 @@
/* pnginfo.h - header file for PNG reference library
*
* Last changed in libpng 1.6.1 [March 28, 2013]
* Copyright (c) 1998-2013 Glenn Randers-Pehrson
* Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
@ -185,6 +185,14 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
#endif
#ifdef PNG_eXIf_SUPPORTED
int num_exif; /* Added at libpng-1.6.31 */
png_bytep exif;
# ifdef PNG_READ_eXIf_SUPPORTED
png_bytep eXIf_buf; /* Added at libpng-1.6.32 */
# endif
#endif
#ifdef PNG_hIST_SUPPORTED
/* The hIST chunk contains the relative frequency or importance of the
* various palette entries, so that a viewer can intelligently select a
@ -223,7 +231,7 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
/* Storage for unknown chunks that the library doesn't recognize. */
png_unknown_chunkp unknown_chunks;
/* The type of this field is limited by the type of
/* The type of this field is limited by the type of
* png_struct::user_chunk_cache_max, else overflow can occur.
*/
int unknown_chunks_num;

View File

@ -1,10 +1,8 @@
/* libpng 1.6.18 STANDARD API DEFINITION */
/* pnglibconf.h - library build configuration */
/* Libpng version 1.6.18 - July 23, 2015 */
/* libpng version 1.6.32, August 24, 2017 */
/* Copyright (c) 1998-2014 Glenn Randers-Pehrson */
/* Copyright (c) 1998-2017 Glenn Randers-Pehrson */
/* This code is released under the libpng license. */
/* For conditions of distribution and use, see the disclaimer */
@ -44,6 +42,8 @@
#define PNG_IO_STATE_SUPPORTED
#define PNG_MNG_FEATURES_SUPPORTED
#define PNG_POINTER_INDEXING_SUPPORTED
/*#undef PNG_POWERPC_VSX_API_SUPPORTED*/
/*#undef PNG_POWERPC_VSX_CHECK_SUPPORTED*/
#define PNG_PROGRESSIVE_READ_SUPPORTED
#define PNG_READ_16BIT_SUPPORTED
#define PNG_READ_ALPHA_MODE_SUPPORTED
@ -82,6 +82,7 @@
#define PNG_READ_USER_TRANSFORM_SUPPORTED
#define PNG_READ_bKGD_SUPPORTED
#define PNG_READ_cHRM_SUPPORTED
#define PNG_READ_eXIf_SUPPORTED
#define PNG_READ_gAMA_SUPPORTED
#define PNG_READ_hIST_SUPPORTED
#define PNG_READ_iCCP_SUPPORTED
@ -109,6 +110,7 @@
#define PNG_SIMPLIFIED_READ_SUPPORTED
#define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
#define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
#define PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
#define PNG_SIMPLIFIED_WRITE_SUPPORTED
#define PNG_STDIO_SUPPORTED
#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
@ -150,6 +152,7 @@
#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
#define PNG_WRITE_bKGD_SUPPORTED
#define PNG_WRITE_cHRM_SUPPORTED
#define PNG_WRITE_eXIf_SUPPORTED
#define PNG_WRITE_gAMA_SUPPORTED
#define PNG_WRITE_hIST_SUPPORTED
#define PNG_WRITE_iCCP_SUPPORTED
@ -167,6 +170,7 @@
#define PNG_WRITE_zTXt_SUPPORTED
#define PNG_bKGD_SUPPORTED
#define PNG_cHRM_SUPPORTED
#define PNG_eXIf_SUPPORTED
#define PNG_gAMA_SUPPORTED
#define PNG_hIST_SUPPORTED
#define PNG_iCCP_SUPPORTED
@ -185,7 +189,7 @@
/* end of options */
/* settings */
#define PNG_API_RULE 0
#define PNG_COST_SHIFT 3
#define PNG_ARM_NEON_OPT 2
#define PNG_DEFAULT_READ_MACROS 1
#define PNG_GAMMA_THRESHOLD_FIXED 5000
#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE
@ -204,9 +208,8 @@
#define PNG_USER_CHUNK_MALLOC_MAX 8000000
#define PNG_USER_HEIGHT_MAX 1000000
#define PNG_USER_WIDTH_MAX 1000000
#define PNG_WEIGHT_SHIFT 8
#define PNG_ZBUF_SIZE 8192
#define PNG_ZLIB_VERNUM 0 /* unknown */
#define PNG_ZLIB_VERNUM 0x1280
#define PNG_Z_DEFAULT_COMPRESSION (-1)
#define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0
#define PNG_Z_DEFAULT_STRATEGY 1

View File

@ -1,8 +1,8 @@
/* pngmem.c - stub functions for memory allocation
*
* Last changed in libpng 1.6.15 [November 20, 2014]
* Copyright (c) 1998-2014 Glenn Randers-Pehrson
* Last changed in libpng 1.6.26 [October 20, 2016]
* Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
@ -66,7 +66,7 @@ png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
*/
PNG_FUNCTION(png_voidp /* PRIVATE */,
png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size),
PNG_ALLOCATED)
PNG_ALLOCATED)
{
/* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS
* allocators have also been removed in 1.6.0, so any 16-bit system now has
@ -107,9 +107,9 @@ png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size),
*/
static png_voidp
png_malloc_array_checked(png_const_structrp png_ptr, int nelements,
size_t element_size)
size_t element_size)
{
png_alloc_size_t req = nelements; /* known to be > 0 */
png_alloc_size_t req = (png_alloc_size_t)nelements; /* known to be > 0 */
if (req <= PNG_SIZE_MAX/element_size)
return png_malloc_base(png_ptr, req * element_size);
@ -120,7 +120,7 @@ png_malloc_array_checked(png_const_structrp png_ptr, int nelements,
PNG_FUNCTION(png_voidp /* PRIVATE */,
png_malloc_array,(png_const_structrp png_ptr, int nelements,
size_t element_size),PNG_ALLOCATED)
size_t element_size),PNG_ALLOCATED)
{
if (nelements <= 0 || element_size == 0)
png_error(png_ptr, "internal error: array alloc");
@ -130,7 +130,7 @@ png_malloc_array,(png_const_structrp png_ptr, int nelements,
PNG_FUNCTION(png_voidp /* PRIVATE */,
png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED)
int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED)
{
/* These are internal errors: */
if (add_elements <= 0 || element_size == 0 || old_elements < 0 ||
@ -143,7 +143,7 @@ png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
if (add_elements <= INT_MAX - old_elements)
{
png_voidp new_array = png_malloc_array_checked(png_ptr,
old_elements+add_elements, element_size);
old_elements+add_elements, element_size);
if (new_array != NULL)
{
@ -154,7 +154,7 @@ png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
memcpy(new_array, old_array, element_size*(unsigned)old_elements);
memset((char*)new_array + element_size*(unsigned)old_elements, 0,
element_size*(unsigned)add_elements);
element_size*(unsigned)add_elements);
return new_array;
}
@ -187,7 +187,7 @@ png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
#ifdef PNG_USER_MEM_SUPPORTED
PNG_FUNCTION(png_voidp,PNGAPI
png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),
PNG_ALLOCATED PNG_DEPRECATED)
PNG_ALLOCATED PNG_DEPRECATED)
{
png_voidp ret;
@ -210,7 +210,7 @@ png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),
*/
PNG_FUNCTION(png_voidp,PNGAPI
png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size),
PNG_ALLOCATED)
PNG_ALLOCATED)
{
if (png_ptr != NULL)
{

View File

@ -1,8 +1,8 @@
/* pngpread.c - read a png file in push mode
*
* Last changed in libpng 1.6.18 [July 23, 2015]
* Copyright (c) 1998-2015 Glenn Randers-Pehrson
* Last changed in libpng 1.6.32 [August 24, 2017]
* Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
@ -77,11 +77,11 @@ png_process_data_pause(png_structrp png_ptr, int save)
png_uint_32 PNGAPI
png_process_data_skip(png_structrp png_ptr)
{
/* TODO: Deprecate and remove this API.
* Somewhere the implementation of this seems to have been lost,
* or abandoned. It was only to support some internal back-door access
* to png_struct) in libpng-1.4.x.
*/
/* TODO: Deprecate and remove this API.
* Somewhere the implementation of this seems to have been lost,
* or abandoned. It was only to support some internal back-door access
* to png_struct) in libpng-1.4.x.
*/
png_app_warning(png_ptr,
"png_process_data_skip is not implemented in any current version of libpng");
return 0;
@ -133,7 +133,7 @@ png_process_some_data(png_structrp png_ptr, png_inforp info_ptr)
void /* PRIVATE */
png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr)
{
png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */
png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */
num_to_check = 8 - num_checked;
if (png_ptr->buffer_size < num_to_check)
@ -189,6 +189,7 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
png_crc_read(png_ptr, chunk_tag, 4);
png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
png_check_chunk_name(png_ptr, png_ptr->chunk_name);
png_check_chunk_length(png_ptr, png_ptr->push_length);
png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
}
@ -210,12 +211,14 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
(png_ptr->mode & PNG_HAVE_PLTE) == 0)
png_error(png_ptr, "Missing PLTE before IDAT");
png_ptr->mode |= PNG_HAVE_IDAT;
png_ptr->process_mode = PNG_READ_IDAT_MODE;
if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0)
if (png_ptr->push_length == 0)
return;
if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0)
if (png_ptr->push_length == 0)
return;
png_ptr->mode |= PNG_HAVE_IDAT;
if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
png_benign_error(png_ptr, "Too many IDATs found");
@ -408,7 +411,7 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
{
PNG_PUSH_SAVE_BUFFER_IF_FULL
png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length,
PNG_HANDLE_CHUNK_AS_DEFAULT);
PNG_HANDLE_CHUNK_AS_DEFAULT);
}
png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
@ -499,7 +502,10 @@ png_push_save_buffer(png_structrp png_ptr)
png_error(png_ptr, "Insufficient memory for save_buffer");
}
memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
if (old_buffer)
memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
else if (png_ptr->save_buffer_size)
png_error(png_ptr, "save_buffer error");
png_free(png_ptr, old_buffer);
png_ptr->save_buffer_max = new_max;
}
@ -516,7 +522,7 @@ png_push_save_buffer(png_structrp png_ptr)
void /* PRIVATE */
png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer,
png_size_t buffer_length)
png_size_t buffer_length)
{
png_ptr->current_buffer = buffer;
png_ptr->current_buffer_size = buffer_length;
@ -563,7 +569,7 @@ png_push_read_IDAT(png_structrp png_ptr)
* are of different types and we don't know which variable has the fewest
* bits. Carefully select the smaller and cast it to the type of the
* larger - this cannot overflow. Do not cast in the following test - it
* will break on either 16 or 64 bit platforms.
* will break on either 16-bit or 64-bit platforms.
*/
if (idat_size < save_size)
save_size = (png_size_t)idat_size;
@ -619,7 +625,7 @@ png_push_read_IDAT(png_structrp png_ptr)
void /* PRIVATE */
png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
png_size_t buffer_length)
png_size_t buffer_length)
{
/* The caller checks for a non-zero buffer length. */
if (!(buffer_length > 0) || buffer == NULL)
@ -662,7 +668,7 @@ png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
* change the current behavior (see comments in inflate.c
* for why this doesn't happen at present with zlib 1.2.5).
*/
ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);
ret = PNG_INFLATE(png_ptr, Z_SYNC_FLUSH);
/* Check for any failure before proceeding. */
if (ret != Z_OK && ret != Z_STREAM_END)
@ -679,7 +685,12 @@ png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
png_warning(png_ptr, "Truncated compressed data in IDAT");
else
png_error(png_ptr, "Decompression error in IDAT");
{
if (ret == Z_DATA_ERROR)
png_benign_error(png_ptr, "IDAT: ADLER32 checksum mismatch");
else
png_error(png_ptr, "Decompression error in IDAT");
}
/* Skip the check on unprocessed input */
return;
@ -777,7 +788,7 @@ png_push_process_row(png_structrp png_ptr)
{
if (png_ptr->pass < 6)
png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
png_ptr->transformations);
png_ptr->transformations);
switch (png_ptr->pass)
{
@ -1039,7 +1050,7 @@ png_push_have_row(png_structrp png_ptr, png_bytep row)
{
if (png_ptr->row_fn != NULL)
(*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
(int)png_ptr->pass);
(int)png_ptr->pass);
}
#ifdef PNG_READ_INTERLACING_SUPPORTED

View File

@ -1,8 +1,8 @@
/* pngpriv.h - private declarations for use inside libpng
*
* Last changed in libpng 1.6.18 [July 23, 2015]
* Copyright (c) 1998-2015 Glenn Randers-Pehrson
* Last changed in libpng 1.6.32 [August 24, 2017]
* Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
@ -35,7 +35,9 @@
* Windows/Visual Studio) there is no effect; the OS specific tests below are
* still required (as of 2011-05-02.)
*/
#define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */
#ifndef _POSIX_SOURCE
# define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */
#endif
#ifndef PNG_VERSION_INFO_ONLY
/* Standard library headers not required by png.h: */
@ -133,54 +135,132 @@
# endif
#endif
#if PNG_ARM_NEON_OPT > 0
/* NEON optimizations are to be at least considered by libpng, so enable the
* callbacks to do this.
*/
# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_neon
//#if PNG_ARM_NEON_OPT > 0
// /* NEON optimizations are to be at least considered by libpng, so enable the
// * callbacks to do this.
// */
//# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_neon
//
// /* By default the 'intrinsics' code in arm/filter_neon_intrinsics.c is used
// * if possible - if __ARM_NEON__ is set and the compiler version is not known
// * to be broken. This is controlled by PNG_ARM_NEON_IMPLEMENTATION which can
// * be:
// *
// * 1 The intrinsics code (the default with __ARM_NEON__)
// * 2 The hand coded assembler (the default without __ARM_NEON__)
// *
// * It is possible to set PNG_ARM_NEON_IMPLEMENTATION in CPPFLAGS, however
// * this is *NOT* supported and may cease to work even after a minor revision
// * to libpng. It *is* valid to do this for testing purposes, e.g. speed
// * testing or a new compiler, but the results should be communicated to the
// * libpng implementation list for incorporation in the next minor release.
// */
//# ifndef PNG_ARM_NEON_IMPLEMENTATION
//# if defined(__ARM_NEON__) || defined(__ARM_NEON)
//# if defined(__clang__)
// /* At present it is unknown by the libpng developers which versions
// * of clang support the intrinsics, however some or perhaps all
// * versions do not work with the assembler so this may be
// * irrelevant, so just use the default (do nothing here.)
// */
//# elif defined(__GNUC__)
// /* GCC 4.5.4 NEON support is known to be broken. 4.6.3 is known to
// * work, so if this *is* GCC, or G++, look for a version >4.5
// */
//# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)
//# define PNG_ARM_NEON_IMPLEMENTATION 2
//# endif /* no GNUC support */
//# endif /* __GNUC__ */
//# else /* !defined __ARM_NEON__ */
// /* The 'intrinsics' code simply won't compile without this -mfpu=neon:
// */
//# define PNG_ARM_NEON_IMPLEMENTATION 2
//# endif /* __ARM_NEON__ */
//# endif /* !PNG_ARM_NEON_IMPLEMENTATION */
//
//# ifndef PNG_ARM_NEON_IMPLEMENTATION
// /* Use the intrinsics code by default. */
//# define PNG_ARM_NEON_IMPLEMENTATION 1
//# endif
//#endif /* PNG_ARM_NEON_OPT > 0 */
/* By default the 'intrinsics' code in arm/filter_neon_intrinsics.c is used
* if possible - if __ARM_NEON__ is set and the compiler version is not known
* to be broken. This is controlled by PNG_ARM_NEON_IMPLEMENTATION which can
* be:
*
* 1 The intrinsics code (the default with __ARM_NEON__)
* 2 The hand coded assembler (the default without __ARM_NEON__)
*
* It is possible to set PNG_ARM_NEON_IMPLEMENTATION in CPPFLAGS, however
* this is *NOT* supported and may cease to work even after a minor revision
* to libpng. It *is* valid to do this for testing purposes, e.g. speed
* testing or a new compiler, but the results should be communicated to the
* libpng implementation list for incorporation in the next minor release.
*/
# ifndef PNG_ARM_NEON_IMPLEMENTATION
# if defined(__ARM_NEON__) || defined(__ARM_NEON)
#ifndef PNG_MIPS_MSA_OPT
# if defined(__mips_msa) && (__mips_isa_rev >= 5) && defined(PNG_ALIGNED_MEMORY_SUPPORTED)
# define PNG_MIPS_MSA_OPT 2
# else
# define PNG_MIPS_MSA_OPT 0
# endif
#endif
#ifndef PNG_POWERPC_VSX_OPT
# if defined(__PPC64__) && defined(__ALTIVEC__) && defined(__VSX__)
# define PNG_POWERPC_VSX_OPT 2
# else
# define PNG_POWERPC_VSX_OPT 0
# endif
#endif
#ifndef PNG_INTEL_SSE_OPT
# ifdef PNG_INTEL_SSE
/* Only check for SSE if the build configuration has been modified to
* enable SSE optimizations. This means that these optimizations will
* be off by default. See contrib/intel for more details.
*/
# if defined(__SSE4_1__) || defined(__AVX__) || defined(__SSSE3__) || \
defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \
(defined(_M_IX86_FP) && _M_IX86_FP >= 2)
# define PNG_INTEL_SSE_OPT 1
# endif
# endif
#endif
#if PNG_INTEL_SSE_OPT > 0
# ifndef PNG_INTEL_SSE_IMPLEMENTATION
# if defined(__SSE4_1__) || defined(__AVX__)
/* We are not actually using AVX, but checking for AVX is the best
way we can detect SSE4.1 and SSSE3 on MSVC.
*/
# define PNG_INTEL_SSE_IMPLEMENTATION 3
# elif defined(__SSSE3__)
# define PNG_INTEL_SSE_IMPLEMENTATION 2
# elif defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \
(defined(_M_IX86_FP) && _M_IX86_FP >= 2)
# define PNG_INTEL_SSE_IMPLEMENTATION 1
# else
# define PNG_INTEL_SSE_IMPLEMENTATION 0
# endif
# endif
# if PNG_INTEL_SSE_IMPLEMENTATION > 0
# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_sse2
# endif
#endif
#if PNG_MIPS_MSA_OPT > 0
# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_msa
# ifndef PNG_MIPS_MSA_IMPLEMENTATION
# if defined(__mips_msa)
# if defined(__clang__)
/* At present it is unknown by the libpng developers which versions
* of clang support the intrinsics, however some or perhaps all
* versions do not work with the assembler so this may be
* irrelevant, so just use the default (do nothing here.)
*/
# elif defined(__GNUC__)
/* GCC 4.5.4 NEON support is known to be broken. 4.6.3 is known to
* work, so if this *is* GCC, or G++, look for a version >4.5
*/
# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)
# define PNG_ARM_NEON_IMPLEMENTATION 2
# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7)
# define PNG_MIPS_MSA_IMPLEMENTATION 2
# endif /* no GNUC support */
# endif /* __GNUC__ */
# else /* !defined __ARM_NEON__ */
/* The 'intrinsics' code simply won't compile without this -mfpu=neon:
*/
# define PNG_ARM_NEON_IMPLEMENTATION 2
# endif /* __ARM_NEON__ */
# endif /* !PNG_ARM_NEON_IMPLEMENTATION */
# else /* !defined __mips_msa */
# define PNG_MIPS_MSA_IMPLEMENTATION 2
# endif /* __mips_msa */
# endif /* !PNG_MIPS_MSA_IMPLEMENTATION */
# ifndef PNG_ARM_NEON_IMPLEMENTATION
/* Use the intrinsics code by default. */
# define PNG_ARM_NEON_IMPLEMENTATION 1
# ifndef PNG_MIPS_MSA_IMPLEMENTATION
# define PNG_MIPS_MSA_IMPLEMENTATION 1
# endif
#endif /* PNG_ARM_NEON_OPT > 0 */
#endif /* PNG_MIPS_MSA_OPT > 0 */
#if PNG_POWERPC_VSX_OPT > 0
# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_vsx
# define PNG_POWERPC_VSX_IMPLEMENTATION 1
#endif
/* Is this a build of a DLL where compilation of the object modules requires
* different preprocessor settings to those required for a simple library? If
@ -374,25 +454,6 @@
# define png_fixed_error(s1,s2) png_err(s1)
#endif
/* C allows up-casts from (void*) to any pointer and (const void*) to any
* pointer to a const object. C++ regards this as a type error and requires an
* explicit, static, cast and provides the static_cast<> rune to ensure that
* const is not cast away.
*/
#ifdef __cplusplus
# define png_voidcast(type, value) static_cast<type>(value)
# define png_constcast(type, value) const_cast<type>(value)
# define png_aligncast(type, value) \
static_cast<type>(static_cast<void*>(value))
# define png_aligncastconst(type, value) \
static_cast<type>(static_cast<const void*>(value))
#else
# define png_voidcast(type, value) (value)
# define png_constcast(type, value) ((type)(value))
# define png_aligncast(type, value) ((void*)(value))
# define png_aligncastconst(type, value) ((const void*)(value))
#endif /* __cplusplus */
/* Some fixed point APIs are still required even if not exported because
* they get used by the corresponding floating point APIs. This magic
* deals with this:
@ -407,6 +468,35 @@
/* Other defines specific to compilers can go here. Try to keep
* them inside an appropriate ifdef/endif pair for portability.
*/
/* C allows up-casts from (void*) to any pointer and (const void*) to any
* pointer to a const object. C++ regards this as a type error and requires an
* explicit, static, cast and provides the static_cast<> rune to ensure that
* const is not cast away.
*/
#ifdef __cplusplus
# define png_voidcast(type, value) static_cast<type>(value)
# define png_constcast(type, value) const_cast<type>(value)
# define png_aligncast(type, value) \
static_cast<type>(static_cast<void*>(value))
# define png_aligncastconst(type, value) \
static_cast<type>(static_cast<const void*>(value))
#else
# define png_voidcast(type, value) (value)
# ifdef _WIN64
# ifdef __GNUC__
typedef unsigned long long png_ptruint;
# else
typedef unsigned __int64 png_ptruint;
# endif
# else
typedef unsigned long png_ptruint;
# endif
# define png_constcast(type, value) ((type)(png_ptruint)(const void*)(value))
# define png_aligncast(type, value) ((void*)(value))
# define png_aligncastconst(type, value) ((const void*)(value))
#endif /* __cplusplus */
#if defined(PNG_FLOATING_POINT_SUPPORTED) ||\
defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)
/* png.c requires the following ANSI-C constants if the conversion of
@ -420,10 +510,10 @@
# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
/* We need to check that <math.h> hasn't already been included earlier
* as it seems it doesn't agree with <fp.h>, yet we should really use
* <fp.h> if possible.
*/
/* We need to check that <math.h> hasn't already been included earlier
* as it seems it doesn't agree with <fp.h>, yet we should really use
* <fp.h> if possible.
*/
# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
# include <fp.h>
# endif
@ -431,9 +521,9 @@
# include <math.h>
# endif
# if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
/* Amiga SAS/C: We must include builtin FPU functions when compiling using
* MATH=68881
*/
/* Amiga SAS/C: We must include builtin FPU functions when compiling using
* MATH=68881
*/
# include <m68881.h>
# endif
#endif
@ -504,7 +594,8 @@
/* This implicitly assumes alignment is always to a power of 2. */
#ifdef png_alignof
# define png_isaligned(ptr, type)\
((((const char*)ptr-(const char*)0) & (png_alignof(type)-1)) == 0)
(((type)((const char*)ptr-(const char*)0) & \
(type)(png_alignof(type)-1)) == 0)
#else
# define png_isaligned(ptr, type) 0
#endif
@ -521,96 +612,92 @@
* are defined in png.h because they need to be visible to applications
* that call png_set_unknown_chunk().
*/
/* #define PNG_HAVE_IHDR 0x01 (defined in png.h) */
/* #define PNG_HAVE_PLTE 0x02 (defined in png.h) */
#define PNG_HAVE_IDAT 0x04
/* #define PNG_AFTER_IDAT 0x08 (defined in png.h) */
#define PNG_HAVE_IEND 0x10
/* 0x20 (unused) */
/* 0x40 (unused) */
/* 0x80 (unused) */
#define PNG_HAVE_CHUNK_HEADER 0x100
#define PNG_WROTE_tIME 0x200
#define PNG_WROTE_INFO_BEFORE_PLTE 0x400
#define PNG_BACKGROUND_IS_GRAY 0x800
#define PNG_HAVE_PNG_SIGNATURE 0x1000
#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */
/* 0x4000 (unused) */
#define PNG_IS_READ_STRUCT 0x8000 /* Else is a write struct */
/* #define PNG_HAVE_IHDR 0x01U (defined in png.h) */
/* #define PNG_HAVE_PLTE 0x02U (defined in png.h) */
#define PNG_HAVE_IDAT 0x04U
/* #define PNG_AFTER_IDAT 0x08U (defined in png.h) */
#define PNG_HAVE_IEND 0x10U
/* 0x20U (unused) */
/* 0x40U (unused) */
/* 0x80U (unused) */
#define PNG_HAVE_CHUNK_HEADER 0x100U
#define PNG_WROTE_tIME 0x200U
#define PNG_WROTE_INFO_BEFORE_PLTE 0x400U
#define PNG_BACKGROUND_IS_GRAY 0x800U
#define PNG_HAVE_PNG_SIGNATURE 0x1000U
#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000U /* Have another chunk after IDAT */
/* 0x4000U (unused) */
#define PNG_IS_READ_STRUCT 0x8000U /* Else is a write struct */
/* Flags for the transformations the PNG library does on the image data */
#define PNG_BGR 0x0001
#define PNG_INTERLACE 0x0002
#define PNG_PACK 0x0004
#define PNG_SHIFT 0x0008
#define PNG_SWAP_BYTES 0x0010
#define PNG_INVERT_MONO 0x0020
#define PNG_QUANTIZE 0x0040
#define PNG_COMPOSE 0x0080 /* Was PNG_BACKGROUND */
#define PNG_BACKGROUND_EXPAND 0x0100
#define PNG_EXPAND_16 0x0200 /* Added to libpng 1.5.2 */
#define PNG_16_TO_8 0x0400 /* Becomes 'chop' in 1.5.4 */
#define PNG_RGBA 0x0800
#define PNG_EXPAND 0x1000
#define PNG_GAMMA 0x2000
#define PNG_GRAY_TO_RGB 0x4000
#define PNG_FILLER 0x8000
#define PNG_PACKSWAP 0x10000
#define PNG_SWAP_ALPHA 0x20000
#define PNG_STRIP_ALPHA 0x40000
#define PNG_INVERT_ALPHA 0x80000
#define PNG_USER_TRANSFORM 0x100000
#define PNG_RGB_TO_GRAY_ERR 0x200000
#define PNG_RGB_TO_GRAY_WARN 0x400000
#define PNG_RGB_TO_GRAY 0x600000 /* two bits, RGB_TO_GRAY_ERR|WARN */
#define PNG_ENCODE_ALPHA 0x800000 /* Added to libpng-1.5.4 */
#define PNG_ADD_ALPHA 0x1000000 /* Added to libpng-1.2.7 */
#define PNG_EXPAND_tRNS 0x2000000 /* Added to libpng-1.2.9 */
#define PNG_SCALE_16_TO_8 0x4000000 /* Added to libpng-1.5.4 */
/* 0x8000000 unused */
/* 0x10000000 unused */
/* 0x20000000 unused */
/* 0x40000000 unused */
#define PNG_BGR 0x0001U
#define PNG_INTERLACE 0x0002U
#define PNG_PACK 0x0004U
#define PNG_SHIFT 0x0008U
#define PNG_SWAP_BYTES 0x0010U
#define PNG_INVERT_MONO 0x0020U
#define PNG_QUANTIZE 0x0040U
#define PNG_COMPOSE 0x0080U /* Was PNG_BACKGROUND */
#define PNG_BACKGROUND_EXPAND 0x0100U
#define PNG_EXPAND_16 0x0200U /* Added to libpng 1.5.2 */
#define PNG_16_TO_8 0x0400U /* Becomes 'chop' in 1.5.4 */
#define PNG_RGBA 0x0800U
#define PNG_EXPAND 0x1000U
#define PNG_GAMMA 0x2000U
#define PNG_GRAY_TO_RGB 0x4000U
#define PNG_FILLER 0x8000U
#define PNG_PACKSWAP 0x10000U
#define PNG_SWAP_ALPHA 0x20000U
#define PNG_STRIP_ALPHA 0x40000U
#define PNG_INVERT_ALPHA 0x80000U
#define PNG_USER_TRANSFORM 0x100000U
#define PNG_RGB_TO_GRAY_ERR 0x200000U
#define PNG_RGB_TO_GRAY_WARN 0x400000U
#define PNG_RGB_TO_GRAY 0x600000U /* two bits, RGB_TO_GRAY_ERR|WARN */
#define PNG_ENCODE_ALPHA 0x800000U /* Added to libpng-1.5.4 */
#define PNG_ADD_ALPHA 0x1000000U /* Added to libpng-1.2.7 */
#define PNG_EXPAND_tRNS 0x2000000U /* Added to libpng-1.2.9 */
#define PNG_SCALE_16_TO_8 0x4000000U /* Added to libpng-1.5.4 */
/* 0x8000000U unused */
/* 0x10000000U unused */
/* 0x20000000U unused */
/* 0x40000000U unused */
/* Flags for png_create_struct */
#define PNG_STRUCT_PNG 0x0001
#define PNG_STRUCT_INFO 0x0002
/* Scaling factor for filter heuristic weighting calculations */
#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT))
#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT))
#define PNG_STRUCT_PNG 0x0001U
#define PNG_STRUCT_INFO 0x0002U
/* Flags for the png_ptr->flags rather than declaring a byte for each one */
#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001
#define PNG_FLAG_ZSTREAM_INITIALIZED 0x0002 /* Added to libpng-1.6.0 */
/* 0x0004 unused */
#define PNG_FLAG_ZSTREAM_ENDED 0x0008 /* Added to libpng-1.6.0 */
/* 0x0010 unused */
/* 0x0020 unused */
#define PNG_FLAG_ROW_INIT 0x0040
#define PNG_FLAG_FILLER_AFTER 0x0080
#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100
#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200
#define PNG_FLAG_CRC_CRITICAL_USE 0x0400
#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800
#define PNG_FLAG_ASSUME_sRGB 0x1000 /* Added to libpng-1.5.4 */
#define PNG_FLAG_OPTIMIZE_ALPHA 0x2000 /* Added to libpng-1.5.4 */
#define PNG_FLAG_DETECT_UNINITIALIZED 0x4000 /* Added to libpng-1.5.4 */
/* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000 */
/* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000 */
#define PNG_FLAG_LIBRARY_MISMATCH 0x20000
#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000
#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000
#define PNG_FLAG_BENIGN_ERRORS_WARN 0x100000 /* Added to libpng-1.4.0 */
#define PNG_FLAG_APP_WARNINGS_WARN 0x200000 /* Added to libpng-1.6.0 */
#define PNG_FLAG_APP_ERRORS_WARN 0x400000 /* Added to libpng-1.6.0 */
/* 0x800000 unused */
/* 0x1000000 unused */
/* 0x2000000 unused */
/* 0x4000000 unused */
/* 0x8000000 unused */
/* 0x10000000 unused */
/* 0x20000000 unused */
/* 0x40000000 unused */
#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001U
#define PNG_FLAG_ZSTREAM_INITIALIZED 0x0002U /* Added to libpng-1.6.0 */
/* 0x0004U unused */
#define PNG_FLAG_ZSTREAM_ENDED 0x0008U /* Added to libpng-1.6.0 */
/* 0x0010U unused */
/* 0x0020U unused */
#define PNG_FLAG_ROW_INIT 0x0040U
#define PNG_FLAG_FILLER_AFTER 0x0080U
#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100U
#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200U
#define PNG_FLAG_CRC_CRITICAL_USE 0x0400U
#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800U
#define PNG_FLAG_ASSUME_sRGB 0x1000U /* Added to libpng-1.5.4 */
#define PNG_FLAG_OPTIMIZE_ALPHA 0x2000U /* Added to libpng-1.5.4 */
#define PNG_FLAG_DETECT_UNINITIALIZED 0x4000U /* Added to libpng-1.5.4 */
/* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000U */
/* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000U */
#define PNG_FLAG_LIBRARY_MISMATCH 0x20000U
#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000U
#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000U
#define PNG_FLAG_BENIGN_ERRORS_WARN 0x100000U /* Added to libpng-1.4.0 */
#define PNG_FLAG_APP_WARNINGS_WARN 0x200000U /* Added to libpng-1.6.0 */
#define PNG_FLAG_APP_ERRORS_WARN 0x400000U /* Added to libpng-1.6.0 */
/* 0x800000U unused */
/* 0x1000000U unused */
/* 0x2000000U unused */
/* 0x4000000U unused */
/* 0x8000000U unused */
/* 0x10000000U unused */
/* 0x20000000U unused */
/* 0x40000000U unused */
#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
PNG_FLAG_CRC_ANCILLARY_NOWARN)
@ -644,6 +731,24 @@
((png_size_t)(width) * (((png_size_t)(pixel_bits)) >> 3)) : \
(( ((png_size_t)(width) * ((png_size_t)(pixel_bits))) + 7) >> 3) )
/* This returns the number of trailing bits in the last byte of a row, 0 if the
* last byte is completely full of pixels. It is, in principle, (pixel_bits x
* width) % 8, but that would overflow for large 'width'. The second macro is
* the same except that it returns the number of unused bits in the last byte;
* (8-TRAILBITS), but 0 when TRAILBITS is 0.
*
* NOTE: these macros are intended to be self-evidently correct and never
* overflow on the assumption that pixel_bits is in the range 0..255. The
* arguments are evaluated only once and they can be signed (e.g. as a result of
* the integral promotions). The result of the expression always has type
* (png_uint_32), however the compiler always knows it is in the range 0..7.
*/
#define PNG_TRAILBITS(pixel_bits, width) \
(((pixel_bits) * ((width) % (png_uint_32)8)) % 8)
#define PNG_PADBITS(pixel_bits, width) \
((8 - PNG_TRAILBITS(pixel_bits, width)) % 8)
/* PNG_OUT_OF_RANGE returns true if value is outside the range
* ideal-delta..ideal+delta. Each argument is evaluated twice.
* "ideal" and "delta" should be constants, normally simple
@ -669,7 +774,7 @@
/* The fixed point conversion performs range checking and evaluates
* its argument multiple times, so must be used with care. The
* range checking uses the PNG specification values for a signed
* 32 bit fixed point value except that the values are deliberately
* 32-bit fixed point value except that the values are deliberately
* rounded-to-zero to an integral value - 21474 (21474.83 is roughly
* (2^31-1) * 100000). 's' is a string that describes the value being
* converted.
@ -737,6 +842,7 @@
#define png_PLTE PNG_U32( 80, 76, 84, 69)
#define png_bKGD PNG_U32( 98, 75, 71, 68)
#define png_cHRM PNG_U32( 99, 72, 82, 77)
#define png_eXIf PNG_U32(101, 88, 73, 102) /* registered July 2017 */
#define png_fRAc PNG_U32(102, 82, 65, 99) /* registered, not defined */
#define png_gAMA PNG_U32(103, 65, 77, 65)
#define png_gIFg PNG_U32(103, 73, 70, 103)
@ -816,7 +922,7 @@
*/
#endif
/* This is used for 16 bit gamma tables -- only the top level pointers are
/* This is used for 16-bit gamma tables -- only the top level pointers are
* const; this could be changed:
*/
typedef const png_uint_16p * png_const_uint_16pp;
@ -1029,7 +1135,7 @@ PNG_INTERNAL_FUNCTION(void,png_write_sBIT,(png_structrp png_ptr,
#ifdef PNG_WRITE_cHRM_SUPPORTED
PNG_INTERNAL_FUNCTION(void,png_write_cHRM_fixed,(png_structrp png_ptr,
const png_xy *xy), PNG_EMPTY);
/* The xy value must have been previously validated */
/* The xy value must have been previously validated */
#endif
#ifdef PNG_WRITE_sRGB_SUPPORTED
@ -1037,6 +1143,11 @@ PNG_INTERNAL_FUNCTION(void,png_write_sRGB,(png_structrp png_ptr,
int intent),PNG_EMPTY);
#endif
#ifdef PNG_WRITE_eXIf_SUPPORTED
PNG_INTERNAL_FUNCTION(void,png_write_eXIf,(png_structrp png_ptr,
png_bytep exif, int num_exif),PNG_EMPTY);
#endif
#ifdef PNG_WRITE_iCCP_SUPPORTED
PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr,
png_const_charp name, png_const_bytep profile), PNG_EMPTY);
@ -1178,6 +1289,7 @@ PNG_INTERNAL_FUNCTION(void,png_do_write_interlace,(png_row_infop row_info,
PNG_INTERNAL_FUNCTION(void,png_read_filter_row,(png_structrp pp, png_row_infop
row_info, png_bytep row, png_const_bytep prev_row, int filter),PNG_EMPTY);
#if PNG_ARM_NEON_OPT > 0
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_neon,(png_row_infop row_info,
png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_neon,(png_row_infop
@ -1192,6 +1304,56 @@ PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_neon,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
#endif
#if PNG_MIPS_MSA_OPT > 0
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_msa,(png_row_infop row_info,
png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_msa,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_msa,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_msa,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_msa,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_msa,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_msa,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
#endif
#if PNG_POWERPC_VSX_OPT > 0
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_vsx,(png_row_infop row_info,
png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_vsx,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_vsx,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_vsx,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_vsx,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_vsx,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_vsx,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
#endif
#if PNG_INTEL_SSE_IMPLEMENTATION > 0
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_sse2,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_sse2,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_sse2,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_sse2,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_sse2,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_sse2,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
#endif
/* Choose the best filter to use and filter the row data */
PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr,
@ -1219,6 +1381,14 @@ PNG_INTERNAL_FUNCTION(void,png_read_finish_row,(png_structrp png_ptr),
/* Initialize the row buffers, etc. */
PNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY);
#if ZLIB_VERNUM >= 0x1240
PNG_INTERNAL_FUNCTION(int,png_zlib_inflate,(png_structrp png_ptr, int flush),
PNG_EMPTY);
# define PNG_INFLATE(pp, flush) png_zlib_inflate(pp, flush)
#else /* Zlib < 1.2.4 */
# define PNG_INFLATE(pp, flush) inflate(&(pp)->zstream, flush)
#endif /* Zlib < 1.2.4 */
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
/* Optional call to update the users info structure */
PNG_INTERNAL_FUNCTION(void,png_read_transform_info,(png_structrp png_ptr,
@ -1277,6 +1447,11 @@ PNG_INTERNAL_FUNCTION(void,png_handle_cHRM,(png_structrp png_ptr,
png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
#endif
#ifdef PNG_READ_eXIf_SUPPORTED
PNG_INTERNAL_FUNCTION(void,png_handle_eXIf,(png_structrp png_ptr,
png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
#endif
#ifdef PNG_READ_gAMA_SUPPORTED
PNG_INTERNAL_FUNCTION(void,png_handle_gAMA,(png_structrp png_ptr,
png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
@ -1352,8 +1527,11 @@ PNG_INTERNAL_FUNCTION(void,png_handle_zTXt,(png_structrp png_ptr,
png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
#endif
PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_structrp png_ptr,
png_uint_32 chunk_name),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_const_structrp png_ptr,
const png_uint_32 chunk_name),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_check_chunk_length,(png_const_structrp png_ptr,
const png_uint_32 chunk_length),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr,
png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY);
@ -1409,7 +1587,7 @@ PNG_INTERNAL_FUNCTION(void,png_push_have_info,(png_structrp png_ptr,
PNG_INTERNAL_FUNCTION(void,png_push_have_end,(png_structrp png_ptr,
png_inforp info_ptr),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_push_have_row,(png_structrp png_ptr,
png_bytep row),PNG_EMPTY);
png_bytep row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_push_read_end,(png_structrp png_ptr,
png_inforp info_ptr),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_process_some_data,(png_structrp png_ptr,
@ -1448,13 +1626,13 @@ PNG_INTERNAL_FUNCTION(void,png_colorspace_set_gamma,(png_const_structrp png_ptr,
PNG_INTERNAL_FUNCTION(void,png_colorspace_sync_info,(png_const_structrp png_ptr,
png_inforp info_ptr), PNG_EMPTY);
/* Synchronize the info 'valid' flags with the colorspace */
/* Synchronize the info 'valid' flags with the colorspace */
PNG_INTERNAL_FUNCTION(void,png_colorspace_sync,(png_const_structrp png_ptr,
png_inforp info_ptr), PNG_EMPTY);
/* Copy the png_struct colorspace to the info_struct and call the above to
* synchronize the flags. Checks for NULL info_ptr and does nothing.
*/
/* Copy the png_struct colorspace to the info_struct and call the above to
* synchronize the flags. Checks for NULL info_ptr and does nothing.
*/
#endif
/* Added at libpng version 1.4.0 */
@ -1488,9 +1666,11 @@ PNG_INTERNAL_FUNCTION(int,png_colorspace_set_ICC,(png_const_structrp png_ptr,
/* The 'name' is used for information only */
/* Routines for checking parts of an ICC profile. */
#ifdef PNG_READ_iCCP_SUPPORTED
PNG_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr,
png_colorspacerp colorspace, png_const_charp name,
png_uint_32 profile_length), PNG_EMPTY);
#endif /* READ_iCCP */
PNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr,
png_colorspacerp colorspace, png_const_charp name,
png_uint_32 profile_length,
@ -1909,10 +2089,25 @@ PNG_INTERNAL_FUNCTION(void, PNG_FILTER_OPTIMIZATIONS, (png_structp png_ptr,
* the builder of libpng passes the definition of PNG_FILTER_OPTIMIZATIONS in
* CFLAGS in place of CPPFLAGS *and* uses symbol prefixing.
*/
# if PNG_ARM_NEON_OPT > 0
PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon,
(png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
#endif
#if PNG_MIPS_MSA_OPT > 0
PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_msa,
(png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
#endif
# if PNG_INTEL_SSE_IMPLEMENTATION > 0
PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2,
(png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
# endif
#endif
PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr,
png_const_charp key, png_bytep new_key), PNG_EMPTY);
/* Maintainer: Put new private prototypes here ^ */
#include "pngdebug.h"

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
/* pngrio.c - functions for data input
*
* Last changed in libpng 1.6.17 [March 26, 2015]
* Copyright (c) 1998-2015 Glenn Randers-Pehrson
* Last changed in libpng 1.6.24 [August 4, 2016]
* Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
@ -26,7 +26,7 @@
* reads from a file pointer. Note that this routine sometimes gets called
* with very small lengths, so you should implement some kind of simple
* buffering if you are using unbuffered reads. This should never be asked
* to read more than 64K on a 16 bit machine.
* to read more than 64K on a 16-bit machine.
*/
void /* PRIVATE */
png_read_data(png_structrp png_ptr, png_bytep data, png_size_t length)
@ -85,7 +85,7 @@ png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
*/
void PNGAPI
png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr,
png_rw_ptr read_data_fn)
png_rw_ptr read_data_fn)
{
if (png_ptr == NULL)
return;

View File

@ -1,8 +1,8 @@
/* pngrtran.c - transforms the data in a row for PNG readers
*
* Last changed in libpng 1.6.18 [July 23, 2015]
* Copyright (c) 1998-2015 Glenn Randers-Pehrson
* Last changed in libpng 1.6.33 [September 28, 2017]
* Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
@ -48,7 +48,8 @@ png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action)
case PNG_CRC_WARN_DISCARD: /* Not a valid action for critical data */
png_warning(png_ptr,
"Can't discard critical data on CRC error");
"Can't discard critical data on CRC error");
/* FALLTHROUGH */
case PNG_CRC_ERROR_QUIT: /* Error/quit */
case PNG_CRC_DEFAULT:
@ -101,7 +102,7 @@ png_rtran_ok(png_structrp png_ptr, int need_IHDR)
{
if ((png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
png_app_error(png_ptr,
"invalid after png_start_read_image or png_read_update_info");
"invalid after png_start_read_image or png_read_update_info");
else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0)
png_app_error(png_ptr, "invalid before the PNG header has been read");
@ -159,7 +160,7 @@ png_set_background(png_structrp png_ptr,
png_set_background_fixed(png_ptr, background_color, background_gamma_code,
need_expand, png_fixed(png_ptr, background_gamma, "png_set_background"));
}
# endif /* FLOATING_POINT */
# endif /* FLOATING_POINT */
#endif /* READ_BACKGROUND */
/* Scale 16-bit depth files to 8-bit depth. If both of these are set then the
@ -209,7 +210,7 @@ png_set_strip_alpha(png_structrp png_ptr)
#if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED)
static png_fixed_point
translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma,
int is_screen)
int is_screen)
{
/* Check for flag values. The main reason for having the old Mac value as a
* flag is that it is pretty near impossible to work out what the correct
@ -273,7 +274,7 @@ convert_gamma_value(png_structrp png_ptr, double output_gamma)
#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
void PNGFAPI
png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
png_fixed_point output_gamma)
png_fixed_point output_gamma)
{
int compose = 0;
png_fixed_point file_gamma;
@ -289,9 +290,12 @@ png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
* is expected to be 1 or greater, but this range test allows for some
* viewing correction values. The intent is to weed out users of this API
* who use the inverse of the gamma value accidentally! Since some of these
* values are reasonable this may have to be changed.
* values are reasonable this may have to be changed:
*
* 1.6.x: changed from 0.07..3 to 0.01..100 (to accomodate the optimal 16-bit
* gamma of 36, and its reciprocal.)
*/
if (output_gamma < 70000 || output_gamma > 300000)
if (output_gamma < 1000 || output_gamma > 10000000)
png_error(png_ptr, "output gamma out of expected range");
/* The default file gamma is the inverse of the output gamma; the output
@ -374,7 +378,7 @@ png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
if ((png_ptr->transformations & PNG_COMPOSE) != 0)
png_error(png_ptr,
"conflicting calls to set alpha mode and background");
"conflicting calls to set alpha mode and background");
png_ptr->transformations |= PNG_COMPOSE;
}
@ -385,7 +389,7 @@ void PNGAPI
png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma)
{
png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr,
output_gamma));
output_gamma));
}
# endif
#endif
@ -426,7 +430,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
int i;
png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,
(png_uint_32)(num_palette * (sizeof (png_byte))));
(png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte))));
for (i = 0; i < num_palette; i++)
png_ptr->quantize_index[i] = (png_byte)i;
}
@ -443,7 +447,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
/* Initialize an array to sort colors */
png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,
(png_uint_32)(num_palette * (sizeof (png_byte))));
(png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte))));
/* Initialize the quantize_sort array */
for (i = 0; i < num_palette; i++)
@ -577,9 +581,11 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
/* Initialize palette index arrays */
png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
(png_uint_32)(num_palette * (sizeof (png_byte))));
(png_alloc_size_t)((png_uint_32)num_palette *
(sizeof (png_byte))));
png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
(png_uint_32)(num_palette * (sizeof (png_byte))));
(png_alloc_size_t)((png_uint_32)num_palette *
(sizeof (png_byte))));
/* Initialize the sort array */
for (i = 0; i < num_palette; i++)
@ -588,7 +594,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
png_ptr->palette_to_index[i] = (png_byte)i;
}
hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 *
hash = (png_dsortpp)png_calloc(png_ptr, (png_alloc_size_t)(769 *
(sizeof (png_dsortp))));
num_new_palette = num_palette;
@ -619,7 +625,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
{
t = (png_dsortp)png_malloc_warn(png_ptr,
(png_uint_32)(sizeof (png_dsort)));
(png_alloc_size_t)(sizeof (png_dsort)));
if (t == NULL)
break;
@ -744,9 +750,9 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
png_size_t num_entries = ((png_size_t)1 << total_bits);
png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr,
(png_uint_32)(num_entries * (sizeof (png_byte))));
(png_alloc_size_t)(num_entries * (sizeof (png_byte))));
distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
distance = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)(num_entries *
(sizeof (png_byte))));
memset(distance, 0xff, num_entries * (sizeof (png_byte)));
@ -799,7 +805,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
#ifdef PNG_READ_GAMMA_SUPPORTED
void PNGFAPI
png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma,
png_fixed_point file_gamma)
png_fixed_point file_gamma)
{
png_debug(1, "in png_set_gamma_fixed");
@ -841,7 +847,7 @@ void PNGAPI
png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma)
{
png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma),
convert_gamma_value(png_ptr, file_gamma));
convert_gamma_value(png_ptr, file_gamma));
}
# endif /* FLOATING_POINT */
#endif /* READ_GAMMA */
@ -976,7 +982,6 @@ png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
default:
png_error(png_ptr, "invalid error action to rgb_to_gray");
break;
}
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
@ -988,7 +993,7 @@ png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
* that it just worked and get a memory overwrite.
*/
png_error(png_ptr,
"Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED");
"Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED");
/* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */
}
@ -1015,7 +1020,7 @@ png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
{
if (red >= 0 && green >= 0)
png_app_warning(png_ptr,
"ignoring out of range rgb_to_gray coefficients");
"ignoring out of range rgb_to_gray coefficients");
/* Use the defaults, from the cHRM chunk if set, else the historical
* values which are close to the sRGB/HDTV/ITU-Rec 709 values. See
@ -1024,7 +1029,7 @@ png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
* something has already provided a default.
*/
if (png_ptr->rgb_to_gray_red_coeff == 0 &&
png_ptr->rgb_to_gray_green_coeff == 0)
png_ptr->rgb_to_gray_green_coeff == 0)
{
png_ptr->rgb_to_gray_red_coeff = 6968;
png_ptr->rgb_to_gray_green_coeff = 23434;
@ -1041,10 +1046,10 @@ png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
void PNGAPI
png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red,
double green)
double green)
{
png_set_rgb_to_gray_fixed(png_ptr, error_action,
png_fixed(png_ptr, red, "rgb to gray red coefficient"),
png_fixed(png_ptr, red, "rgb to gray red coefficient"),
png_fixed(png_ptr, green, "rgb to gray green coefficient"));
}
#endif /* FLOATING POINT */
@ -1251,7 +1256,7 @@ png_init_rgb_transformations(png_structrp png_ptr)
default:
case 8:
/* FALL THROUGH (Already 8 bits) */
/* FALLTHROUGH */ /* (Already 8 bits) */
case 16:
/* Already a full 16 bits */
@ -1301,7 +1306,7 @@ png_init_read_transformations(png_structrp png_ptr)
{
if (png_ptr->screen_gamma != 0) /* screen set too */
gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma,
png_ptr->screen_gamma);
png_ptr->screen_gamma);
else
/* Assume the output matches the input; a long time default behavior
@ -1582,7 +1587,7 @@ png_init_read_transformations(png_structrp png_ptr)
*/
if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
png_warning(png_ptr,
"libpng does not support gamma+background+rgb_to_gray");
"libpng does not support gamma+background+rgb_to_gray");
if ((png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) != 0)
{
@ -1618,13 +1623,13 @@ png_init_read_transformations(png_structrp png_ptr)
case PNG_BACKGROUND_GAMMA_FILE:
g = png_reciprocal(png_ptr->colorspace.gamma);
gs = png_reciprocal2(png_ptr->colorspace.gamma,
png_ptr->screen_gamma);
png_ptr->screen_gamma);
break;
case PNG_BACKGROUND_GAMMA_UNIQUE:
g = png_reciprocal(png_ptr->background_gamma);
gs = png_reciprocal2(png_ptr->background_gamma,
png_ptr->screen_gamma);
png_ptr->screen_gamma);
break;
default:
g = PNG_FP_1; /* back_1 */
@ -1652,11 +1657,11 @@ png_init_read_transformations(png_structrp png_ptr)
if (png_gamma_significant(g) != 0)
{
back_1.red = png_gamma_8bit_correct(png_ptr->background.red,
g);
g);
back_1.green = png_gamma_8bit_correct(
png_ptr->background.green, g);
png_ptr->background.green, g);
back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue,
g);
g);
}
else
@ -1727,7 +1732,7 @@ png_init_read_transformations(png_structrp png_ptr)
case PNG_BACKGROUND_GAMMA_FILE:
g = png_reciprocal(png_ptr->colorspace.gamma);
gs = png_reciprocal2(png_ptr->colorspace.gamma,
png_ptr->screen_gamma);
png_ptr->screen_gamma);
break;
case PNG_BACKGROUND_GAMMA_UNIQUE:
@ -1913,7 +1918,7 @@ png_init_read_transformations(png_structrp png_ptr)
png_ptr->palette[i].blue = (png_byte)component;
}
}
#endif /* READ_SHIFT */
#endif /* READ_SHIFT */
}
/* Modify the info structure to reflect the transformations. The
@ -1997,7 +2002,7 @@ png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr)
# endif
# else
/* No 16 bit support: force chopping 16-bit input down to 8, in this case
/* No 16-bit support: force chopping 16-bit input down to 8, in this case
* the app program can chose if both APIs are available by setting the
* correct scaling to use.
*/
@ -2098,10 +2103,10 @@ png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr)
defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
{
if (info_ptr->bit_depth < png_ptr->user_transform_depth)
if (png_ptr->user_transform_depth != 0)
info_ptr->bit_depth = png_ptr->user_transform_depth;
if (info_ptr->channels < png_ptr->user_transform_channels)
if (png_ptr->user_transform_channels != 0)
info_ptr->channels = png_ptr->user_transform_channels;
}
#endif
@ -2148,7 +2153,7 @@ png_do_unpack(png_row_infop row_info, png_bytep row)
{
png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
png_bytep dp = row + (png_size_t)row_width - 1;
png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
png_uint_32 shift = 7U - ((row_width + 7U) & 0x07);
for (i = 0; i < row_width; i++)
{
*dp = (png_byte)((*sp >> shift) & 0x01);
@ -2172,7 +2177,7 @@ png_do_unpack(png_row_infop row_info, png_bytep row)
png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
png_bytep dp = row + (png_size_t)row_width - 1;
png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
png_uint_32 shift = ((3U - ((row_width + 3U) & 0x03)) << 1);
for (i = 0; i < row_width; i++)
{
*dp = (png_byte)((*sp >> shift) & 0x03);
@ -2195,7 +2200,7 @@ png_do_unpack(png_row_infop row_info, png_bytep row)
{
png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
png_bytep dp = row + (png_size_t)row_width - 1;
png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
png_uint_32 shift = ((1U - ((row_width + 1U) & 0x01)) << 2);
for (i = 0; i < row_width; i++)
{
*dp = (png_byte)((*sp >> shift) & 0x0f);
@ -2382,8 +2387,8 @@ png_do_scale_16_to_8(png_row_infop row_info, png_bytep row)
while (sp < ep)
{
/* The input is an array of 16 bit components, these must be scaled to
* 8 bits each. For a 16 bit value V the required value (from the PNG
/* The input is an array of 16-bit components, these must be scaled to
* 8 bits each. For a 16-bit value V the required value (from the PNG
* specification) is:
*
* (V * 255) / 65535
@ -2404,7 +2409,7 @@ png_do_scale_16_to_8(png_row_infop row_info, png_bytep row)
*
* The approximate differs from the exact answer only when (vlo-vhi) is
* 128; it then gives a correction of +1 when the exact correction is
* 0. This gives 128 errors. The exact answer (correct for all 16 bit
* 0. This gives 128 errors. The exact answer (correct for all 16-bit
* input values) is:
*
* error = (vlo-vhi+128)*65535 >> 24;
@ -2932,7 +2937,7 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
* using the equation given in Poynton's ColorFAQ of 1998-01-04 at
* <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008 but
* versions dated 1998 through November 2002 have been archived at
* http://web.archive.org/web/20000816232553/http://www.inforamp.net/
* https://web.archive.org/web/20000816232553/www.inforamp.net/
* ~poynton/notes/colour_and_gamma/ColorFAQ.txt )
* Charles Poynton poynton at poynton.com
*
@ -3148,9 +3153,9 @@ png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
if (red != green || red != blue)
rgb_error |= 1;
/* From 1.5.5 in the 16 bit case do the accurate conversion even
/* From 1.5.5 in the 16-bit case do the accurate conversion even
* in the 'fast' case - this is because this is where the code
* ends up when handling linear 16 bit data.
* ends up when handling linear 16-bit data.
*/
gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >>
15);
@ -3221,7 +3226,8 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
== png_ptr->trans_color.gray)
{
unsigned int tmp = *sp & (0x7f7f >> (7 - shift));
tmp |= png_ptr->background.gray << shift;
tmp |=
(unsigned int)(png_ptr->background.gray << shift);
*sp = (png_byte)(tmp & 0xff);
}
@ -3250,7 +3256,8 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
== png_ptr->trans_color.gray)
{
unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
tmp |= png_ptr->background.gray << shift;
tmp |=
(unsigned int)png_ptr->background.gray << shift;
*sp = (png_byte)(tmp & 0xff);
}
@ -3260,7 +3267,7 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
unsigned int g = (gamma_table [p | (p << 2) |
(p << 4) | (p << 6)] >> 6) & 0x03;
unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
tmp |= g << shift;
tmp |= (unsigned int)(g << shift);
*sp = (png_byte)(tmp & 0xff);
}
@ -3286,7 +3293,8 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
== png_ptr->trans_color.gray)
{
unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
tmp |= png_ptr->background.gray << shift;
tmp |=
(unsigned int)png_ptr->background.gray << shift;
*sp = (png_byte)(tmp & 0xff);
}
@ -3315,8 +3323,9 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
if ((png_uint_16)((*sp >> shift) & 0x0f)
== png_ptr->trans_color.gray)
{
unsigned int tmp = *sp & (0xf0f >> (4 - shift));
tmp |= png_ptr->background.gray << shift;
unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
tmp |=
(unsigned int)(png_ptr->background.gray << shift);
*sp = (png_byte)(tmp & 0xff);
}
@ -3325,8 +3334,8 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
unsigned int p = (*sp >> shift) & 0x0f;
unsigned int g = (gamma_table[p | (p << 4)] >> 4) &
0x0f;
unsigned int tmp = *sp & (0xf0f >> (4 - shift));
tmp |= g << shift;
unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
tmp |= (unsigned int)(g << shift);
*sp = (png_byte)(tmp & 0xff);
}
@ -3351,8 +3360,9 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
if ((png_uint_16)((*sp >> shift) & 0x0f)
== png_ptr->trans_color.gray)
{
unsigned int tmp = *sp & (0xf0f >> (4 - shift));
tmp |= png_ptr->background.gray << shift;
unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
tmp |=
(unsigned int)(png_ptr->background.gray << shift);
*sp = (png_byte)(tmp & 0xff);
}
@ -4193,7 +4203,7 @@ png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
*/
static void
png_do_expand_palette(png_row_infop row_info, png_bytep row,
png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)
png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)
{
int shift, value;
png_bytep sp, dp;
@ -4295,7 +4305,7 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row,
if (num_trans > 0)
{
sp = row + (png_size_t)row_width - 1;
dp = row + (png_size_t)(row_width << 2) - 1;
dp = row + ((png_size_t)row_width << 2) - 1;
for (i = 0; i < row_width; i++)
{
@ -4456,7 +4466,7 @@ png_do_expand(png_row_infop row_info, png_bytep row,
{
gray = gray & 0xff;
sp = row + (png_size_t)row_width - 1;
dp = row + (png_size_t)(row_width << 1) - 1;
dp = row + ((png_size_t)row_width << 1) - 1;
for (i = 0; i < row_width; i++)
{
@ -4500,7 +4510,7 @@ png_do_expand(png_row_infop row_info, png_bytep row,
row_info->channels = 2;
row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
row_width);
row_width);
}
}
else if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
@ -4512,7 +4522,7 @@ png_do_expand(png_row_infop row_info, png_bytep row,
png_byte green = (png_byte)(trans_color->green & 0xff);
png_byte blue = (png_byte)(trans_color->blue & 0xff);
sp = row + (png_size_t)row_info->rowbytes - 1;
dp = row + (png_size_t)(row_width << 2) - 1;
dp = row + ((png_size_t)row_width << 2) - 1;
for (i = 0; i < row_width; i++)
{
if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
@ -4535,7 +4545,7 @@ png_do_expand(png_row_infop row_info, png_bytep row,
png_byte green_low = (png_byte)(trans_color->green & 0xff);
png_byte blue_low = (png_byte)(trans_color->blue & 0xff);
sp = row + row_info->rowbytes - 1;
dp = row + (png_size_t)(row_width << 3) - 1;
dp = row + ((png_size_t)row_width << 3) - 1;
for (i = 0; i < row_width; i++)
{
if (*(sp - 5) == red_high &&
@ -4594,7 +4604,9 @@ png_do_expand_16(png_row_infop row_info, png_bytep row)
png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */
png_byte *dp = sp + row_info->rowbytes; /* destination, end + 1 */
while (dp > sp)
dp[-2] = dp[-1] = *--sp, dp -= 2;
{
dp[-2] = dp[-1] = *--sp; dp -= 2;
}
row_info->rowbytes *= 2;
row_info->bit_depth = 16;
@ -4760,7 +4772,7 @@ png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
(row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
png_do_strip_channel(row_info, png_ptr->row_buf + 1,
0 /* at_start == false, because SWAP_ALPHA happens later */);
0 /* at_start == false, because SWAP_ALPHA happens later */);
#endif
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
/* pngset.c - storage of image information into info struct
*
* Last changed in libpng 1.6.18 [July 23, 2015]
* Copyright (c) 1998-2015 Glenn Randers-Pehrson
* Last changed in libpng 1.6.32 [August 24, 2017]
* Copyright (c) 1998-2017 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
@ -104,14 +104,14 @@ png_set_cHRM(png_const_structrp png_ptr, png_inforp info_ptr,
double green_x, double green_y, double blue_x, double blue_y)
{
png_set_cHRM_fixed(png_ptr, info_ptr,
png_fixed(png_ptr, white_x, "cHRM White X"),
png_fixed(png_ptr, white_y, "cHRM White Y"),
png_fixed(png_ptr, red_x, "cHRM Red X"),
png_fixed(png_ptr, red_y, "cHRM Red Y"),
png_fixed(png_ptr, green_x, "cHRM Green X"),
png_fixed(png_ptr, green_y, "cHRM Green Y"),
png_fixed(png_ptr, blue_x, "cHRM Blue X"),
png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
png_fixed(png_ptr, white_x, "cHRM White X"),
png_fixed(png_ptr, white_y, "cHRM White Y"),
png_fixed(png_ptr, red_x, "cHRM Red X"),
png_fixed(png_ptr, red_y, "cHRM Red Y"),
png_fixed(png_ptr, green_x, "cHRM Green X"),
png_fixed(png_ptr, green_y, "cHRM Green Y"),
png_fixed(png_ptr, blue_x, "cHRM Blue X"),
png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
}
void PNGAPI
@ -120,20 +120,67 @@ png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X,
double blue_X, double blue_Y, double blue_Z)
{
png_set_cHRM_XYZ_fixed(png_ptr, info_ptr,
png_fixed(png_ptr, red_X, "cHRM Red X"),
png_fixed(png_ptr, red_Y, "cHRM Red Y"),
png_fixed(png_ptr, red_Z, "cHRM Red Z"),
png_fixed(png_ptr, green_X, "cHRM Red X"),
png_fixed(png_ptr, green_Y, "cHRM Red Y"),
png_fixed(png_ptr, green_Z, "cHRM Red Z"),
png_fixed(png_ptr, blue_X, "cHRM Red X"),
png_fixed(png_ptr, blue_Y, "cHRM Red Y"),
png_fixed(png_ptr, blue_Z, "cHRM Red Z"));
png_fixed(png_ptr, red_X, "cHRM Red X"),
png_fixed(png_ptr, red_Y, "cHRM Red Y"),
png_fixed(png_ptr, red_Z, "cHRM Red Z"),
png_fixed(png_ptr, green_X, "cHRM Green X"),
png_fixed(png_ptr, green_Y, "cHRM Green Y"),
png_fixed(png_ptr, green_Z, "cHRM Green Z"),
png_fixed(png_ptr, blue_X, "cHRM Blue X"),
png_fixed(png_ptr, blue_Y, "cHRM Blue Y"),
png_fixed(png_ptr, blue_Z, "cHRM Blue Z"));
}
# endif /* FLOATING_POINT */
#endif /* cHRM */
#ifdef PNG_eXIf_SUPPORTED
void PNGAPI
png_set_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
const png_bytep eXIf_buf)
{
png_warning(png_ptr, "png_set_eXIf does not work; use png_set_eXIf_1");
PNG_UNUSED(info_ptr)
PNG_UNUSED(eXIf_buf)
}
void PNGAPI
png_set_eXIf_1(png_const_structrp png_ptr, png_inforp info_ptr,
const png_uint_32 num_exif, const png_bytep eXIf_buf)
{
int i;
png_debug1(1, "in %s storage function", "eXIf");
if (png_ptr == NULL || info_ptr == NULL)
return;
if (info_ptr->exif)
{
png_free(png_ptr, info_ptr->exif);
info_ptr->exif = NULL;
}
info_ptr->num_exif = num_exif;
info_ptr->exif = png_voidcast(png_bytep, png_malloc_warn(png_ptr,
info_ptr->num_exif));
if (info_ptr->exif == NULL)
{
png_warning(png_ptr, "Insufficient memory for eXIf chunk data");
return;
}
info_ptr->free_me |= PNG_FREE_EXIF;
for (i = 0; i < (int) info_ptr->num_exif; i++)
info_ptr->exif[i] = eXIf_buf[i];
info_ptr->valid |= PNG_INFO_eXIf;
}
#endif /* eXIf */
#ifdef PNG_gAMA_SUPPORTED
void PNGFAPI
png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
@ -283,17 +330,29 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
/* Check that the type matches the specification. */
if (type < 0 || type > 3)
png_error(png_ptr, "Invalid pCAL equation type");
{
png_chunk_report(png_ptr, "Invalid pCAL equation type",
PNG_CHUNK_WRITE_ERROR);
return;
}
if (nparams < 0 || nparams > 255)
png_error(png_ptr, "Invalid pCAL parameter count");
{
png_chunk_report(png_ptr, "Invalid pCAL parameter count",
PNG_CHUNK_WRITE_ERROR);
return;
}
/* Validate params[nparams] */
for (i=0; i<nparams; ++i)
{
if (params[i] == NULL ||
!png_check_fp_string(params[i], strlen(params[i])))
png_error(png_ptr, "Invalid format for pCAL parameter");
{
png_chunk_report(png_ptr, "Invalid format for pCAL parameter",
PNG_CHUNK_WRITE_ERROR);
return;
}
}
info_ptr->pcal_purpose = png_voidcast(png_charp,
@ -301,8 +360,8 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
if (info_ptr->pcal_purpose == NULL)
{
png_warning(png_ptr, "Insufficient memory for pCAL purpose");
png_chunk_report(png_ptr, "Insufficient memory for pCAL purpose",
PNG_CHUNK_WRITE_ERROR);
return;
}
@ -316,10 +375,10 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
length = strlen(units) + 1;
png_debug1(3, "allocating units for info (%lu bytes)",
(unsigned long)length);
(unsigned long)length);
info_ptr->pcal_units = png_voidcast(png_charp,
png_malloc_warn(png_ptr, length));
png_malloc_warn(png_ptr, length));
if (info_ptr->pcal_units == NULL)
{
@ -331,7 +390,7 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
memcpy(info_ptr->pcal_units, units, length);
info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr,
(png_size_t)((nparams + 1) * (sizeof (png_charp)))));
(png_size_t)(((unsigned int)nparams + 1) * (sizeof (png_charp)))));
if (info_ptr->pcal_params == NULL)
{
@ -340,7 +399,8 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
return;
}
memset(info_ptr->pcal_params, 0, (nparams + 1) * (sizeof (png_charp)));
memset(info_ptr->pcal_params, 0, ((unsigned int)nparams + 1) *
(sizeof (png_charp)));
for (i = 0; i < nparams; i++)
{
@ -398,7 +458,7 @@ png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr,
png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw);
info_ptr->scal_s_width = png_voidcast(png_charp,
png_malloc_warn(png_ptr, lengthw));
png_malloc_warn(png_ptr, lengthw));
if (info_ptr->scal_s_width == NULL)
{
@ -414,7 +474,7 @@ png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr,
png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh);
info_ptr->scal_s_height = png_voidcast(png_charp,
png_malloc_warn(png_ptr, lengthh));
png_malloc_warn(png_ptr, lengthh));
if (info_ptr->scal_s_height == NULL)
{
@ -453,9 +513,9 @@ png_set_sCAL(png_const_structrp png_ptr, png_inforp info_ptr, int unit,
char sheight[PNG_sCAL_MAX_DIGITS+1];
png_ascii_from_fp(png_ptr, swidth, (sizeof swidth), width,
PNG_sCAL_PRECISION);
PNG_sCAL_PRECISION);
png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height,
PNG_sCAL_PRECISION);
PNG_sCAL_PRECISION);
png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
}
@ -513,12 +573,17 @@ png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr,
png_const_colorp palette, int num_palette)
{
png_uint_32 max_palette_length;
png_debug1(1, "in %s storage function", "PLTE");
if (png_ptr == NULL || info_ptr == NULL)
return;
if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH)
max_palette_length = (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
(1 << info_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;
if (num_palette < 0 || num_palette > (int) max_palette_length)
{
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
png_error(png_ptr, "Invalid palette length");
@ -551,14 +616,15 @@ png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr,
png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
/* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
* of num_palette entries, in case of an invalid PNG file that has
* too-large sample values.
* of num_palette entries, in case of an invalid PNG file or incorrect
* call to png_set_PLTE() with too-large sample values.
*/
png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr,
PNG_MAX_PALETTE_LENGTH * (sizeof (png_color))));
if (num_palette > 0)
memcpy(png_ptr->palette, palette, num_palette * (sizeof (png_color)));
memcpy(png_ptr->palette, palette, (unsigned int)num_palette *
(sizeof (png_color)));
info_ptr->palette = png_ptr->palette;
info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
@ -643,7 +709,7 @@ png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
*/
{
int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name,
proflen, profile, info_ptr->color_type);
proflen, profile, info_ptr->color_type);
png_colorspace_sync_info(png_ptr, info_ptr);
@ -668,7 +734,7 @@ png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
memcpy(new_iccp_name, name, length);
new_iccp_profile = png_voidcast(png_bytep,
png_malloc_warn(png_ptr, proflen));
png_malloc_warn(png_ptr, proflen));
if (new_iccp_profile == NULL)
{
@ -709,7 +775,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
{
int i;
png_debug1(1, "in %lx storage function", png_ptr == NULL ? 0xabadca11 :
png_debug1(1, "in %lx storage function", png_ptr == NULL ? 0xabadca11U :
(unsigned long)png_ptr->chunk_name);
if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL)
@ -743,14 +809,14 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
* the overflow checks.
*/
new_text = png_voidcast(png_textp,png_realloc_array(png_ptr,
info_ptr->text, old_num_text, max_text-old_num_text,
sizeof *new_text));
info_ptr->text, old_num_text, max_text-old_num_text,
sizeof *new_text));
}
if (new_text == NULL)
{
png_chunk_report(png_ptr, "too many text chunks",
PNG_CHUNK_WRITE_ERROR);
PNG_CHUNK_WRITE_ERROR);
return 1;
}
@ -778,7 +844,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)
{
png_chunk_report(png_ptr, "text compression mode is out of range",
PNG_CHUNK_WRITE_ERROR);
PNG_CHUNK_WRITE_ERROR);
continue;
}
@ -810,7 +876,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
# else /* iTXt */
{
png_chunk_report(png_ptr, "iTXt chunk not supported",
PNG_CHUNK_WRITE_ERROR);
PNG_CHUNK_WRITE_ERROR);
continue;
}
# endif
@ -839,7 +905,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
if (textp->key == NULL)
{
png_chunk_report(png_ptr, "text chunk: out of memory",
PNG_CHUNK_WRITE_ERROR);
PNG_CHUNK_WRITE_ERROR);
return 1;
}
@ -947,12 +1013,14 @@ png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr,
png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
/* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
png_ptr->trans_alpha = info_ptr->trans_alpha = png_voidcast(png_bytep,
png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
{
/* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
info_ptr->trans_alpha = png_voidcast(png_bytep,
png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans);
}
png_ptr->trans_alpha = info_ptr->trans_alpha;
}
if (trans_color != NULL)
@ -969,7 +1037,7 @@ png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr,
trans_color->green > sample_max ||
trans_color->blue > sample_max)))
png_warning(png_ptr,
"tRNS chunk has out-of-range samples for bit_depth");
"tRNS chunk has out-of-range samples for bit_depth");
}
#endif
@ -1011,8 +1079,8 @@ png_set_sPLT(png_const_structrp png_ptr,
* overflows. Notice that the parameters are (int) and (size_t)
*/
np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr,
info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries,
sizeof *np));
info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries,
sizeof *np));
if (np == NULL)
{
@ -1073,7 +1141,7 @@ png_set_sPLT(png_const_structrp png_ptr,
* checked it when doing the allocation.
*/
memcpy(np->entries, entries->entries,
entries->nentries * sizeof (png_sPLT_entry));
(unsigned int)entries->nentries * sizeof (png_sPLT_entry));
/* Note that 'continue' skips the advance of the out pointer and out
* count, so an invalid entry is not added.
@ -1081,8 +1149,9 @@ png_set_sPLT(png_const_structrp png_ptr,
info_ptr->valid |= PNG_INFO_sPLT;
++(info_ptr->splt_palettes_num);
++np;
++entries;
}
while (++entries, --nentries);
while (--nentries);
if (nentries > 0)
png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR);
@ -1103,10 +1172,10 @@ check_location(png_const_structrp png_ptr, int location)
{
/* Write struct, so unknown chunks come from the app */
png_app_warning(png_ptr,
"png_set_unknown_chunks now expects a valid location");
"png_set_unknown_chunks now expects a valid location");
/* Use the old behavior */
location = (png_byte)(png_ptr->mode &
(PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT));
(PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT));
}
/* This need not be an internal error - if the app calls
@ -1129,7 +1198,7 @@ check_location(png_const_structrp png_ptr, int location)
void PNGAPI
png_set_unknown_chunks(png_const_structrp png_ptr,
png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
{
png_unknown_chunkp np;
@ -1168,13 +1237,13 @@ png_set_unknown_chunks(png_const_structrp png_ptr,
* appropriate to read or write.
*/
np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr,
info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns,
sizeof *np));
info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns,
sizeof *np));
if (np == NULL)
{
png_chunk_report(png_ptr, "too many unknown chunks",
PNG_CHUNK_WRITE_ERROR);
PNG_CHUNK_WRITE_ERROR);
return;
}
@ -1203,12 +1272,12 @@ png_set_unknown_chunks(png_const_structrp png_ptr,
else
{
np->data = png_voidcast(png_bytep,
png_malloc_base(png_ptr, unknowns->size));
png_malloc_base(png_ptr, unknowns->size));
if (np->data == NULL)
{
png_chunk_report(png_ptr, "unknown chunk: out of memory",
PNG_CHUNK_WRITE_ERROR);
PNG_CHUNK_WRITE_ERROR);
/* But just skip storing the unknown chunk */
continue;
}
@ -1242,7 +1311,7 @@ png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr,
{
png_app_error(png_ptr, "invalid unknown chunk location");
/* Fake out the pre 1.6.0 behavior: */
if ((location & PNG_HAVE_IDAT) != 0) /* undocumented! */
if (((unsigned int)location & PNG_HAVE_IDAT) != 0) /* undocumented! */
location = PNG_AFTER_IDAT;
else
@ -1333,6 +1402,7 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
static PNG_CONST png_byte chunks_to_ignore[] = {
98, 75, 71, 68, '\0', /* bKGD */
99, 72, 82, 77, '\0', /* cHRM */
101, 88, 73, 102, '\0', /* eXIf */
103, 65, 77, 65, '\0', /* gAMA */
104, 73, 83, 84, '\0', /* hIST */
105, 67, 67, 80, '\0', /* iCCP */
@ -1366,7 +1436,7 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
return;
}
num_chunks = num_chunks_in;
num_chunks = (unsigned int)num_chunks_in;
}
old_num_chunks = png_ptr->num_chunk_list;
@ -1415,7 +1485,7 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
for (i=0; i<num_chunks; ++i)
{
old_num_chunks = add_one_chunk(new_list, old_num_chunks,
chunk_list+5*i, keep);
chunk_list+5*i, keep);
}
/* Now remove any spurious 'default' entries. */
@ -1495,60 +1565,60 @@ png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr,
void PNGAPI
png_set_compression_buffer_size(png_structrp png_ptr, png_size_t size)
{
if (png_ptr == NULL)
return;
if (png_ptr == NULL)
return;
if (size == 0 || size > PNG_UINT_31_MAX)
png_error(png_ptr, "invalid compression buffer size");
if (size == 0 || size > PNG_UINT_31_MAX)
png_error(png_ptr, "invalid compression buffer size");
# ifdef PNG_SEQUENTIAL_READ_SUPPORTED
if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
{
png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */
return;
}
if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
{
png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */
return;
}
# endif
# ifdef PNG_WRITE_SUPPORTED
if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
{
if (png_ptr->zowner != 0)
{
if (png_ptr->zowner != 0)
{
png_warning(png_ptr,
"Compression buffer size cannot be changed because it is in use");
png_warning(png_ptr,
"Compression buffer size cannot be changed because it is in use");
return;
}
return;
}
#ifndef __COVERITY__
/* Some compilers complain that this is always false. However, it
* can be true when integer overflow happens.
*/
if (size > ZLIB_IO_MAX)
{
png_warning(png_ptr,
"Compression buffer size limited to system maximum");
size = ZLIB_IO_MAX; /* must fit */
}
/* Some compilers complain that this is always false. However, it
* can be true when integer overflow happens.
*/
if (size > ZLIB_IO_MAX)
{
png_warning(png_ptr,
"Compression buffer size limited to system maximum");
size = ZLIB_IO_MAX; /* must fit */
}
#endif
if (size < 6)
{
/* Deflate will potentially go into an infinite loop on a SYNC_FLUSH
* if this is permitted.
*/
png_warning(png_ptr,
"Compression buffer size cannot be reduced below 6");
if (size < 6)
{
/* Deflate will potentially go into an infinite loop on a SYNC_FLUSH
* if this is permitted.
*/
png_warning(png_ptr,
"Compression buffer size cannot be reduced below 6");
return;
}
if (png_ptr->zbuffer_size != size)
{
png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
png_ptr->zbuffer_size = (uInt)size;
}
return;
}
if (png_ptr->zbuffer_size != size)
{
png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
png_ptr->zbuffer_size = (uInt)size;
}
}
# endif
}
@ -1556,7 +1626,7 @@ void PNGAPI
png_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask)
{
if (png_ptr != NULL && info_ptr != NULL)
info_ptr->valid &= ~mask;
info_ptr->valid &= (unsigned int)(~mask);
}
@ -1568,7 +1638,7 @@ png_set_user_limits (png_structrp png_ptr, png_uint_32 user_width_max,
{
/* Images with dimensions larger than these limits will be
* rejected by png_set_IHDR(). To accept any PNG datastream
* regardless of dimensions, set both limits to 0x7ffffffL.
* regardless of dimensions, set both limits to 0x7fffffff.
*/
if (png_ptr == NULL)
return;
@ -1639,4 +1709,94 @@ png_set_check_for_invalid_index(png_structrp png_ptr, int allowed)
png_ptr->num_palette_max = -1;
}
#endif
#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) || \
defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED)
/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
* and if invalid, correct the keyword rather than discarding the entire
* chunk. The PNG 1.0 specification requires keywords 1-79 characters in
* length, forbids leading or trailing whitespace, multiple internal spaces,
* and the non-break space (0x80) from ISO 8859-1. Returns keyword length.
*
* The 'new_key' buffer must be 80 characters in size (for the keyword plus a
* trailing '\0'). If this routine returns 0 then there was no keyword, or a
* valid one could not be generated, and the caller must png_error.
*/
png_uint_32 /* PRIVATE */
png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)
{
#ifdef PNG_WARNINGS_SUPPORTED
png_const_charp orig_key = key;
#endif
png_uint_32 key_len = 0;
int bad_character = 0;
int space = 1;
png_debug(1, "in png_check_keyword");
if (key == NULL)
{
*new_key = 0;
return 0;
}
while (*key && key_len < 79)
{
png_byte ch = (png_byte)*key++;
if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/))
{
*new_key++ = ch; ++key_len; space = 0;
}
else if (space == 0)
{
/* A space or an invalid character when one wasn't seen immediately
* before; output just a space.
*/
*new_key++ = 32; ++key_len; space = 1;
/* If the character was not a space then it is invalid. */
if (ch != 32)
bad_character = ch;
}
else if (bad_character == 0)
bad_character = ch; /* just skip it, record the first error */
}
if (key_len > 0 && space != 0) /* trailing space */
{
--key_len; --new_key;
if (bad_character == 0)
bad_character = 32;
}
/* Terminate the keyword */
*new_key = 0;
if (key_len == 0)
return 0;
#ifdef PNG_WARNINGS_SUPPORTED
/* Try to only output one warning per keyword: */
if (*key != 0) /* keyword too long */
png_warning(png_ptr, "keyword truncated");
else if (bad_character != 0)
{
PNG_WARNING_PARAMETERS(p)
png_warning_parameter(p, 1, orig_key);
png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character);
png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'");
}
#else /* !WARNINGS */
PNG_UNUSED(png_ptr)
#endif /* !WARNINGS */
return key_len;
}
#endif /* TEXT || pCAL || iCCP || sPLT */
#endif /* READ || WRITE */

View File

@ -1,8 +1,8 @@
/* pngstruct.h - header file for PNG reference library
*
* Last changed in libpng 1.6.18 [July 23, 2015]
* Copyright (c) 1998-2015 Glenn Randers-Pehrson
* Last changed in libpng 1.6.32 [August 24, 2017]
* Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
@ -249,7 +249,7 @@ struct png_struct_def
png_byte filter; /* file filter type (always 0) */
png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
png_byte pass; /* current interlace pass (0 - 6) */
png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */
png_byte do_filter; /* row filter flags (see PNG_FILTER_ in png.h ) */
png_byte color_type; /* color type of file */
png_byte bit_depth; /* bit depth of file */
png_byte usr_bit_depth; /* bit depth of users row: write only */
@ -263,6 +263,9 @@ struct png_struct_def
/* pixel depth used for the row buffers */
png_byte transformed_pixel_depth;
/* pixel depth after read/write transforms */
#if ZLIB_VERNUM >= 0x1240
png_byte zstream_start; /* at start of an input zlib stream */
#endif /* Zlib >= 1.2.4 */
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
png_uint_16 filler; /* filler bytes for pixel expansion */
#endif
@ -350,7 +353,7 @@ struct png_struct_def
/* Options */
#ifdef PNG_SET_OPTION_SUPPORTED
png_byte options; /* On/off state (up to 4 options) */
png_uint_32 options; /* On/off state (up to 16 options) */
#endif
#if PNG_LIBPNG_VER < 10700

View File

@ -1,8 +1,8 @@
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
*
* Last changed in libpng 1.6.18 [July 23, 2015]
* Copyright (c) 1998-2015 Glenn Randers-Pehrson
* Last changed in libpng 1.6.33 [September 28, 2017]
* Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
@ -30,7 +30,7 @@ png_set_bgr(png_structrp png_ptr)
#endif
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
/* Turn on 16 bit byte swapping */
/* Turn on 16-bit byte swapping */
void PNGAPI
png_set_swap(png_structrp png_ptr)
{
@ -172,13 +172,14 @@ png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
* size!
*/
png_app_error(png_ptr,
"png_set_filler is invalid for low bit depth gray output");
"png_set_filler is invalid for"
" low bit depth gray output");
return;
}
default:
png_app_error(png_ptr,
"png_set_filler: inappropriate color type");
"png_set_filler: inappropriate color type");
return;
}
# else
@ -313,7 +314,7 @@ png_do_invert(png_row_infop row_info, png_bytep row)
#ifdef PNG_16BIT_SUPPORTED
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
/* Swaps byte order on 16 bit depth images */
/* Swaps byte order on 16-bit depth images */
void /* PRIVATE */
png_do_swap(png_row_infop row_info, png_bytep row)
{
@ -513,11 +514,15 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
if (at_start != 0) /* Skip initial filler */
++sp;
else /* Skip initial channel and, for sp, the filler */
sp += 2, ++dp;
{
sp += 2; ++dp;
}
/* For a 1 pixel wide image there is nothing to do */
while (sp < ep)
*dp++ = *sp, sp += 2;
{
*dp++ = *sp; sp += 2;
}
row_info->pixel_depth = 8;
}
@ -527,10 +532,14 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
if (at_start != 0) /* Skip initial filler */
sp += 2;
else /* Skip initial channel and, for sp, the filler */
sp += 4, dp += 2;
{
sp += 4; dp += 2;
}
while (sp < ep)
*dp++ = *sp++, *dp++ = *sp, sp += 3;
{
*dp++ = *sp++; *dp++ = *sp; sp += 3;
}
row_info->pixel_depth = 16;
}
@ -553,11 +562,15 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
if (at_start != 0) /* Skip initial filler */
++sp;
else /* Skip initial channels and, for sp, the filler */
sp += 4, dp += 3;
{
sp += 4; dp += 3;
}
/* Note that the loop adds 3 to dp and 4 to sp each time. */
while (sp < ep)
*dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2;
{
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp; sp += 2;
}
row_info->pixel_depth = 24;
}
@ -567,14 +580,16 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
if (at_start != 0) /* Skip initial filler */
sp += 2;
else /* Skip initial channels and, for sp, the filler */
sp += 8, dp += 6;
{
sp += 8; dp += 6;
}
while (sp < ep)
{
/* Copy 6 bytes, skip 2 */
*dp++ = *sp++, *dp++ = *sp++;
*dp++ = *sp++, *dp++ = *sp++;
*dp++ = *sp++, *dp++ = *sp, sp += 3;
*dp++ = *sp++; *dp++ = *sp++;
*dp++ = *sp++; *dp++ = *sp++;
*dp++ = *sp++; *dp++ = *sp; sp += 3;
}
row_info->pixel_depth = 48;
@ -594,7 +609,7 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
return; /* The filler channel has gone already */
/* Fix the rowbytes value. */
row_info->rowbytes = dp-row;
row_info->rowbytes = (png_size_t)(dp-row);
}
#endif
@ -692,8 +707,8 @@ png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
* and this calculation is used because it avoids warnings that other
* forms produced on either GCC or MSVC.
*/
int padding = (-row_info->pixel_depth * row_info->width) & 7;
png_bytep rp = png_ptr->row_buf + row_info->rowbytes;
int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width);
png_bytep rp = png_ptr->row_buf + row_info->rowbytes - 1;
switch (row_info->bit_depth)
{
@ -797,7 +812,7 @@ png_set_user_transform_info(png_structrp png_ptr, png_voidp
(png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
{
png_app_error(png_ptr,
"info change after png_start_read_image or png_read_update_info");
"info change after png_start_read_image or png_read_update_info");
return;
}
#endif

View File

@ -1,8 +1,8 @@
/* pngwio.c - functions for data output
*
* Last changed in libpng 1.6.15 [November 20, 2014]
* Copyright (c) 1998-2014 Glenn Randers-Pehrson
* Last changed in libpng 1.6.24 [August 4, 2016]
* Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
@ -26,7 +26,7 @@
* writes to a file pointer. Note that this routine sometimes gets called
* with very small lengths, so you should implement some kind of simple
* buffering if you are using unbuffered writes. This should never be asked
* to write more than 64K on a 16 bit machine.
* to write more than 64K on a 16-bit machine.
*/
void /* PRIVATE */
@ -35,7 +35,7 @@ png_write_data(png_structrp png_ptr, png_const_bytep data, png_size_t length)
/* NOTE: write_data_fn must not change the buffer! */
if (png_ptr->write_data_fn != NULL )
(*(png_ptr->write_data_fn))(png_ptr, png_constcast(png_bytep,data),
length);
length);
else
png_error(png_ptr, "Call to NULL write function");

View File

@ -1,8 +1,8 @@
/* pngwrite.c - general routines to write a PNG file
*
* Last changed in libpng 1.6.18 [July 23, 2015]
* Copyright (c) 1998-2015 Glenn Randers-Pehrson
* Last changed in libpng 1.6.32 [August 24, 2017]
* Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
@ -12,9 +12,9 @@
*/
#include "pngpriv.h"
#if defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)
#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
# include <errno.h>
#endif
#endif /* SIMPLIFIED_WRITE_STDIO */
#ifdef PNG_WRITE_SUPPORTED
@ -22,7 +22,7 @@
/* Write out all the unknown chunks for the current given location */
static void
write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr,
unsigned int where)
unsigned int where)
{
if (info_ptr->unknown_chunks_num != 0)
{
@ -148,11 +148,11 @@ png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr)
# ifdef PNG_WRITE_sRGB_SUPPORTED
if ((info_ptr->valid & PNG_INFO_sRGB) != 0)
png_app_warning(png_ptr,
"profile matches sRGB but writing iCCP instead");
"profile matches sRGB but writing iCCP instead");
# endif
png_write_iCCP(png_ptr, info_ptr->iccp_name,
info_ptr->iccp_profile);
info_ptr->iccp_profile);
}
# ifdef PNG_WRITE_sRGB_SUPPORTED
else
@ -206,7 +206,7 @@ png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
png_write_PLTE(png_ptr, info_ptr->palette,
(png_uint_32)info_ptr->num_palette);
else if ((info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) !=0)
else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
png_error(png_ptr, "Valid palette required for paletted images");
#ifdef PNG_WRITE_tRNS_SUPPORTED
@ -237,6 +237,11 @@ png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);
#endif
#ifdef PNG_WRITE_eXIf_SUPPORTED
if ((info_ptr->valid & PNG_INFO_eXIf) != 0)
png_write_eXIf(png_ptr, info_ptr->exif, info_ptr->num_exif);
#endif
#ifdef PNG_WRITE_hIST_SUPPORTED
if ((info_ptr->valid & PNG_INFO_hIST) != 0)
png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
@ -383,7 +388,7 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr)
for (i = 0; i < info_ptr->num_text; i++)
{
png_debug2(2, "Writing trailer text chunk %d, type %d", i,
info_ptr->text[i].compression);
info_ptr->text[i].compression);
/* An internationalized chunk? */
if (info_ptr->text[i].compression > 0)
{
@ -432,6 +437,12 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr)
}
}
#endif
#ifdef PNG_WRITE_eXIf_SUPPORTED
if ((info_ptr->valid & PNG_INFO_eXIf) != 0)
png_write_eXIf(png_ptr, info_ptr->exif, info_ptr->num_exif);
#endif
#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
write_unknown_chunks(png_ptr, info_ptr, PNG_AFTER_IDAT);
#endif
@ -666,9 +677,9 @@ png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
{
png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1);
png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3);
png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5);
png_uint_32 s0 = (png_uint_32)(*(rp ) << 8) | *(rp + 1);
png_uint_32 s1 = (png_uint_32)(*(rp + 2) << 8) | *(rp + 3);
png_uint_32 s2 = (png_uint_32)(*(rp + 4) << 8) | *(rp + 5);
png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL);
png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
*(rp ) = (png_byte)(red >> 8);
@ -693,7 +704,7 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
return;
png_debug2(1, "in png_write_row (row %u, pass %d)",
png_ptr->row_number, png_ptr->pass);
png_ptr->row_number, png_ptr->pass);
/* Initialize transformations and other stuff if first time */
if (png_ptr->row_number == 0 && png_ptr->pass == 0)
@ -901,7 +912,7 @@ png_set_flush(png_structrp png_ptr, int nrows)
if (png_ptr == NULL)
return;
png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);
png_ptr->flush_dist = (nrows < 0 ? 0 : (png_uint_32)nrows);
}
/* Flush the current output buffers now */
@ -1007,8 +1018,8 @@ png_set_filter(png_structrp png_ptr, int method, int filters)
case 5:
case 6:
case 7: png_app_error(png_ptr, "Unknown row filter for method 0");
/* FALL THROUGH */
#endif /* WRITE_FILTER */
/* FALLTHROUGH */
case PNG_FILTER_VALUE_NONE:
png_ptr->do_filter = PNG_FILTER_NONE; break;
@ -1069,7 +1080,7 @@ png_set_filter(png_structrp png_ptr, int method, int filters)
* is not available so the filter can't be used. Just warn here.
*/
png_app_warning(png_ptr,
"png_set_filter: UP/AVG/PAETH cannot be added after start");
"png_set_filter: UP/AVG/PAETH cannot be added after start");
filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH);
}
@ -1095,13 +1106,13 @@ png_set_filter(png_structrp png_ptr, int method, int filters)
if (png_ptr->try_row == NULL)
png_ptr->try_row = png_voidcast(png_bytep,
png_malloc(png_ptr, buf_size));
png_malloc(png_ptr, buf_size));
if (num_filters > 1)
{
if (png_ptr->tst_row == NULL)
png_ptr->tst_row = png_voidcast(png_bytep,
png_malloc(png_ptr, buf_size));
png_malloc(png_ptr, buf_size));
}
}
png_ptr->do_filter = (png_byte)filters;
@ -1422,7 +1433,7 @@ png_write_png(png_structrp png_ptr, png_inforp info_ptr,
png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported");
#endif
/* Swap bits of 1, 2, 4 bit packed pixel formats */
/* Swap bits of 1-bit, 2-bit, 4-bit packed pixel formats */
if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0)
#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
png_set_packswap(png_ptr);
@ -1452,7 +1463,6 @@ png_write_png(png_structrp png_ptr, png_inforp info_ptr,
#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
# ifdef PNG_STDIO_SUPPORTED /* currently required for png_image_write_* */
/* Initialize the write structure - general purpose utility. */
static int
png_image_write_init(png_imagep image)
@ -1504,6 +1514,10 @@ typedef struct
png_const_voidp first_row;
ptrdiff_t row_bytes;
png_voidp local_row;
/* Byte count for memory writing */
png_bytep memory;
png_alloc_size_t memory_bytes; /* not used for STDIO */
png_alloc_size_t output_bytes; /* running total */
} png_image_write_control;
/* Write png_uint_16 input to a 16-bit PNG; the png_ptr has already been set to
@ -1522,7 +1536,8 @@ png_write_image_16bit(png_voidp argument)
display->first_row);
png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row);
png_uint_16p row_end;
const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;
const unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ?
3 : 1;
int aindex = 0;
png_uint_32 y = image->height;
@ -1536,9 +1551,9 @@ png_write_image_16bit(png_voidp argument)
++output_row;
}
else
aindex = channels;
aindex = (int)channels;
# else
aindex = channels;
aindex = (int)channels;
# endif
}
@ -1551,7 +1566,7 @@ png_write_image_16bit(png_voidp argument)
*/
row_end = output_row + image->width * (channels+1);
while (y-- > 0)
for (; y > 0; --y)
{
png_const_uint_16p in_ptr = input_row;
png_uint_16p out_ptr = output_row;
@ -1572,7 +1587,7 @@ png_write_image_16bit(png_voidp argument)
if (alpha > 0 && alpha < 65535)
reciprocal = ((0xffff<<15)+(alpha>>1))/alpha;
c = channels;
c = (int)channels;
do /* always at least one channel */
{
png_uint_16 component = *in_ptr++;
@ -1607,7 +1622,7 @@ png_write_image_16bit(png_voidp argument)
}
png_write_row(png_ptr, png_voidcast(png_const_bytep, display->local_row));
input_row += display->row_bytes/(sizeof (png_uint_16));
input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16));
}
return 1;
@ -1625,7 +1640,7 @@ png_write_image_16bit(png_voidp argument)
static png_byte
png_unpremultiply(png_uint_32 component, png_uint_32 alpha,
png_uint_32 reciprocal/*from the above macro*/)
png_uint_32 reciprocal/*from the above macro*/)
{
/* The following gives 1.0 for an alpha of 0, which is fine, otherwise if 0/0
* is represented as some other value there is more likely to be a
@ -1680,7 +1695,8 @@ png_write_image_8bit(png_voidp argument)
display->first_row);
png_bytep output_row = png_voidcast(png_bytep, display->local_row);
png_uint_32 y = image->height;
const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;
const unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ?
3 : 1;
if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0)
{
@ -1697,12 +1713,12 @@ png_write_image_8bit(png_voidp argument)
else
# endif
aindex = channels;
aindex = (int)channels;
/* Use row_end in place of a loop counter: */
row_end = output_row + image->width * (channels+1);
while (y-- > 0)
for (; y > 0; --y)
{
png_const_uint_16p in_ptr = input_row;
png_bytep out_ptr = output_row;
@ -1720,7 +1736,7 @@ png_write_image_8bit(png_voidp argument)
if (alphabyte > 0 && alphabyte < 255)
reciprocal = UNP_RECIPROCAL(alpha);
c = channels;
c = (int)channels;
do /* always at least one channel */
*out_ptr++ = png_unpremultiply(*in_ptr++, alpha, reciprocal);
while (--c > 0);
@ -1732,7 +1748,7 @@ png_write_image_8bit(png_voidp argument)
png_write_row(png_ptr, png_voidcast(png_const_bytep,
display->local_row));
input_row += display->row_bytes/(sizeof (png_uint_16));
input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16));
} /* while y */
}
@ -1743,7 +1759,7 @@ png_write_image_8bit(png_voidp argument)
*/
png_bytep row_end = output_row + image->width * channels;
while (y-- > 0)
for (; y > 0; --y)
{
png_const_uint_16p in_ptr = input_row;
png_bytep out_ptr = output_row;
@ -1757,7 +1773,7 @@ png_write_image_8bit(png_voidp argument)
}
png_write_row(png_ptr, output_row);
input_row += display->row_bytes/(sizeof (png_uint_16));
input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16));
}
}
@ -1774,7 +1790,7 @@ png_image_set_PLTE(png_image_write_control *display)
/* NOTE: the caller must check for cmap != NULL and entries != 0 */
const png_uint_32 format = image->format;
const int channels = PNG_IMAGE_SAMPLE_CHANNELS(format);
const unsigned int channels = PNG_IMAGE_SAMPLE_CHANNELS(format);
# if defined(PNG_FORMAT_BGR_SUPPORTED) &&\
defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED)
@ -1806,7 +1822,7 @@ png_image_set_PLTE(png_image_write_control *display)
{
png_const_uint_16p entry = png_voidcast(png_const_uint_16p, cmap);
entry += i * channels;
entry += (unsigned int)i * channels;
if ((channels & 1) != 0) /* no alpha */
{
@ -1845,16 +1861,16 @@ png_image_set_PLTE(png_image_write_control *display)
if (channels >= 3) /* RGB */
{
palette[i].blue = png_unpremultiply(entry[afirst + (2 ^ bgr)],
alpha, reciprocal);
alpha, reciprocal);
palette[i].green = png_unpremultiply(entry[afirst + 1], alpha,
reciprocal);
reciprocal);
palette[i].red = png_unpremultiply(entry[afirst + bgr], alpha,
reciprocal);
reciprocal);
}
else /* gray */
palette[i].blue = palette[i].red = palette[i].green =
png_unpremultiply(entry[afirst], alpha, reciprocal);
png_unpremultiply(entry[afirst], alpha, reciprocal);
}
}
@ -1862,7 +1878,7 @@ png_image_set_PLTE(png_image_write_control *display)
{
png_const_bytep entry = png_voidcast(png_const_bytep, cmap);
entry += i * channels;
entry += (unsigned int)i * channels;
switch (channels)
{
@ -1870,7 +1886,7 @@ png_image_set_PLTE(png_image_write_control *display)
tRNS[i] = entry[afirst ? 0 : 3];
if (tRNS[i] < 255)
num_trans = i+1;
/* FALL THROUGH */
/* FALLTHROUGH */
case 3:
palette[i].blue = entry[afirst + (2 ^ bgr)];
palette[i].green = entry[afirst + 1];
@ -1881,7 +1897,7 @@ png_image_set_PLTE(png_image_write_control *display)
tRNS[i] = entry[1 ^ afirst];
if (tRNS[i] < 255)
num_trans = i+1;
/* FALL THROUGH */
/* FALLTHROUGH */
case 1:
palette[i].blue = palette[i].red = palette[i].green =
entry[afirst];
@ -1901,20 +1917,20 @@ png_image_set_PLTE(png_image_write_control *display)
# endif
png_set_PLTE(image->opaque->png_ptr, image->opaque->info_ptr, palette,
entries);
entries);
if (num_trans > 0)
png_set_tRNS(image->opaque->png_ptr, image->opaque->info_ptr, tRNS,
num_trans, NULL);
num_trans, NULL);
image->colormap_entries = entries;
image->colormap_entries = (png_uint_32)entries;
}
static int
png_image_write_main(png_voidp argument)
{
png_image_write_control *display = png_voidcast(png_image_write_control*,
argument);
argument);
png_imagep image = display->image;
png_structrp png_ptr = image->opaque->png_ptr;
png_inforp info_ptr = image->opaque->info_ptr;
@ -1924,16 +1940,50 @@ png_image_write_main(png_voidp argument)
int colormap = (format & PNG_FORMAT_FLAG_COLORMAP);
int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */
int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA);
int write_16bit = linear && !colormap && (display->convert_to_8bit == 0);
int write_16bit = linear && (display->convert_to_8bit == 0);
# ifdef PNG_BENIGN_ERRORS_SUPPORTED
/* Make sure we error out on any bad situation */
png_set_benign_errors(png_ptr, 0/*error*/);
# endif
/* Default the 'row_stride' parameter if required. */
if (display->row_stride == 0)
display->row_stride = PNG_IMAGE_ROW_STRIDE(*image);
/* Default the 'row_stride' parameter if required, also check the row stride
* and total image size to ensure that they are within the system limits.
*/
{
const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format);
if (image->width <= 0x7fffffffU/channels) /* no overflow */
{
png_uint_32 check;
const png_uint_32 png_row_stride = image->width * channels;
if (display->row_stride == 0)
display->row_stride = (png_int_32)/*SAFE*/png_row_stride;
if (display->row_stride < 0)
check = (png_uint_32)(-display->row_stride);
else
check = (png_uint_32)display->row_stride;
if (check >= png_row_stride)
{
/* Now check for overflow of the image buffer calculation; this
* limits the whole image size to 32 bits for API compatibility with
* the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro.
*/
if (image->height > 0xffffffffU/png_row_stride)
png_error(image->opaque->png_ptr, "memory image too large");
}
else
png_error(image->opaque->png_ptr, "supplied row stride too small");
}
else
png_error(image->opaque->png_ptr, "image row stride too large");
}
/* Set the required transforms then write the rows in the correct order. */
if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0)
@ -1943,24 +1993,24 @@ png_image_write_main(png_voidp argument)
png_uint_32 entries = image->colormap_entries;
png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)),
PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)),
PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
png_image_set_PLTE(display);
}
else
png_error(image->opaque->png_ptr,
"no color-map for color-mapped image");
"no color-map for color-mapped image");
}
else
png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
write_16bit ? 16 : 8,
((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) +
((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0),
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
write_16bit ? 16 : 8,
((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) +
((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0),
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
/* Counter-intuitively the data transformations must be called *after*
* png_write_info, not before as in the read code, but the 'set' functions
@ -1975,11 +2025,11 @@ png_image_write_main(png_voidp argument)
if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0)
png_set_cHRM_fixed(png_ptr, info_ptr,
/* color x y */
/* white */ 31270, 32900,
/* red */ 64000, 33000,
/* green */ 30000, 60000,
/* blue */ 15000, 6000
/* color x y */
/* white */ 31270, 32900,
/* red */ 64000, 33000,
/* green */ 30000, 60000,
/* blue */ 15000, 6000
);
}
@ -1998,7 +2048,7 @@ png_image_write_main(png_voidp argument)
/* Now set up the data transformations (*after* the header is written),
* remove the handled transformations from the 'format' flags for checking.
*
* First check for a little endian system if writing 16 bit files.
* First check for a little endian system if writing 16-bit files.
*/
if (write_16bit != 0)
{
@ -2073,7 +2123,7 @@ png_image_write_main(png_voidp argument)
(colormap == 0 && display->convert_to_8bit != 0))
{
png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr,
png_get_rowbytes(png_ptr, info_ptr)));
png_get_rowbytes(png_ptr, info_ptr)));
int result;
display->local_row = row;
@ -2099,7 +2149,7 @@ png_image_write_main(png_voidp argument)
ptrdiff_t row_bytes = display->row_bytes;
png_uint_32 y = image->height;
while (y-- > 0)
for (; y > 0; --y)
{
png_write_row(png_ptr, row);
row += row_bytes;
@ -2110,14 +2160,130 @@ png_image_write_main(png_voidp argument)
return 1;
}
static void (PNGCBAPI
image_memory_write)(png_structp png_ptr, png_bytep/*const*/ data,
png_size_t size)
{
png_image_write_control *display = png_voidcast(png_image_write_control*,
png_ptr->io_ptr/*backdoor: png_get_io_ptr(png_ptr)*/);
const png_alloc_size_t ob = display->output_bytes;
/* Check for overflow; this should never happen: */
if (size <= ((png_alloc_size_t)-1) - ob)
{
/* I don't think libpng ever does this, but just in case: */
if (size > 0)
{
if (display->memory_bytes >= ob+size) /* writing */
memcpy(display->memory+ob, data, size);
/* Always update the size: */
display->output_bytes = ob+size;
}
}
else
png_error(png_ptr, "png_image_write_to_memory: PNG too big");
}
static void (PNGCBAPI
image_memory_flush)(png_structp png_ptr)
{
PNG_UNUSED(png_ptr)
}
static int
png_image_write_memory(png_voidp argument)
{
png_image_write_control *display = png_voidcast(png_image_write_control*,
argument);
/* The rest of the memory-specific init and write_main in an error protected
* environment. This case needs to use callbacks for the write operations
* since libpng has no built in support for writing to memory.
*/
png_set_write_fn(display->image->opaque->png_ptr, display/*io_ptr*/,
image_memory_write, image_memory_flush);
return png_image_write_main(display);
}
int PNGAPI
png_image_write_to_memory(png_imagep image, void *memory,
png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8bit,
const void *buffer, png_int_32 row_stride, const void *colormap)
{
/* Write the image to the given buffer, or count the bytes if it is NULL */
if (image != NULL && image->version == PNG_IMAGE_VERSION)
{
if (memory_bytes != NULL && buffer != NULL)
{
/* This is to give the caller an easier error detection in the NULL
* case and guard against uninitialized variable problems:
*/
if (memory == NULL)
*memory_bytes = 0;
if (png_image_write_init(image) != 0)
{
png_image_write_control display;
int result;
memset(&display, 0, (sizeof display));
display.image = image;
display.buffer = buffer;
display.row_stride = row_stride;
display.colormap = colormap;
display.convert_to_8bit = convert_to_8bit;
display.memory = png_voidcast(png_bytep, memory);
display.memory_bytes = *memory_bytes;
display.output_bytes = 0;
result = png_safe_execute(image, png_image_write_memory, &display);
png_image_free(image);
/* write_memory returns true even if we ran out of buffer. */
if (result)
{
/* On out-of-buffer this function returns '0' but still updates
* memory_bytes:
*/
if (memory != NULL && display.output_bytes > *memory_bytes)
result = 0;
*memory_bytes = display.output_bytes;
}
return result;
}
else
return 0;
}
else
return png_image_error(image,
"png_image_write_to_memory: invalid argument");
}
else if (image != NULL)
return png_image_error(image,
"png_image_write_to_memory: incorrect PNG_IMAGE_VERSION");
else
return 0;
}
#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
int PNGAPI
png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
const void *buffer, png_int_32 row_stride, const void *colormap)
const void *buffer, png_int_32 row_stride, const void *colormap)
{
/* Write the image to the given (FILE*). */
if (image != NULL && image->version == PNG_IMAGE_VERSION)
{
if (file != NULL)
if (file != NULL && buffer != NULL)
{
if (png_image_write_init(image) != 0)
{
@ -2148,12 +2314,12 @@ png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
else
return png_image_error(image,
"png_image_write_to_stdio: invalid argument");
"png_image_write_to_stdio: invalid argument");
}
else if (image != NULL)
return png_image_error(image,
"png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION");
"png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION");
else
return 0;
@ -2161,20 +2327,20 @@ png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
int PNGAPI
png_image_write_to_file(png_imagep image, const char *file_name,
int convert_to_8bit, const void *buffer, png_int_32 row_stride,
const void *colormap)
int convert_to_8bit, const void *buffer, png_int_32 row_stride,
const void *colormap)
{
/* Write the image to the named file. */
if (image != NULL && image->version == PNG_IMAGE_VERSION)
{
if (file_name != NULL)
if (file_name != NULL && buffer != NULL)
{
FILE *fp = fopen(file_name, "wb");
if (fp != NULL)
{
if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer,
row_stride, colormap) != 0)
row_stride, colormap) != 0)
{
int error; /* from fflush/fclose */
@ -2215,16 +2381,16 @@ png_image_write_to_file(png_imagep image, const char *file_name,
else
return png_image_error(image,
"png_image_write_to_file: invalid argument");
"png_image_write_to_file: invalid argument");
}
else if (image != NULL)
return png_image_error(image,
"png_image_write_to_file: incorrect PNG_IMAGE_VERSION");
"png_image_write_to_file: incorrect PNG_IMAGE_VERSION");
else
return 0;
}
# endif /* STDIO */
#endif /* SIMPLIFIED_WRITE_STDIO */
#endif /* SIMPLIFIED_WRITE */
#endif /* WRITE */

View File

@ -1,8 +1,8 @@
/* pngwtran.c - transforms the data in a row for PNG writers
*
* Last changed in libpng 1.6.18 [July 23, 2015]
* Copyright (c) 1998-2015 Glenn Randers-Pehrson
* Last changed in libpng 1.6.26 [October 20, 2016]
* Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
@ -177,7 +177,7 @@ png_do_shift(png_row_infop row_info, png_bytep row,
if (row_info->color_type != PNG_COLOR_TYPE_PALETTE)
{
int shift_start[4], shift_dec[4];
int channels = 0;
unsigned int channels = 0;
if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
{
@ -525,7 +525,7 @@ png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info)
#ifdef PNG_WRITE_FILLER_SUPPORTED
if ((png_ptr->transformations & PNG_FILLER) != 0)
png_do_strip_channel(row_info, png_ptr->row_buf + 1,
!(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
!(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
#endif
#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
@ -549,7 +549,7 @@ png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info)
#ifdef PNG_WRITE_SHIFT_SUPPORTED
if ((png_ptr->transformations & PNG_SHIFT) != 0)
png_do_shift(row_info, png_ptr->row_buf + 1,
&(png_ptr->shift));
&(png_ptr->shift));
#endif
#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED

View File

@ -1,8 +1,8 @@
/* pngwutil.c - utilities to write a PNG file
*
* Last changed in libpng 1.6.18 [July 23, 2015]
* Copyright (c) 1998-2015 Glenn Randers-Pehrson
* Last changed in libpng 1.6.32 [August 24, 2017]
* Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
@ -23,10 +23,10 @@
void PNGAPI
png_save_uint_32(png_bytep buf, png_uint_32 i)
{
buf[0] = (png_byte)(i >> 24);
buf[1] = (png_byte)(i >> 16);
buf[2] = (png_byte)(i >> 8);
buf[3] = (png_byte)(i );
buf[0] = (png_byte)((i >> 24) & 0xffU);
buf[1] = (png_byte)((i >> 16) & 0xffU);
buf[2] = (png_byte)((i >> 8) & 0xffU);
buf[3] = (png_byte)( i & 0xffU);
}
/* Place a 16-bit number into a buffer in PNG byte order.
@ -36,8 +36,8 @@ png_save_uint_32(png_bytep buf, png_uint_32 i)
void PNGAPI
png_save_uint_16(png_bytep buf, unsigned int i)
{
buf[0] = (png_byte)(i >> 8);
buf[1] = (png_byte)(i );
buf[0] = (png_byte)((i >> 8) & 0xffU);
buf[1] = (png_byte)( i & 0xffU);
}
#endif
@ -59,7 +59,7 @@ png_write_sig(png_structrp png_ptr)
/* Write the rest of the 8 byte signature */
png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
(png_size_t)(8 - png_ptr->sig_bytes));
(png_size_t)(8 - png_ptr->sig_bytes));
if (png_ptr->sig_bytes < 3)
png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
@ -174,12 +174,12 @@ png_write_chunk_end(png_structrp png_ptr)
*/
static void
png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name,
png_const_bytep data, png_size_t length)
png_const_bytep data, png_size_t length)
{
if (png_ptr == NULL)
return;
/* On 64 bit architectures 'length' may not fit in a png_uint_32. */
/* On 64-bit architectures 'length' may not fit in a png_uint_32. */
if (length > PNG_UINT_31_MAX)
png_error(png_ptr, "length exceeds PNG maximum");
@ -191,10 +191,10 @@ png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name,
/* This is the API that calls the internal function above. */
void PNGAPI
png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string,
png_const_bytep data, png_size_t length)
png_const_bytep data, png_size_t length)
{
png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data,
length);
length);
}
/* This is used below to find the size of an image to pass to png_deflate_claim,
@ -291,7 +291,7 @@ optimize_cmf(png_bytep data, png_alloc_size_t data_size)
/* Initialize the compressor for the appropriate type of compression. */
static int
png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
png_alloc_size_t data_size)
png_alloc_size_t data_size)
{
if (png_ptr->zowner != 0)
{
@ -408,7 +408,7 @@ png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
png_ptr->zstream.avail_out = 0;
/* Now initialize if required, setting the new parameters, otherwise just
* to a simple reset to the previous parameters.
* do a simple reset to the previous parameters.
*/
if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0)
ret = deflateReset(&png_ptr->zstream);
@ -416,7 +416,7 @@ png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
else
{
ret = deflateInit2(&png_ptr->zstream, level, method, windowBits,
memLevel, strategy);
memLevel, strategy);
if (ret == Z_OK)
png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
@ -477,7 +477,7 @@ typedef struct
static void
png_text_compress_init(compression_state *comp, png_const_bytep input,
png_alloc_size_t input_len)
png_alloc_size_t input_len)
{
comp->input = input;
comp->input_len = input_len;
@ -487,7 +487,7 @@ png_text_compress_init(compression_state *comp, png_const_bytep input,
/* Compress the data in the compression state input */
static int
png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name,
compression_state *comp, png_uint_32 prefix_len)
compression_state *comp, png_uint_32 prefix_len)
{
int ret;
@ -579,7 +579,7 @@ png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name,
/* Compress the data */
ret = deflate(&png_ptr->zstream,
input_len > 0 ? Z_NO_FLUSH : Z_FINISH);
input_len > 0 ? Z_NO_FLUSH : Z_FINISH);
/* Claw back input data that was not consumed (because avail_in is
* reset above every time round the loop).
@ -665,90 +665,6 @@ png_write_compressed_data_out(png_structrp png_ptr, compression_state *comp)
}
#endif /* WRITE_COMPRESSED_TEXT */
#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
* and if invalid, correct the keyword rather than discarding the entire
* chunk. The PNG 1.0 specification requires keywords 1-79 characters in
* length, forbids leading or trailing whitespace, multiple internal spaces,
* and the non-break space (0x80) from ISO 8859-1. Returns keyword length.
*
* The 'new_key' buffer must be 80 characters in size (for the keyword plus a
* trailing '\0'). If this routine returns 0 then there was no keyword, or a
* valid one could not be generated, and the caller must png_error.
*/
static png_uint_32
png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)
{
png_const_charp orig_key = key;
png_uint_32 key_len = 0;
int bad_character = 0;
int space = 1;
png_debug(1, "in png_check_keyword");
if (key == NULL)
{
*new_key = 0;
return 0;
}
while (*key && key_len < 79)
{
png_byte ch = (png_byte)*key++;
if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/))
*new_key++ = ch, ++key_len, space = 0;
else if (space == 0)
{
/* A space or an invalid character when one wasn't seen immediately
* before; output just a space.
*/
*new_key++ = 32, ++key_len, space = 1;
/* If the character was not a space then it is invalid. */
if (ch != 32)
bad_character = ch;
}
else if (bad_character == 0)
bad_character = ch; /* just skip it, record the first error */
}
if (key_len > 0 && space != 0) /* trailing space */
{
--key_len, --new_key;
if (bad_character == 0)
bad_character = 32;
}
/* Terminate the keyword */
*new_key = 0;
if (key_len == 0)
return 0;
#ifdef PNG_WARNINGS_SUPPORTED
/* Try to only output one warning per keyword: */
if (*key != 0) /* keyword too long */
png_warning(png_ptr, "keyword truncated");
else if (bad_character != 0)
{
PNG_WARNING_PARAMETERS(p)
png_warning_parameter(p, 1, orig_key);
png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character);
png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'");
}
#endif /* WARNINGS */
return key_len;
}
#endif /* WRITE_TEXT || WRITE_pCAL || WRITE_iCCP || WRITE_sPLT */
/* Write the IHDR chunk, and update the png_struct with the necessary
* information. Note that the rest of this code depends upon this
* information being correct.
@ -759,6 +675,7 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
int interlace_type)
{
png_byte buf[13]; /* Buffer to store the IHDR info */
int is_invalid_depth;
png_debug(1, "in png_write_IHDR");
@ -784,11 +701,11 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
break;
case PNG_COLOR_TYPE_RGB:
is_invalid_depth = (bit_depth != 8);
#ifdef PNG_WRITE_16BIT_SUPPORTED
if (bit_depth != 8 && bit_depth != 16)
#else
if (bit_depth != 8)
is_invalid_depth = (is_invalid_depth && bit_depth != 16);
#endif
if (is_invalid_depth)
png_error(png_ptr, "Invalid bit depth for RGB image");
png_ptr->channels = 3;
@ -810,18 +727,22 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
break;
case PNG_COLOR_TYPE_GRAY_ALPHA:
if (bit_depth != 8 && bit_depth != 16)
is_invalid_depth = (bit_depth != 8);
#ifdef PNG_WRITE_16BIT_SUPPORTED
is_invalid_depth = (is_invalid_depth && bit_depth != 16);
#endif
if (is_invalid_depth)
png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
png_ptr->channels = 2;
break;
case PNG_COLOR_TYPE_RGB_ALPHA:
is_invalid_depth = (bit_depth != 8);
#ifdef PNG_WRITE_16BIT_SUPPORTED
if (bit_depth != 8 && bit_depth != 16)
#else
if (bit_depth != 8)
is_invalid_depth = (is_invalid_depth && bit_depth != 16);
#endif
if (is_invalid_depth)
png_error(png_ptr, "Invalid bit depth for RGBA image");
png_ptr->channels = 4;
@ -922,17 +843,20 @@ void /* PRIVATE */
png_write_PLTE(png_structrp png_ptr, png_const_colorp palette,
png_uint_32 num_pal)
{
png_uint_32 i;
png_uint_32 max_palette_length, i;
png_const_colorp pal_ptr;
png_byte buf[3];
png_debug(1, "in png_write_PLTE");
max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
(1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;
if ((
#ifdef PNG_MNG_FEATURES_SUPPORTED
(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 &&
#endif
num_pal == 0) || num_pal > 256)
num_pal == 0) || num_pal > max_palette_length)
{
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
{
@ -1006,7 +930,7 @@ png_write_PLTE(png_structrp png_ptr, png_const_colorp palette,
*/
void /* PRIVATE */
png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
png_alloc_size_t input_len, int flush)
png_alloc_size_t input_len, int flush)
{
if (png_ptr->zowner != png_IDAT)
{
@ -1018,7 +942,7 @@ png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
if (png_ptr->zbuffer_list == NULL)
{
png_ptr->zbuffer_list = png_voidcast(png_compression_bufferp,
png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));
png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));
png_ptr->zbuffer_list->next = NULL;
}
@ -1079,7 +1003,8 @@ png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
optimize_cmf(data, png_image_size(png_ptr));
#endif
png_write_complete_chunk(png_ptr, png_IDAT, data, size);
if (size > 0)
png_write_complete_chunk(png_ptr, png_IDAT, data, size);
png_ptr->mode |= PNG_HAVE_IDAT;
png_ptr->zstream.next_out = data;
@ -1125,7 +1050,8 @@ png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
optimize_cmf(data, png_image_size(png_ptr));
#endif
png_write_complete_chunk(png_ptr, png_IDAT, data, size);
if (size > 0)
png_write_complete_chunk(png_ptr, png_IDAT, data, size);
png_ptr->zstream.avail_out = 0;
png_ptr->zstream.next_out = NULL;
png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT;
@ -1257,7 +1183,7 @@ png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette)
png_byte new_name[80];
png_byte entrybuf[10];
png_size_t entry_size = (spalette->depth == 8 ? 6 : 10);
png_size_t palette_size = entry_size * spalette->nentries;
png_size_t palette_size = entry_size * (png_size_t)spalette->nentries;
png_sPLT_entryp ep;
#ifndef PNG_POINTER_INDEXING_SUPPORTED
int i;
@ -1439,12 +1365,12 @@ png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha,
/* Write the chunk out as it is */
png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha,
(png_size_t)num_trans);
(png_size_t)num_trans);
}
else if (color_type == PNG_COLOR_TYPE_GRAY)
{
/* One 16 bit value */
/* One 16-bit value */
if (tran->gray >= (1 << png_ptr->bit_depth))
{
png_app_warning(png_ptr,
@ -1459,7 +1385,7 @@ png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha,
else if (color_type == PNG_COLOR_TYPE_RGB)
{
/* Three 16 bit values */
/* Three 16-bit values */
png_save_uint_16(buf, tran->red);
png_save_uint_16(buf + 2, tran->green);
png_save_uint_16(buf + 4, tran->blue);
@ -1470,7 +1396,7 @@ png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha,
#endif
{
png_app_warning(png_ptr,
"Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
"Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
return;
}
@ -1522,7 +1448,8 @@ png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type)
#endif
{
png_warning(png_ptr,
"Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8");
"Ignoring attempt to write 16-bit bKGD chunk "
"when bit_depth is 8");
return;
}
@ -1546,6 +1473,28 @@ png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type)
}
#endif
#ifdef PNG_WRITE_eXIf_SUPPORTED
/* Write the Exif data */
void /* PRIVATE */
png_write_eXIf(png_structrp png_ptr, png_bytep exif, int num_exif)
{
int i;
png_byte buf[1];
png_debug(1, "in png_write_eXIf");
png_write_chunk_header(png_ptr, png_eXIf, (png_uint_32)(num_exif));
for (i = 0; i < num_exif; i++)
{
buf[0] = exif[i];
png_write_chunk_data(png_ptr, buf, (png_size_t)1);
}
png_write_chunk_end(png_ptr);
}
#endif
#ifdef PNG_WRITE_hIST_SUPPORTED
/* Write the histogram */
void /* PRIVATE */
@ -1652,7 +1601,7 @@ png_write_zTXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,
/* Compute the compressed data; do it now for the length */
png_text_compress_init(&comp, (png_const_bytep)text,
text == NULL ? 0 : strlen(text));
text == NULL ? 0 : strlen(text));
if (png_text_compress(png_ptr, png_zTXt, &comp, key_len) != Z_OK)
png_error(png_ptr, png_ptr->zstream.msg);
@ -1823,7 +1772,7 @@ png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0,
total_len = purpose_len + units_len + 10;
params_len = (png_size_tp)png_malloc(png_ptr,
(png_alloc_size_t)(nparams * (sizeof (png_size_t))));
(png_alloc_size_t)((png_alloc_size_t)nparams * (sizeof (png_size_t))));
/* Find the length of each parameter, making sure we don't count the
* null terminator for the last parameter.
@ -2022,7 +1971,7 @@ png_write_start_row(png_structrp png_ptr)
*/
if ((filters & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) != 0)
png_ptr->prev_row = png_voidcast(png_bytep,
png_calloc(png_ptr, buf_size));
png_calloc(png_ptr, buf_size));
#endif /* WRITE_FILTER */
#ifdef PNG_WRITE_INTERLACING_SUPPORTED
@ -2325,7 +2274,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
*/
static void /* PRIVATE */
png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
png_size_t row_bytes);
png_size_t row_bytes);
#ifdef PNG_WRITE_FILTER_SUPPORTED
static png_size_t /* PRIVATE */
@ -2335,7 +2284,7 @@ png_setup_sub_row(png_structrp png_ptr, const png_uint_32 bpp,
png_bytep rp, dp, lp;
png_size_t i;
png_size_t sum = 0;
int v;
unsigned int v;
png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB;
@ -2343,14 +2292,22 @@ png_setup_sub_row(png_structrp png_ptr, const png_uint_32 bpp,
i++, rp++, dp++)
{
v = *dp = *rp;
#ifdef PNG_USE_ABS
sum += 128 - abs((int)v - 128);
#else
sum += (v < 128) ? v : 256 - v;
#endif
}
for (lp = png_ptr->row_buf + 1; i < row_bytes;
i++, rp++, lp++, dp++)
{
v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
#ifdef PNG_USE_ABS
sum += 128 - abs((int)v - 128);
#else
sum += (v < 128) ? v : 256 - v;
#endif
if (sum > lmins) /* We are already worse, don't continue. */
break;
@ -2359,6 +2316,28 @@ png_setup_sub_row(png_structrp png_ptr, const png_uint_32 bpp,
return (sum);
}
static void /* PRIVATE */
png_setup_sub_row_only(png_structrp png_ptr, const png_uint_32 bpp,
const png_size_t row_bytes)
{
png_bytep rp, dp, lp;
png_size_t i;
png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB;
for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1; i < bpp;
i++, rp++, dp++)
{
*dp = *rp;
}
for (lp = png_ptr->row_buf + 1; i < row_bytes;
i++, rp++, lp++, dp++)
{
*dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
}
}
static png_size_t /* PRIVATE */
png_setup_up_row(png_structrp png_ptr, const png_size_t row_bytes,
const png_size_t lmins)
@ -2366,7 +2345,7 @@ png_setup_up_row(png_structrp png_ptr, const png_size_t row_bytes,
png_bytep rp, dp, pp;
png_size_t i;
png_size_t sum = 0;
int v;
unsigned int v;
png_ptr->try_row[0] = PNG_FILTER_VALUE_UP;
@ -2375,7 +2354,11 @@ png_setup_up_row(png_structrp png_ptr, const png_size_t row_bytes,
i++, rp++, pp++, dp++)
{
v = *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
#ifdef PNG_USE_ABS
sum += 128 - abs((int)v - 128);
#else
sum += (v < 128) ? v : 256 - v;
#endif
if (sum > lmins) /* We are already worse, don't continue. */
break;
@ -2383,24 +2366,43 @@ png_setup_up_row(png_structrp png_ptr, const png_size_t row_bytes,
return (sum);
}
static void /* PRIVATE */
png_setup_up_row_only(png_structrp png_ptr, const png_size_t row_bytes)
{
png_bytep rp, dp, pp;
png_size_t i;
png_ptr->try_row[0] = PNG_FILTER_VALUE_UP;
for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
pp = png_ptr->prev_row + 1; i < row_bytes;
i++, rp++, pp++, dp++)
{
*dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
}
}
static png_size_t /* PRIVATE */
png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp,
const png_size_t row_bytes, const png_size_t lmins)
const png_size_t row_bytes, const png_size_t lmins)
{
png_bytep rp, dp, pp, lp;
png_uint_32 i;
png_size_t sum = 0;
int v;
unsigned int v;
png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG;
for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
pp = png_ptr->prev_row + 1; i < bpp; i++)
pp = png_ptr->prev_row + 1; i < bpp; i++)
{
v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
#ifdef PNG_USE_ABS
sum += 128 - abs((int)v - 128);
#else
sum += (v < 128) ? v : 256 - v;
#endif
}
for (lp = png_ptr->row_buf + 1; i < row_bytes; i++)
@ -2408,7 +2410,11 @@ png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp,
v = *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
& 0xff);
#ifdef PNG_USE_ABS
sum += 128 - abs((int)v - 128);
#else
sum += (v < 128) ? v : 256 - v;
#endif
if (sum > lmins) /* We are already worse, don't continue. */
break;
@ -2416,6 +2422,27 @@ png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp,
return (sum);
}
static void /* PRIVATE */
png_setup_avg_row_only(png_structrp png_ptr, const png_uint_32 bpp,
const png_size_t row_bytes)
{
png_bytep rp, dp, pp, lp;
png_uint_32 i;
png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG;
for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
pp = png_ptr->prev_row + 1; i < bpp; i++)
{
*dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
}
for (lp = png_ptr->row_buf + 1; i < row_bytes; i++)
{
*dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
& 0xff);
}
}
static png_size_t /* PRIVATE */
png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp,
@ -2424,7 +2451,7 @@ png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp,
png_bytep rp, dp, pp, cp, lp;
png_size_t i;
png_size_t sum = 0;
int v;
unsigned int v;
png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH;
@ -2433,7 +2460,11 @@ png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp,
{
v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
#ifdef PNG_USE_ABS
sum += 128 - abs((int)v - 128);
#else
sum += (v < 128) ? v : 256 - v;
#endif
}
for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes;
@ -2462,7 +2493,11 @@ png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp,
v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
#ifdef PNG_USE_ABS
sum += 128 - abs((int)v - 128);
#else
sum += (v < 128) ? v : 256 - v;
#endif
if (sum > lmins) /* We are already worse, don't continue. */
break;
@ -2470,6 +2505,48 @@ png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp,
return (sum);
}
static void /* PRIVATE */
png_setup_paeth_row_only(png_structrp png_ptr, const png_uint_32 bpp,
const png_size_t row_bytes)
{
png_bytep rp, dp, pp, cp, lp;
png_size_t i;
png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH;
for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
pp = png_ptr->prev_row + 1; i < bpp; i++)
{
*dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
}
for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes;
i++)
{
int a, b, c, pa, pb, pc, p;
b = *pp++;
c = *cp++;
a = *lp++;
p = b - c;
pc = a - c;
#ifdef PNG_USE_ABS
pa = abs(p);
pb = abs(pc);
pc = abs(p + pc);
#else
pa = p < 0 ? -p : p;
pb = pc < 0 ? -pc : pc;
pc = (p + pc) < 0 ? -(p + pc) : p + pc;
#endif
p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
*dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
}
}
#endif /* WRITE_FILTER */
void /* PRIVATE */
@ -2478,7 +2555,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
#ifndef PNG_WRITE_FILTER_SUPPORTED
png_write_filtered_row(png_ptr, png_ptr->row_buf, row_info->rowbytes+1);
#else
png_byte filter_to_do = png_ptr->do_filter;
unsigned int filter_to_do = png_ptr->do_filter;
png_bytep row_buf;
png_bytep best_row;
png_uint_32 bpp;
@ -2524,32 +2601,33 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
*/
best_row = png_ptr->row_buf;
if ((filter_to_do & PNG_FILTER_NONE) != 0 && filter_to_do != PNG_FILTER_NONE)
if (PNG_SIZE_MAX/128 <= row_bytes)
{
/* Overflow can occur in the calculation, just select the lowest set
* filter.
*/
filter_to_do &= 0U-filter_to_do;
}
else if ((filter_to_do & PNG_FILTER_NONE) != 0 &&
filter_to_do != PNG_FILTER_NONE)
{
/* Overflow not possible and multiple filters in the list, including the
* 'none' filter.
*/
png_bytep rp;
png_size_t sum = 0;
png_size_t i;
int v;
unsigned int v;
if (PNG_SIZE_MAX/128 <= row_bytes)
{
for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
{
/* Check for overflow */
if (sum > PNG_SIZE_MAX/128 - 256)
break;
v = *rp;
sum += (v < 128) ? v : 256 - v;
}
}
else /* Overflow is not possible */
{
for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
{
v = *rp;
#ifdef PNG_USE_ABS
sum += 128 - abs((int)v - 128);
#else
sum += (v < 128) ? v : 256 - v;
#endif
}
}
@ -2560,7 +2638,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
if (filter_to_do == PNG_FILTER_SUB)
/* It's the only filter so no testing is needed */
{
(void) png_setup_sub_row(png_ptr, bpp, row_bytes, mins);
png_setup_sub_row_only(png_ptr, bpp, row_bytes);
best_row = png_ptr->try_row;
}
@ -2569,7 +2647,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
png_size_t sum;
png_size_t lmins = mins;
sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins);
sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins);
if (sum < mins)
{
@ -2586,7 +2664,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
/* Up filter */
if (filter_to_do == PNG_FILTER_UP)
{
(void) png_setup_up_row(png_ptr, row_bytes, mins);
png_setup_up_row_only(png_ptr, row_bytes);
best_row = png_ptr->try_row;
}
@ -2595,7 +2673,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
png_size_t sum;
png_size_t lmins = mins;
sum = png_setup_up_row(png_ptr, row_bytes, lmins);
sum = png_setup_up_row(png_ptr, row_bytes, lmins);
if (sum < mins)
{
@ -2612,7 +2690,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
/* Avg filter */
if (filter_to_do == PNG_FILTER_AVG)
{
(void) png_setup_avg_row(png_ptr, bpp, row_bytes, mins);
png_setup_avg_row_only(png_ptr, bpp, row_bytes);
best_row = png_ptr->try_row;
}
@ -2636,9 +2714,9 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
}
/* Paeth filter */
if ((filter_to_do == PNG_FILTER_PAETH) != 0)
if (filter_to_do == PNG_FILTER_PAETH)
{
(void) png_setup_paeth_row(png_ptr, bpp, row_bytes, mins);
png_setup_paeth_row_only(png_ptr, bpp, row_bytes);
best_row = png_ptr->try_row;
}
@ -2651,7 +2729,6 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
if (sum < mins)
{
mins = sum;
best_row = png_ptr->try_row;
if (png_ptr->tst_row != NULL)
{
@ -2671,7 +2748,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
/* Do the actual writing of a previously filtered row. */
static void
png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
png_size_t full_row_length/*includes filter byte*/)
png_size_t full_row_length/*includes filter byte*/)
{
png_debug(1, "in png_write_filtered_row");

View File

@ -196,6 +196,52 @@
};
return mapping;
}
bool input_evdev_button_assigned(EvdevControllerMapping* mapping, int button)
{
return ((mapping->Btn_A == button)
|| (mapping->Btn_B == button)
|| (mapping->Btn_C == button)
|| (mapping->Btn_D == button)
|| (mapping->Btn_X == button)
|| (mapping->Btn_Y == button)
|| (mapping->Btn_Z == button)
|| (mapping->Btn_Start == button)
|| (mapping->Btn_Escape == button)
|| (mapping->Btn_DPad_Left == button)
|| (mapping->Btn_DPad_Right == button)
|| (mapping->Btn_DPad_Up == button)
|| (mapping->Btn_DPad_Down == button)
|| (mapping->Btn_DPad2_Left == button)
|| (mapping->Btn_DPad2_Right == button)
|| (mapping->Btn_DPad2_Up == button)
|| (mapping->Btn_DPad2_Down == button)
|| (mapping->Btn_Trigger_Left == button)
|| (mapping->Btn_Trigger_Right == button));
}
bool input_evdev_button_duplicate_button(EvdevControllerMapping* mapping1, EvdevControllerMapping* mapping2)
{
return (input_evdev_button_assigned(mapping1, mapping2->Btn_A)
|| input_evdev_button_assigned(mapping1, mapping2->Btn_B)
|| input_evdev_button_assigned(mapping1, mapping2->Btn_C)
|| input_evdev_button_assigned(mapping1, mapping2->Btn_D)
|| input_evdev_button_assigned(mapping1, mapping2->Btn_X)
|| input_evdev_button_assigned(mapping1, mapping2->Btn_Y)
|| input_evdev_button_assigned(mapping1, mapping2->Btn_Z)
|| input_evdev_button_assigned(mapping1, mapping2->Btn_Start)
|| input_evdev_button_assigned(mapping1, mapping2->Btn_Escape)
|| input_evdev_button_assigned(mapping1, mapping2->Btn_DPad_Left)
|| input_evdev_button_assigned(mapping1, mapping2->Btn_DPad_Right)
|| input_evdev_button_assigned(mapping1, mapping2->Btn_DPad_Up)
|| input_evdev_button_assigned(mapping1, mapping2->Btn_DPad_Down)
|| input_evdev_button_assigned(mapping1, mapping2->Btn_DPad2_Left)
|| input_evdev_button_assigned(mapping1, mapping2->Btn_DPad2_Right)
|| input_evdev_button_assigned(mapping1, mapping2->Btn_DPad2_Up)
|| input_evdev_button_assigned(mapping1, mapping2->Btn_DPad2_Down)
|| input_evdev_button_assigned(mapping1, mapping2->Btn_Trigger_Left)
|| input_evdev_button_assigned(mapping1, mapping2->Btn_Trigger_Right));
}
int input_evdev_init(EvdevController* controller, const char* device, const char* custom_mapping_fname = NULL)
{

View File

@ -74,3 +74,4 @@ struct EvdevController
extern int input_evdev_init(EvdevController* controller, const char* device, const char* mapping_fname);
extern bool input_evdev_handle(EvdevController* controller, u32 port);
extern void input_evdev_rumble(EvdevController* controller, u16 pow_strong, u16 pow_weak);
extern bool input_evdev_button_duplicate_button(EvdevControllerMapping* mapping1, EvdevControllerMapping* mapping2);

View File

@ -127,14 +127,6 @@ void SetupInput()
}
else
{
for (i = 0; i < port; i++)
{
if (evdev_device_id[port] == evdev_device_id[i])
{
die("You can't assign the same device to multiple ports!\n");
}
}
size_needed = snprintf(NULL, 0, EVDEV_DEVICE_STRING, evdev_device_id[port]) + 1;
evdev_device = (char*)malloc(size_needed);
sprintf(evdev_device, EVDEV_DEVICE_STRING, evdev_device_id[port]);
@ -150,6 +142,18 @@ void SetupInput()
input_evdev_init(&evdev_controllers[port], evdev_device, mapping);
free(evdev_device);
for (i = 0; i < port; i++)
{
if (evdev_device_id[port] == evdev_device_id[i])
{
// Multiple controllers with the same device, check for multiple button assignments
if (input_evdev_button_duplicate_button(evdev_controllers[i].mapping, evdev_controllers[port].mapping))
{
printf("WARNING: One or more button(s) of this device is also used in the configuration of input device %d (mapping: %s)\n", i, evdev_controllers[i].mapping->name);
}
}
}
}
}
#endif

View File

@ -188,7 +188,9 @@ void input_x11_init()
x11_keymap[KEY_F] = DC_AXIS_LT;
x11_keymap[KEY_V] = DC_AXIS_RT;
x11_keyboard_input = cfgLoadInt("input", "enable_x11_keyboard", 1);
x11_keyboard_input = (cfgLoadInt("input", "enable_x11_keyboard", 1) >= 1);
if (!x11_keyboard_input)
printf("X11 Keyboard input disabled by config.\n");
}
void x11_window_create()

View File

@ -259,6 +259,13 @@ void dc_term()
TermAudio();
}
#if defined(_ANDROID)
void dc_pause()
{
SaveRomFiles(get_writable_data_path("/data/"));
}
#endif
void dc_stop()
{
sh4_cpu.Stop();
@ -307,7 +314,6 @@ void LoadSettings()
#else
// TODO Expose this with JNI
settings.rend.Clipping = 1;
settings.rend.ModifierVolumes = 1;
#endif
settings.pvr.HashLogFile = cfgLoadStr("testing", "ta.HashLogFile", "");

View File

@ -1,5 +1,4 @@
**Please Note: This form is the minimum required information for submitting bugs.**
**Please Note: This form is the minimum required information for submitting bugs.**
**Removing this form may lead to your issue being closed until it is completed.**
| Platform | Branch | Hash | CIDL |
@ -28,6 +27,6 @@ You may leave this field blank if you have none.
**_Screenshots_**
![Issue Screenshot](https://github.com/adam-p/markdown-here/raw/master/src/common/images/icon48.png)
(Replace this line with any issue screenshots)
- [ ] Place an X in the box to confirm you have filled in this form

View File

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.system.id="GRADLE" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android-gradle" name="Android-Gradle">
<configuration>
<option name="GRADLE_PROJECT_PATH" value=":" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -1,354 +0,0 @@
package com.reicast.emulator;
/*
* File: CloudFragment.java
* Author: Luca D'Amico (Luca91)
* Last Edit: 11 May 2014
*
* Reference: http://forums.reicast.com/index.php?topic=160.msg422
*/
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;
import com.dropbox.client2.DropboxAPI;
import com.dropbox.client2.DropboxAPI.Entry;
import com.dropbox.client2.android.AndroidAuthSession;
import com.dropbox.client2.exception.DropboxException;
import com.dropbox.client2.session.AccessTokenPair;
import com.dropbox.client2.session.AppKeyPair;
import com.dropbox.client2.session.TokenPair;
import com.reicast.emulator.config.Config;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.ExecutionException;
public class CloudFragment extends Fragment {
Button uploadBtn;
Button downloadBtn;
AlertDialog.Builder confirmDialog = null;
boolean actionRequired=false;
public String task = "";
DropBoxClient client = null;
private String home_directory;
String[] vmus = {"vmu_save_A1.bin","vmu_save_A2.bin",
"vmu_save_B1.bin","vmu_save_B2.bin",
"vmu_save_C1.bin","vmu_save_C2.bin",
"vmu_save_D1.bin","vmu_save_D2.bin"};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.cloud_fragment, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
home_directory = mPrefs.getString(Config.pref_home,
Environment.getExternalStorageDirectory().getAbsolutePath());
buttonListener();
confirmDialog = new AlertDialog.Builder(getActivity());
setClient();
}
public void setClient(){
if(client==null)
client = new DropBoxClient(getActivity());
}
public void buttonListener() {
uploadBtn = (Button) getView().findViewById(R.id.uploadBtn);
uploadBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
confirmDialog.setMessage(R.string.uploadWarning);
confirmDialog.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setClient();
task = "Upload";
client.startLogin();
actionRequired = true;
}
});
confirmDialog.setNegativeButton(R.string.cancel, null);
confirmDialog.show();
}
});
downloadBtn = (Button) getView().findViewById(R.id.downloadBtn);
downloadBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
confirmDialog.setMessage(R.string.downloadWarning);
confirmDialog.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setClient();
task = "Download";
client.startLogin();
actionRequired = true;
}
});
confirmDialog.setNegativeButton(R.string.cancel, null);
confirmDialog.show();
}
});
}
@Override
public void onResume(){
super.onResume();
if (client.mDBApi != null) {
if (client.mDBApi.getSession().authenticationSuccessful()) {
try {
client.mDBApi.getSession().finishAuthentication();
TokenPair tokens = client.mDBApi.getSession(). getAccessTokenPair();
if(tokens == null)
Toast.makeText(getActivity(), "Failed to save session token!", Toast.LENGTH_SHORT).show();
else
client.storeKeys(tokens.key, tokens.secret);
} catch (IllegalStateException e) {
Log.i("Dropbox", "Error authenticating", e);
}
}
if(actionRequired){
for(int k=0;k<vmus.length;k++){
String result = "";
try {
String vmuPath = home_directory+"/"+vmus[k];
File vmu = new File(vmuPath);
if(vmu.exists() || task.equals("Download") ){
result = new netOperation(client, home_directory).execute(
task,vmuPath,vmus[k]).get();
}
else{
result = "Ok"; // The result is still ok, because the vmu bin doesn't exist ;)
Toast.makeText(getActivity(), vmus[k]+ " doesn't exist, skipping it!",
Toast.LENGTH_SHORT).show();
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
if(result.equals("Ok"))
Toast.makeText(getActivity(), "Task Completed!", Toast.LENGTH_SHORT).show();
else
Toast.makeText(getActivity(), "Task Failed!", Toast.LENGTH_SHORT).show();
}
}
actionRequired = false;
}
}
}
class DropBoxClient {
Context context;
final static private String APP_KEY = "7d7tw1t57sbzrj5";
final static private String APP_SECRET = "5xxqa2uctousyi2";
public DropboxAPI<AndroidAuthSession> mDBApi;
AndroidAuthSession session;
public DropBoxClient(Context context){
this.context = context;
session = buildSession();
mDBApi = new DropboxAPI<AndroidAuthSession>(session);
}
public void startLogin(){
mDBApi.getSession().startOAuth2Authentication(context);
}
public String[] getKeys() {
SharedPreferences prefs = context.getSharedPreferences("ReicastVMUUploader", 0);
String key = prefs.getString("DBoxKey", null);
String secret = prefs.getString("DBoxSecret", null);
if (key != null && secret != null) {
String[] ret = new String[2];
ret[0] = key;
ret[1] = secret;
return ret;
} else {
return null;
}
}
public void storeKeys(String key, String secret) {
SharedPreferences prefs = context.getSharedPreferences("ReicastVMUUploader", 0);
Editor edit = prefs.edit();
edit.putString("DBoxKey", key);
edit.putString("DBoxSecret", secret);
edit.commit();
}
private AndroidAuthSession buildSession() {
AppKeyPair appKeyPair = new AppKeyPair(APP_KEY, APP_SECRET);
AndroidAuthSession session;
String[] stored = getKeys();
if (stored != null) {
AccessTokenPair accessToken = new AccessTokenPair(stored[0], stored[1]);
session = new AndroidAuthSession(appKeyPair, accessToken);
} else {
session = new AndroidAuthSession(appKeyPair);
}
return session;
}
}
class netOperation extends AsyncTask<String, Void, String> {
DropBoxClient client = null;
private String home_directory;
public netOperation(DropBoxClient client, String home_directory){
this.client = client;
this.home_directory = home_directory;
}
public boolean uploadFile(String filePath, String fileName) {
File file = new File(filePath);
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
DropboxAPI.Entry response = null;
try {
response = client.mDBApi.putFileOverwrite("/"+fileName, inputStream, file.length(), null);
} catch (DropboxException e) {
e.printStackTrace();
}
Log.i("FileInfos", "The uploaded file's rev is: "+ response);
return true;
}
public boolean downloadFile(String filePath, String fileName) {
DropboxAPI.DropboxFileInfo info = null;
try {
Entry remoteFile = client.mDBApi.metadata("/"+fileName, 1, null, false, null);
if((remoteFile.rev != null) && (remoteFile.bytes > 0)){ // Avoid to download 0 bytes vmus!
File file = new File(filePath);
if(file.exists())
createBackupOfVmu(fileName);
FileOutputStream out = null;
try {
out = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
info = client.mDBApi.getFile("/"+fileName,null,out,null);
}
} catch (DropboxException e) {
e.printStackTrace();
}
Log.i("FileInfos", "The downloaded file's rev is: "+ info);
return true;
}
@Override
protected void onPostExecute(String result) {
}
@Override
protected String doInBackground(String... strings) {
if(strings[0].equals("Upload")){
if(uploadFile(strings[1],strings[2]))
return "Ok";
else
return "No";
}
else if(strings[0].equals("Download")){
if(downloadFile(strings[1],strings[2]))
return "Ok";
else
return "No";
}
else
return "Unknown";
}
@Override
protected void onPreExecute() {}
@Override
protected void onProgressUpdate(Void... values) {}
void createBackupOfVmu(String vmuName){
File backupDir = new File(home_directory+"/VmuBackups/");
if(!backupDir.exists()) {
backupDir.mkdirs();
}
File source = new File(home_directory+"/"+vmuName);
File destination = new File(home_directory+"/VmuBackups/"+vmuName);
if(!destination.exists()) {
try {
destination.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
InputStream in = new FileInputStream(source);
OutputStream out = new FileOutputStream(destination);
byte[] buffer = new byte[1024];
int length;
while ((length = in.read(buffer)) > 0){
out.write(buffer, 0, length);
}
in.close();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -1,571 +0,0 @@
package com.reicast.emulator;
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Gravity;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.widget.PopupWindow;
import com.reicast.emulator.config.Config;
import com.reicast.emulator.emu.GL2JNIView;
import com.reicast.emulator.emu.JNIdc;
import com.reicast.emulator.emu.OnScreenMenu;
import com.reicast.emulator.emu.OnScreenMenu.FpsPopup;
import com.reicast.emulator.emu.OnScreenMenu.MainPopup;
import com.reicast.emulator.emu.OnScreenMenu.VmuPopup;
import com.reicast.emulator.periph.Gamepad;
import com.reicast.emulator.periph.MOGAInput;
import com.reicast.emulator.periph.SipEmulator;
import java.util.Arrays;
import java.util.HashMap;
import tv.ouya.console.api.OuyaController;
public class GL2JNIActivity extends Activity {
public GL2JNIView mView;
OnScreenMenu menu;
public MainPopup popUp;
VmuPopup vmuPop;
FpsPopup fpsPop;
MOGAInput moga = new MOGAInput();
private SharedPreferences prefs;
private Gamepad pad = new Gamepad();
public static byte[] syms;
@Override
protected void onCreate(Bundle icicle) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
prefs = PreferenceManager.getDefaultSharedPreferences(this);
if (prefs.getInt(Config.pref_rendertype, 2) == 2) {
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
}
Emulator app = (Emulator)getApplicationContext();
app.getConfigurationPrefs(prefs);
menu = new OnScreenMenu(GL2JNIActivity.this, prefs);
pad.isOuyaOrTV = pad.IsOuyaOrTV(GL2JNIActivity.this);
// pad.isNvidiaShield = pad.IsNvidiaShield();
/*
* try { //int rID =
* getResources().getIdentifier("fortyonepost.com.lfas:raw/syms.map",
* null, null); //get the file as a stream InputStream is =
* getResources().openRawResource(R.raw.syms);
*
* syms = new byte[(int) is.available()]; is.read(syms); is.close(); }
* catch (IOException e) { e.getMessage(); e.printStackTrace(); }
*/
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
pad.compat[0] = true;
pad.compat[1] = true;
pad.compat[2] = true;
pad.compat[3] = true;
}
String fileName = null;
// Call parent onCreate()
super.onCreate(icicle);
OuyaController.init(this);
// Populate device descriptor-to-player-map from preferences
pad.deviceDescriptor_PlayerNum.put(
prefs.getString(Gamepad.pref_player1, null), 0);
pad.deviceDescriptor_PlayerNum.put(
prefs.getString(Gamepad.pref_player2, null), 1);
pad.deviceDescriptor_PlayerNum.put(
prefs.getString(Gamepad.pref_player3, null), 2);
pad.deviceDescriptor_PlayerNum.put(
prefs.getString(Gamepad.pref_player4, null), 3);
pad.deviceDescriptor_PlayerNum.remove(null);
moga.onCreate(this, pad);
moga.mListener.setPlayerNum(1);
boolean controllerTwoConnected = false;
boolean controllerThreeConnected = false;
boolean controllerFourConnected = false;
for (HashMap.Entry<String, Integer> e : pad.deviceDescriptor_PlayerNum.entrySet()) {
String descriptor = e.getKey();
Integer playerNum = e.getValue();
switch (playerNum) {
case 1:
if (descriptor != null)
controllerTwoConnected = true;
break;
case 2:
if (descriptor != null)
controllerThreeConnected = true;
break;
case 3:
if (descriptor != null)
controllerFourConnected = true;
break;
}
}
JNIdc.initControllers(new boolean[] { controllerTwoConnected,
controllerThreeConnected, controllerFourConnected });
int joys[] = InputDevice.getDeviceIds();
for (int joy: joys) {
String descriptor = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
descriptor = InputDevice.getDevice(joy).getDescriptor();
} else {
descriptor = InputDevice.getDevice(joy).getName();
}
Log.d("reicast", "InputDevice ID: " + joy);
Log.d("reicast",
"InputDevice Name: "
+ InputDevice.getDevice(joy).getName());
Log.d("reicast", "InputDevice Descriptor: " + descriptor);
pad.deviceId_deviceDescriptor.put(joy, descriptor);
}
for (int joy :joys) {
Integer playerNum = pad.deviceDescriptor_PlayerNum
.get(pad.deviceId_deviceDescriptor.get(joy));
if (playerNum != null) {
String id = pad.portId[playerNum];
pad.custom[playerNum] = prefs.getBoolean(Gamepad.pref_js_modified + id, false);
pad.compat[playerNum] = prefs.getBoolean(Gamepad.pref_js_compat + id, false);
pad.joystick[playerNum] = prefs.getBoolean(Gamepad.pref_js_merged + id, false);
if (InputDevice.getDevice(joy).getName()
.contains(Gamepad.controllers_gamekey)) {
if (pad.custom[playerNum]) {
pad.setCustomMapping(id, playerNum, prefs);
} else {
pad.map[playerNum] = pad.getConsoleController();
}
} else if (!pad.compat[playerNum]) {
if (pad.custom[playerNum]) {
pad.setCustomMapping(id, playerNum, prefs);
} else if (InputDevice.getDevice(joy).getName()
.equals(Gamepad.controllers_sony)) {
pad.map[playerNum] = pad.getConsoleController();
} else if (InputDevice.getDevice(joy).getName()
.equals(Gamepad.controllers_xbox)) {
pad.map[playerNum] = pad.getConsoleController();
} else if (InputDevice.getDevice(joy).getName()
.contains(Gamepad.controllers_shield)) {
pad.map[playerNum] = pad.getConsoleController();
} else if (!pad.isActiveMoga[playerNum]) { // Ouya controller
pad.map[playerNum] = pad.getOUYAController();
}
} else {
pad.getCompatibilityMap(playerNum, id, prefs);
}
pad.initJoyStickLayout(playerNum);
} else {
pad.runCompatibilityMode(joy, prefs);
}
}
if (joys.length == 0) {
pad.fullCompatibilityMode(prefs);
}
app.loadConfigurationPrefs();
// When viewing a resource, pass its URI to the native code for opening
if (getIntent().getAction().equals("com.reicast.EMULATOR"))
fileName = Uri.decode(getIntent().getData().toString());
// Create the actual GLES view
mView = new GL2JNIView(GL2JNIActivity.this, fileName, false,
prefs.getInt(Config.pref_renderdepth, 24), 8, false);
setContentView(mView);
//setup mic
boolean micPluggedIn = prefs.getBoolean(Config.pref_mic, false);
if(micPluggedIn){
SipEmulator sip = new SipEmulator();
sip.startRecording();
JNIdc.setupMic(sip);
}
popUp = menu.new MainPopup(this);
vmuPop = menu.new VmuPopup(this);
if(prefs.getBoolean(Config.pref_vmu, false)){
//kind of a hack - if the user last had the vmu on screen
//inverse it and then "toggle"
prefs.edit().putBoolean(Config.pref_vmu, false).apply();
//can only display a popup after onCreate
mView.post(new Runnable() {
public void run() {
toggleVmu();
}
});
}
JNIdc.setupVmu(menu.getVmu());
if (prefs.getBoolean(Config.pref_showfps, false)) {
fpsPop = menu.new FpsPopup(this);
mView.setFpsDisplay(fpsPop);
mView.post(new Runnable() {
public void run() {
displayFPS();
}
});
}
}
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
Integer playerNum = Arrays.asList(pad.name).indexOf(event.getDeviceId());
if (playerNum == -1) {
playerNum = pad.deviceDescriptor_PlayerNum
.get(pad.deviceId_deviceDescriptor.get(event.getDeviceId()));
} else {
playerNum = -1;
}
if (playerNum == null || playerNum == -1)
return false;
if (!pad.compat[playerNum]) {
// Joystick
if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
// do other things with joystick
float LS_X = event.getAxisValue(OuyaController.AXIS_LS_X);
float LS_Y = event.getAxisValue(OuyaController.AXIS_LS_Y);
float RS_X = event.getAxisValue(OuyaController.AXIS_RS_X);
float RS_Y = event.getAxisValue(OuyaController.AXIS_RS_Y);
float L2 = event.getAxisValue(OuyaController.AXIS_L2);
float R2 = event.getAxisValue(OuyaController.AXIS_R2);
if (!pad.joystick[playerNum]) {
pad.previousLS_X[playerNum] = pad.globalLS_X[playerNum];
pad.previousLS_Y[playerNum] = pad.globalLS_Y[playerNum];
pad.globalLS_X[playerNum] = LS_X;
pad.globalLS_Y[playerNum] = LS_Y;
}
GL2JNIView.jx[playerNum] = (int) (LS_X * 126);
GL2JNIView.jy[playerNum] = (int) (LS_Y * 126);
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
if (prefs.getBoolean(Gamepad.pref_js_rbuttons + pad.portId[playerNum], true)) {
if (RS_Y > 0.25) {
handle_key(playerNum, pad.map[playerNum][0]/* A */, true);
pad.wasKeyStick[playerNum] = true;
} else if (RS_Y < 0.25) {
handle_key(playerNum, pad.map[playerNum][1]/* B */, true);
pad.wasKeyStick[playerNum] = true;
} else if (pad.wasKeyStick[playerNum]){
handle_key(playerNum, pad.map[playerNum][0], false);
handle_key(playerNum, pad.map[playerNum][1], false);
pad.wasKeyStick[playerNum] = false;
}
} else {
if (RS_Y > 0.25) {
GL2JNIView.rt[playerNum] = (int) (RS_Y * 255);
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
} else if (RS_Y < 0.25) {
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
GL2JNIView.lt[playerNum] = (int) (-(RS_Y) * 255);
}
}
}
}
mView.pushInput();
// Only handle Left Stick on an Xbox 360 controller if there was
// some actual motion on the stick,
// so otherwise the event can be handled as a DPAD event
return (pad.joystick[playerNum] || (!(pad.globalLS_X[playerNum] == pad.previousLS_X[playerNum])
|| !(pad.globalLS_Y[playerNum] == pad.previousLS_Y[playerNum])))
&& (!(pad.previousLS_X[playerNum] == 0.0f) || !(pad.previousLS_Y[playerNum] == 0.0f));
}
public boolean motionEventHandler(Integer playerNum, com.bda.controller.MotionEvent event) {
if (playerNum == null || playerNum == -1)
return false;
if (!pad.compat[playerNum]) {
// do other things with joystick
float LS_X = event.getAxisValue(OuyaController.AXIS_LS_X);
float LS_Y = event.getAxisValue(OuyaController.AXIS_LS_Y);
float RS_X = event.getAxisValue(OuyaController.AXIS_RS_X);
float RS_Y = event.getAxisValue(OuyaController.AXIS_RS_Y);
float L2 = event.getAxisValue(OuyaController.AXIS_L2);
float R2 = event.getAxisValue(OuyaController.AXIS_R2);
if (!pad.joystick[playerNum]) {
pad.previousLS_X[playerNum] = pad.globalLS_X[playerNum];
pad.previousLS_Y[playerNum] = pad.globalLS_Y[playerNum];
pad.globalLS_X[playerNum] = LS_X;
pad.globalLS_Y[playerNum] = LS_Y;
}
GL2JNIView.jx[playerNum] = (int) (LS_X * 126);
GL2JNIView.jy[playerNum] = (int) (LS_Y * 126);
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
if (prefs.getBoolean(Gamepad.pref_js_rbuttons + pad.portId[playerNum], true)) {
if (RS_Y > 0.25) {
handle_key(playerNum, pad.map[playerNum][0]/* A */, true);
pad.wasKeyStick[playerNum] = true;
} else if (RS_Y < 0.25) {
handle_key(playerNum, pad.map[playerNum][1]/* B */, true);
pad.wasKeyStick[playerNum] = true;
} else if (pad.wasKeyStick[playerNum]){
handle_key(playerNum, pad.map[playerNum][0], false);
handle_key(playerNum, pad.map[playerNum][1], false);
pad.wasKeyStick[playerNum] = false;
}
} else {
if (RS_Y > 0.25) {
GL2JNIView.rt[playerNum] = (int) (RS_Y * 255);
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
} else if (RS_Y < 0.25) {
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
GL2JNIView.lt[playerNum] = (int) (-(RS_Y) * 255);
}
}
}
mView.pushInput();
// Only handle Left Stick on an Xbox 360 controller if there was
// some actual motion on the stick,
// so otherwise the event can be handled as a DPAD event
return (pad.joystick[playerNum] || (!(pad.globalLS_X[playerNum] == pad.previousLS_X[playerNum])
|| !(pad.globalLS_Y[playerNum] == pad.previousLS_Y[playerNum])))
&& (!(pad.previousLS_X[playerNum] == 0.0f) || !(pad.previousLS_Y[playerNum] == 0.0f));
}
public boolean simulatedTouchEvent(int playerNum, float L2, float R2) {
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
mView.pushInput();
return true;
}
public boolean handle_key(Integer playerNum, int kc, boolean down) {
if (playerNum == null || playerNum == -1)
return false;
if (kc == pad.getSelectButtonCode()) {
return false;
}
boolean rav = false;
for (int i = 0; i < pad.map[playerNum].length; i += 2) {
if (pad.map[playerNum][i + 0] == kc) {
if (down)
GL2JNIView.kcode_raw[playerNum] &= ~pad.map[playerNum][i + 1];
else
GL2JNIView.kcode_raw[playerNum] |= pad.map[playerNum][i + 1];
rav = true;
break;
}
}
mView.pushInput();
return rav;
}
public void displayPopUp(PopupWindow popUp) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
popUp.showAtLocation(mView, Gravity.BOTTOM, 0, 60);
} else {
popUp.showAtLocation(mView, Gravity.BOTTOM, 0, 0);
}
popUp.update(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
}
public void displayDebug(PopupWindow popUpDebug) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
popUpDebug.showAtLocation(mView, Gravity.BOTTOM, 0, 60);
} else {
popUpDebug.showAtLocation(mView, Gravity.BOTTOM, 0, 0);
}
popUpDebug.update(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
}
public void displayFPS() {
fpsPop.showAtLocation(mView, Gravity.TOP | Gravity.LEFT, 20, 20);
fpsPop.update(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}
public void toggleVmu() {
boolean showFloating = !prefs.getBoolean(Config.pref_vmu, false);
if (showFloating) {
if (popUp.isShowing()) {
popUp.dismiss();
}
//remove from popup menu
popUp.hideVmu();
//add to floating window
vmuPop.showVmu();
vmuPop.showAtLocation(mView, Gravity.TOP | Gravity.RIGHT, 4, 4);
vmuPop.update(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
} else {
vmuPop.dismiss();
//remove from floating window
vmuPop.hideVmu();
//add back to popup menu
popUp.showVmu();
}
prefs.edit().putBoolean(Config.pref_vmu, showFloating).apply();
}
public void displayConfig(PopupWindow popUpConfig) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
popUpConfig.showAtLocation(mView, Gravity.BOTTOM, 0, 60);
} else {
popUpConfig.showAtLocation(mView, Gravity.BOTTOM, 0, 0);
}
popUpConfig.update(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
}
public boolean onKeyUp(int keyCode, KeyEvent event) {
Integer playerNum = Arrays.asList(pad.name).indexOf(event.getDeviceId());
if (playerNum == -1) {
playerNum = pad.deviceDescriptor_PlayerNum
.get(pad.deviceId_deviceDescriptor.get(event.getDeviceId()));
} else {
playerNum = -1;
}
if (playerNum != null && playerNum != -1) {
if (pad.compat[playerNum] || pad.custom[playerNum]) {
String id = pad.portId[playerNum];
if (keyCode == prefs.getInt(Gamepad.pref_button_l + id,
KeyEvent.KEYCODE_BUTTON_L1)
|| keyCode == prefs.getInt(Gamepad.pref_button_r + id,
KeyEvent.KEYCODE_BUTTON_R1)) {
return simulatedTouchEvent(playerNum, 0.0f, 0.0f);
}
}
}
return handle_key(playerNum, keyCode, false)
|| super.onKeyUp(keyCode, event);
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
Integer playerNum = Arrays.asList(pad.name).indexOf(event.getDeviceId());
if (playerNum == -1) {
playerNum = pad.deviceDescriptor_PlayerNum
.get(pad.deviceId_deviceDescriptor.get(event.getDeviceId()));
} else {
playerNum = -1;
}
if (playerNum != null && playerNum != -1) {
if (pad.compat[playerNum] || pad.custom[playerNum]) {
String id = pad.portId[playerNum];
if (keyCode == prefs.getInt(Gamepad.pref_button_l + id, KeyEvent.KEYCODE_BUTTON_L1)) {
return simulatedTouchEvent(playerNum, 1.0f, 0.0f);
}
if (keyCode == prefs.getInt(Gamepad.pref_button_r + id, KeyEvent.KEYCODE_BUTTON_R1)) {
return simulatedTouchEvent(playerNum, 0.0f, 1.0f);
}
}
}
if (handle_key(playerNum, keyCode, true)) {
if (playerNum == 0)
JNIdc.hide_osd();
return true;
}
if (keyCode == pad.getSelectButtonCode()) {
return showMenu();
}
if (ViewConfiguration.get(this).hasPermanentMenuKey()) {
if (keyCode == KeyEvent.KEYCODE_MENU) {
return showMenu();
}
}
if (keyCode == KeyEvent.KEYCODE_BACK) {
return showMenu();
}
return super.onKeyDown(keyCode, event);
}
public GL2JNIView getGameView() {
return mView;
}
public void screenGrab() {
mView.screenGrab();
}
private boolean showMenu() {
if (popUp != null) {
if (!menu.dismissPopUps()) {
if (!popUp.isShowing()) {
displayPopUp(popUp);
} else {
popUp.dismiss();
}
} else {
popUp.dismiss();
}
}
return true;
}
@Override
protected void onPause() {
super.onPause();
mView.onPause();
moga.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
moga.onDestroy();
}
@Override
protected void onStop() {
// TODO Auto-generated method stub
JNIdc.stop();
mView.onStop();
super.onStop();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
@Override
protected void onResume() {
super.onResume();
mView.onResume();
moga.onResume();
}
}

View File

@ -1,728 +0,0 @@
package com.reicast.emulator.emu;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.opengl.GLSurfaceView;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.Vibrator;
import android.preference.PreferenceManager;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.ScaleGestureDetector.SimpleOnScaleGestureListener;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;
import com.android.util.FileUtils;
import com.reicast.emulator.Emulator;
import com.reicast.emulator.GL2JNIActivity;
import com.reicast.emulator.GL2JNINative;
import com.reicast.emulator.config.Config;
import com.reicast.emulator.emu.OnScreenMenu.FpsPopup;
import com.reicast.emulator.periph.VJoy;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
/**
* A simple GLSurfaceView sub-class that demonstrate how to perform
* OpenGL ES 2.0 rendering into a GL Surface. Note the following important
* details:
*
* - The class must use a custom context factory to enable 2.0 rendering.
* See ContextFactory class definition below.
*
* - The class must use a custom EGLConfigChooser to be able to select
* an EGLConfig that supports 2.0. This is done by providing a config
* specification to eglChooseConfig() that has the attribute
* EGL10.ELG_RENDERABLE_TYPE containing the EGL_OPENGL_ES2_BIT flag
* set. See ConfigChooser class definition below.
*
* - The class must select the surface's format, then choose an EGLConfig
* that matches it exactly (with regards to red/green/blue/alpha channels
* bit depths). Failure to do so would result in an EGL_BAD_MATCH error.
*/
public class GL2JNIView extends GLSurfaceView
{
public static final boolean DEBUG = false;
public static final int LAYER_TYPE_SOFTWARE = 1;
public static final int LAYER_TYPE_HARDWARE = 2;
private static String fileName;
//private AudioThread audioThread;
private EmuThread ethd;
private Handler handler = new Handler();
private static int sWidth;
private static int sHeight;
Vibrator vib;
private boolean editVjoyMode = false;
private int selectedVjoyElement = -1;
private ScaleGestureDetector scaleGestureDetector;
public float[][] vjoy_d_custom;
private static final float[][] vjoy = VJoy.baseVJoy();
Renderer rend;
private boolean touchVibrationEnabled;
private int vibrationDuration;
Context context;
public void restoreCustomVjoyValues(float[][] vjoy_d_cached) {
vjoy_d_custom = vjoy_d_cached;
VJoy.writeCustomVjoyValues(vjoy_d_cached, context);
resetEditMode();
requestLayout();
}
public void setFpsDisplay(FpsPopup fpsPop) {
rend.fpsPop = fpsPop;
}
public GL2JNIView(Context context) {
super(context);
}
public GL2JNIView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public GL2JNIView(Context context, String newFileName,
boolean translucent, int depth, int stencil, boolean editVjoyMode) {
super(context);
this.context = context;
this.editVjoyMode = editVjoyMode;
setKeepScreenOn(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
setOnSystemUiVisibilityChangeListener (new OnSystemUiVisibilityChangeListener() {
public void onSystemUiVisibilityChange(int visibility) {
if ((visibility & SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
GL2JNIView.this.setSystemUiVisibility(
SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| SYSTEM_UI_FLAG_FULLSCREEN
| SYSTEM_UI_FLAG_HIDE_NAVIGATION);
requestLayout();
}
}
});
}
setPreserveEGLContextOnPause(true);
vib=(Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
DisplayMetrics metrics = new DisplayMetrics();
//((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(metrics);
((WindowManager) context.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay().getMetrics(metrics);
final float scale = context.getResources().getDisplayMetrics().density;
sWidth = (int) (metrics.widthPixels * scale + 0.5f);
sHeight = (int) (metrics.heightPixels * scale + 0.5f);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
JNIdc.config(prefs.getString(Config.pref_home,
Environment.getExternalStorageDirectory().getAbsolutePath()));
ethd = new EmuThread(!Emulator.nosound);
touchVibrationEnabled = prefs.getBoolean(Config.pref_touchvibe, true);
vibrationDuration = prefs.getInt(Config.pref_vibrationDuration, 20);
this.setLayerType(prefs.getInt(Config.pref_rendertype, LAYER_TYPE_HARDWARE), null);
vjoy_d_custom = VJoy.readCustomVjoyValues(context);
scaleGestureDetector = new ScaleGestureDetector(context, new OscOnScaleGestureListener());
// This is the game we are going to run
fileName = newFileName;
if (Emulator.nativeact) {
if (GL2JNINative.syms != null)
JNIdc.data(1, GL2JNINative.syms);
} else {
if (GL2JNIActivity.syms != null)
JNIdc.data(1, GL2JNIActivity.syms);
}
JNIdc.init(fileName);
// By default, GLSurfaceView() creates a RGB_565 opaque surface.
// If we want a translucent one, we should change the surface's
// format here, using PixelFormat.TRANSLUCENT for GL Surfaces
// is interpreted as any 32-bit surface with alpha by SurfaceFlinger.
if(translucent) this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
if (prefs.getBoolean(Config.pref_egl14, false)) {
setEGLContextFactory(new GLCFactory14.ContextFactory());
setEGLConfigChooser(
translucent?
new GLCFactory14.ConfigChooser(8, 8, 8, 8, depth, stencil)
: new GLCFactory14.ConfigChooser(5, 6, 5, 0, depth, stencil)
);
} else {
// Setup the context factory for 2.0 rendering.
// See ContextFactory class definition below
setEGLContextFactory(new GLCFactory.ContextFactory());
if (!translucent)
this.getHolder().setFormat(PixelFormat.RGBX_8888);
// We need to choose an EGLConfig that matches the format of
// our surface exactly. This is going to be done in our
// custom config chooser. See ConfigChooser class definition
// below.
setEGLConfigChooser(
new GLCFactory.ConfigChooser(8, 8, 8, translucent ? 8 : 0, depth, stencil));
}
// Set the renderer responsible for frame rendering
setRenderer(rend=new Renderer(this));
pushInput(); //initializes controller codes
ethd.start();
}
public GLSurfaceView.Renderer getRenderer()
{
return rend;
}
private void reset_analog()
{
int j=11;
vjoy[j+1][0]=vjoy[j][0]+vjoy[j][2]/2-vjoy[j+1][2]/2;
vjoy[j+1][1]=vjoy[j][1]+vjoy[j][3]/2-vjoy[j+1][3]/2;
JNIdc.vjoy(j+1, vjoy[j+1][0], vjoy[j+1][1], vjoy[j+1][2], vjoy[j+1][3]);
}
int get_anal(int j, int axis)
{
return (int) (((vjoy[j+1][axis]+vjoy[j+1][axis+2]/2) - vjoy[j][axis] - vjoy[j][axis+2]/2)*254/vjoy[j][axis+2]);
}
float vbase(float p, float m, float scl)
{
return (int) ( m - (m -p)*scl);
}
float vbase(float p, float scl)
{
return (int) (p*scl );
}
public boolean isTablet() {
return (getContext().getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom)
{
super.onLayout(changed, left, top, right, bottom);
//dcpx/cm = dcpx/px * px/cm
float magic = isTablet() ? 0.8f : 0.7f;
float scl=480.0f/getHeight() * getContext().getResources().getDisplayMetrics().density * magic;
float scl_dc=getHeight()/480.0f;
float tx = ((getWidth()-640.0f*scl_dc)/2)/scl_dc;
float a_x = -tx+ 24*scl;
float a_y=- 24*scl;
float[][] vjoy_d = VJoy.getVjoy_d(vjoy_d_custom);
for(int i=0;i<vjoy.length;i++)
{
if (vjoy_d[i][0] == 288)
vjoy[i][0] = vjoy_d[i][0];
else if (vjoy_d[i][0]-vjoy_d_custom[getElementIdFromButtonId(i)][0] < 320)
vjoy[i][0] = a_x + vbase(vjoy_d[i][0],scl);
else
vjoy[i][0] = -a_x + vbase(vjoy_d[i][0],640,scl);
vjoy[i][1] = a_y + vbase(vjoy_d[i][1],480,scl);
vjoy[i][2] = vbase(vjoy_d[i][2],scl);
vjoy[i][3] = vbase(vjoy_d[i][3],scl);
}
for(int i=0;i<VJoy.VJoyCount;i++)
JNIdc.vjoy(i,vjoy[i][0],vjoy[i][1],vjoy[i][2],vjoy[i][3]);
reset_analog();
VJoy.writeCustomVjoyValues(vjoy_d_custom, context);
}
int anal_id=-1, lt_id=-1, rt_id=-1;
public void resetEditMode() {
editLastX = 0;
editLastY = 0;
}
private static int getElementIdFromButtonId(int buttonId) {
if (buttonId <= 3)
return 0; // DPAD
else if (buttonId <= 7)
return 1; // X, Y, B, A Buttons
else if (buttonId == 8)
return 2; // Start
else if (buttonId == 9)
return 3; // Left Trigger
else if (buttonId == 10)
return 4; // Right Trigger
else if (buttonId <= 12)
return 5; // Analog
else
return 0; // DPAD diagonials
}
public static int[] kcode_raw = { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF };
public static int[] lt = new int[4];
public static int[] rt = new int[4];
public static int[] jx = new int[4];
public static int[] jy = new int[4];
float editLastX = 0, editLastY = 0;
@Override public boolean onTouchEvent(final MotionEvent event)
{
JNIdc.show_osd();
scaleGestureDetector.onTouchEvent(event);
float ty = 0.0f;
float scl = getHeight()/480.0f;
float tx = (getWidth()-640.0f*scl)/2;
int rv = 0xFFFF;
int aid = event.getActionMasked();
int pid = event.getActionIndex();
if (editVjoyMode && selectedVjoyElement != -1 && aid == MotionEvent.ACTION_MOVE && !scaleGestureDetector.isInProgress()) {
float x = (event.getX()-tx)/scl;
float y = (event.getY()-ty)/scl;
if (editLastX != 0 && editLastY != 0) {
float deltaX = x - editLastX;
float deltaY = y - editLastY;
vjoy_d_custom[selectedVjoyElement][0] += isTablet() ? deltaX * 2 : deltaX;
vjoy_d_custom[selectedVjoyElement][1] += isTablet() ? deltaY * 2 : deltaY;
requestLayout();
}
editLastX = x;
editLastY = y;
return true;
}
for(int i=0;i<event.getPointerCount();i++)
{
float x = (event.getX(i)-tx)/scl;
float y = (event.getY(i)-ty)/scl;
if (anal_id!=event.getPointerId(i))
{
if (aid==MotionEvent.ACTION_POINTER_UP && pid==i)
continue;
for(int j=0;j<vjoy.length;j++)
{
if(x>vjoy[j][0] && x<=(vjoy[j][0]+vjoy[j][2]))
{
/*
//Disable pressure sensitive R/L
//Doesn't really work properly
int pre=(int)(event.getPressure(i)*255);
if (pre>20)
{
pre-=20;
pre*=7;
}
if (pre>255) pre=255;
*/
int pre = 255;
if(y>vjoy[j][1] && y<=(vjoy[j][1]+vjoy[j][3]))
{
if (vjoy[j][4]>=-2)
{
if (vjoy[j][5]==0)
if (!editVjoyMode && touchVibrationEnabled)
vib.vibrate(vibrationDuration);
vjoy[j][5]=2;
}
if(vjoy[j][4]==-3)
{
if (editVjoyMode) {
selectedVjoyElement = 5; // Analog
resetEditMode();
} else {
vjoy[j+1][0]=x-vjoy[j+1][2]/2;
vjoy[j+1][1]=y-vjoy[j+1][3]/2;
JNIdc.vjoy(j+1, vjoy[j+1][0], vjoy[j+1][1] , vjoy[j+1][2], vjoy[j+1][3]);
anal_id=event.getPointerId(i);
}
}
else if (vjoy[j][4]==-4);
else if(vjoy[j][4]==-1) {
if (editVjoyMode) {
selectedVjoyElement = 3; // Left Trigger
resetEditMode();
} else {
lt[0]=pre;
lt_id=event.getPointerId(i);
}
}
else if(vjoy[j][4]==-2) {
if (editVjoyMode) {
selectedVjoyElement = 4; // Right Trigger
resetEditMode();
} else{
rt[0]=pre;
rt_id=event.getPointerId(i);
}
}
else {
if (editVjoyMode) {
selectedVjoyElement = getElementIdFromButtonId(j);
resetEditMode();
} else
rv&=~(int)vjoy[j][4];
}
}
}
}
}
else
{
if (x<vjoy[11][0])
x=vjoy[11][0];
else if (x>(vjoy[11][0]+vjoy[11][2]))
x=vjoy[11][0]+vjoy[11][2];
if (y<vjoy[11][1])
y=vjoy[11][1];
else if (y>(vjoy[11][1]+vjoy[11][3]))
y=vjoy[11][1]+vjoy[11][3];
int j=11;
vjoy[j+1][0]=x-vjoy[j+1][2]/2;
vjoy[j+1][1]=y-vjoy[j+1][3]/2;
JNIdc.vjoy(j+1, vjoy[j+1][0], vjoy[j+1][1] , vjoy[j+1][2], vjoy[j+1][3]);
}
}
for(int j=0;j<vjoy.length;j++)
{
if (vjoy[j][5]==2)
vjoy[j][5]=1;
else if (vjoy[j][5]==1)
vjoy[j][5]=0;
}
switch(aid)
{
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
selectedVjoyElement = -1;
reset_analog();
anal_id=-1;
rv=0xFFFF;
rt[0]=0;
lt[0]=0;
lt_id=-1;
rt_id=-1;
for(int j=0;j<vjoy.length;j++)
vjoy[j][5]=0;
break;
case MotionEvent.ACTION_POINTER_UP:
if (event.getPointerId(event.getActionIndex())==anal_id)
{
reset_analog();
anal_id=-1;
}
else if (event.getPointerId(event.getActionIndex())==lt_id)
{
lt[0]=0;
lt_id=-1;
}
else if (event.getPointerId(event.getActionIndex())==rt_id)
{
rt[0]=0;
rt_id=-1;
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
case MotionEvent.ACTION_DOWN:
break;
}
kcode_raw[0] = rv;
jx[0] = get_anal(11, 0);
jy[0] = get_anal(11, 1);
pushInput();
return(true);
}
private class OscOnScaleGestureListener extends
SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
if (editVjoyMode && selectedVjoyElement != -1) {
vjoy_d_custom[selectedVjoyElement][2] *= detector.getScaleFactor();
requestLayout();
return true;
}
return false;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
selectedVjoyElement = -1;
}
}
public void pushInput(){
JNIdc.kcode(kcode_raw,lt,rt,jx,jy);
}
private static class Renderer implements GLSurfaceView.Renderer
{
private GL2JNIView mView;
private FPSCounter fps = new FPSCounter();
private FpsPopup fpsPop;
public Renderer (GL2JNIView mView) {
this.mView = mView;
}
public void onDrawFrame(GL10 gl)
{
if (fpsPop != null && fpsPop.isShowing()) {
fps.logFrame();
}
JNIdc.rendframe();
if(mView.takeScreenshot){
mView.takeScreenshot = false;
FileUtils.saveScreenshot(mView.getContext(), mView.getWidth(), mView.getHeight(), gl);
}
}
public void onSurfaceChanged(GL10 gl,int width,int height)
{
gl.glViewport(0, 0, width, height);
JNIdc.rendinit(width,height);
}
public void onSurfaceCreated(GL10 gl,EGLConfig config)
{
onSurfaceChanged(gl, 800, 480);
}
public class FPSCounter {
long startTime = System.nanoTime();
int frames = 0;
public void logFrame() {
frames++;
if (System.nanoTime() - startTime >= 1000000000) {
mView.post(new Runnable() {
public void run() {
if (frames > 0) {
fpsPop.setText(frames);
}
}
});
startTime = System.nanoTime();
frames = 0;
}
}
}
}
public void audioDisable(boolean disabled) {
if (disabled) {
ethd.Player.pause();
} else {
ethd.Player.play();
}
}
public void fastForward(boolean enabled) {
if (enabled) {
ethd.setPriority(Thread.MIN_PRIORITY);
} else {
ethd.setPriority(Thread.NORM_PRIORITY);
}
}
class EmuThread extends Thread
{
AudioTrack Player;
long pos; //write position
long size; //size in frames
private boolean sound;
public EmuThread(boolean sound) {
this.sound = sound;
}
@Override public void run()
{
if (sound) {
int min=AudioTrack.getMinBufferSize(44100,AudioFormat.CHANNEL_OUT_STEREO,AudioFormat.ENCODING_PCM_16BIT);
if (2048>min)
min=2048;
Player = new AudioTrack(
AudioManager.STREAM_MUSIC,
44100,
AudioFormat.CHANNEL_OUT_STEREO,
AudioFormat.ENCODING_PCM_16BIT,
min,
AudioTrack.MODE_STREAM
);
size=min/4;
pos=0;
Log.i("audcfg", "Audio streaming: buffer size " + min + " samples / " + min/44100.0 + " ms");
Player.play();
}
JNIdc.run(this);
}
int WriteBuffer(short[] samples, int wait)
{
if (sound) {
int newdata=samples.length/2;
if (wait==0)
{
//user bytes = write-read
//available = size - (write - play)
long used=pos-Player.getPlaybackHeadPosition();
long avail=size-used;
//Log.i("AUD", "u: " + used + " a: " + avail);
if (avail<newdata)
return 0;
}
pos+=newdata;
Player.write(samples, 0, samples.length);
}
return 1;
}
void showMessage(final String msg) {
handler.post(new Runnable() {
public void run() {
Log.d(context.getApplicationContext().getPackageName(), msg);
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
});
}
void coreMessage(byte[] msg) {
try {
showMessage(new String(msg, "UTF-8"));
}
catch (UnsupportedEncodingException e) {
showMessage("coreMessage: Failed to display error");
}
}
void Die() {
showMessage("Something went wrong and reicast crashed.\nPlease report this on the reicast forums.");
((Activity) context).finish();
}
}
public void onStop() {
// TODO Auto-generated method stub
System.exit(0);
try {
ethd.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@TargetApi(19)
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
GL2JNIView.this.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
requestLayout();
}
}
private boolean takeScreenshot = false;
public void screenGrab() {
takeScreenshot = true;
}
}

View File

@ -1,237 +0,0 @@
package com.reicast.emulator.emu;
import android.opengl.GLSurfaceView;
import android.util.Log;
import java.util.Locale;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
public class GLCFactory {
private static void LOGI(String S) { Log.i("GL2JNIView",S); }
private static void LOGW(String S) { Log.w("GL2JNIView",S); }
private static void LOGE(String S) { Log.e("GL2JNIView",S); }
public static class ContextFactory implements GLSurfaceView.EGLContextFactory
{
private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
public EGLContext createContext(EGL10 egl,EGLDisplay display,EGLConfig eglConfig)
{
int[] attrList = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
LOGI("Creating OpenGL ES 2.0 context");
checkEglError("Before eglCreateContext",egl);
EGLContext context = egl.eglCreateContext(display,eglConfig,EGL10.EGL_NO_CONTEXT,attrList);
checkEglError("After eglCreateContext",egl);
return(context);
}
public void destroyContext(EGL10 egl,EGLDisplay display,EGLContext context)
{
LOGI("Destroying OpenGL ES 2.0 context");
egl.eglDestroyContext(display,context);
}
}
private static void checkEglError(String prompt,EGL10 egl)
{
int error;
while((error=egl.eglGetError()) != EGL10.EGL_SUCCESS)
LOGE(String.format("%s: EGL error: 0x%x",prompt,error));
}
public static class ConfigChooser implements GLSurfaceView.EGLConfigChooser
{
// Subclasses can adjust these values:
protected int mRedSize;
protected int mGreenSize;
protected int mBlueSize;
protected int mAlphaSize;
protected int mDepthSize;
protected int mStencilSize;
private int[] mValue = new int[1];
public ConfigChooser(int r,int g,int b,int a,int depth,int stencil)
{
mRedSize = r;
mGreenSize = g;
mBlueSize = b;
mAlphaSize = a;
mDepthSize = depth;
mStencilSize = stencil;
}
// This EGL config specification is used to specify 2.0 rendering.
// We use a minimum size of 4 bits for red/green/blue, but will
// perform actual matching in chooseConfig() below.
private static final int EGL_OPENGL_ES2_BIT = 4;
private static final int[] cfgAttrs =
{
EGL10.EGL_RED_SIZE, 4,
EGL10.EGL_GREEN_SIZE, 4,
EGL10.EGL_BLUE_SIZE, 4,
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL10.EGL_DEPTH_SIZE, 24,
EGL10.EGL_NONE
};
public EGLConfig chooseConfig(EGL10 egl,EGLDisplay display)
{
// Get the number of minimally matching EGL configurations
int[] cfgCount = new int[1];
egl.eglChooseConfig(display,cfgAttrs,null,0,cfgCount);
if(cfgCount[0]<=0)
{
cfgAttrs[9]=16;
egl.eglChooseConfig(display,cfgAttrs,null,0,cfgCount);
}
if(cfgCount[0]<=0)
throw new IllegalArgumentException("No configs match configSpec");
// Allocate then read the array of minimally matching EGL configs
EGLConfig[] configs = new EGLConfig[cfgCount[0]];
egl.eglChooseConfig(display,cfgAttrs,configs,cfgCount[0],cfgCount);
if(GL2JNIView.DEBUG)
printConfigs(egl,display,configs);
// Now return the "best" one
return(chooseConfig(egl,display,configs));
}
public EGLConfig chooseConfig(EGL10 egl,EGLDisplay display,EGLConfig[] configs)
{
for(EGLConfig config : configs)
{
int d = findConfigAttrib(egl,display,config,EGL10.EGL_DEPTH_SIZE,0);
int s = findConfigAttrib(egl,display,config,EGL10.EGL_STENCIL_SIZE,0);
// We need at least mDepthSize and mStencilSize bits
if(d>=mDepthSize || s>=mStencilSize)
{
// We want an *exact* match for red/green/blue/alpha
int r = findConfigAttrib(egl,display,config,EGL10.EGL_RED_SIZE, 0);
int g = findConfigAttrib(egl,display,config,EGL10.EGL_GREEN_SIZE,0);
int b = findConfigAttrib(egl,display,config,EGL10.EGL_BLUE_SIZE, 0);
int a = findConfigAttrib(egl,display,config,EGL10.EGL_ALPHA_SIZE,0);
if(r==mRedSize && g==mGreenSize && b==mBlueSize && a==mAlphaSize)
return(config);
}
}
return(null);
}
private int findConfigAttrib(EGL10 egl,EGLDisplay display,EGLConfig config,int attribute,int defaultValue)
{
return(egl.eglGetConfigAttrib(display,config,attribute,mValue)? mValue[0] : defaultValue);
}
private void printConfigs(EGL10 egl,EGLDisplay display,EGLConfig[] configs)
{
LOGW(String.format(Locale.getDefault(), "%d configurations", configs.length));
for(int i=0 ; i<configs.length ; i++)
{
LOGW(String.format(Locale.getDefault(), "Configuration %d:", i));
printConfig(egl,display,configs[i]);
}
}
private void printConfig(EGL10 egl,EGLDisplay display,EGLConfig config)
{
final int[] attributes =
{
EGL10.EGL_BUFFER_SIZE,
EGL10.EGL_ALPHA_SIZE,
EGL10.EGL_BLUE_SIZE,
EGL10.EGL_GREEN_SIZE,
EGL10.EGL_RED_SIZE,
EGL10.EGL_DEPTH_SIZE,
EGL10.EGL_STENCIL_SIZE,
EGL10.EGL_CONFIG_CAVEAT,
EGL10.EGL_CONFIG_ID,
EGL10.EGL_LEVEL,
EGL10.EGL_MAX_PBUFFER_HEIGHT,
EGL10.EGL_MAX_PBUFFER_PIXELS,
EGL10.EGL_MAX_PBUFFER_WIDTH,
EGL10.EGL_NATIVE_RENDERABLE,
EGL10.EGL_NATIVE_VISUAL_ID,
EGL10.EGL_NATIVE_VISUAL_TYPE,
0x3030, // EGL10.EGL_PRESERVED_RESOURCES,
EGL10.EGL_SAMPLES,
EGL10.EGL_SAMPLE_BUFFERS,
EGL10.EGL_SURFACE_TYPE,
EGL10.EGL_TRANSPARENT_TYPE,
EGL10.EGL_TRANSPARENT_RED_VALUE,
EGL10.EGL_TRANSPARENT_GREEN_VALUE,
EGL10.EGL_TRANSPARENT_BLUE_VALUE,
0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB,
0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA,
0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL,
0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL,
EGL10.EGL_LUMINANCE_SIZE,
EGL10.EGL_ALPHA_MASK_SIZE,
EGL10.EGL_COLOR_BUFFER_TYPE,
EGL10.EGL_RENDERABLE_TYPE,
0x3042 // EGL10.EGL_CONFORMANT
};
final String[] names =
{
"EGL_BUFFER_SIZE",
"EGL_ALPHA_SIZE",
"EGL_BLUE_SIZE",
"EGL_GREEN_SIZE",
"EGL_RED_SIZE",
"EGL_DEPTH_SIZE",
"EGL_STENCIL_SIZE",
"EGL_CONFIG_CAVEAT",
"EGL_CONFIG_ID",
"EGL_LEVEL",
"EGL_MAX_PBUFFER_HEIGHT",
"EGL_MAX_PBUFFER_PIXELS",
"EGL_MAX_PBUFFER_WIDTH",
"EGL_NATIVE_RENDERABLE",
"EGL_NATIVE_VISUAL_ID",
"EGL_NATIVE_VISUAL_TYPE",
"EGL_PRESERVED_RESOURCES",
"EGL_SAMPLES",
"EGL_SAMPLE_BUFFERS",
"EGL_SURFACE_TYPE",
"EGL_TRANSPARENT_TYPE",
"EGL_TRANSPARENT_RED_VALUE",
"EGL_TRANSPARENT_GREEN_VALUE",
"EGL_TRANSPARENT_BLUE_VALUE",
"EGL_BIND_TO_TEXTURE_RGB",
"EGL_BIND_TO_TEXTURE_RGBA",
"EGL_MIN_SWAP_INTERVAL",
"EGL_MAX_SWAP_INTERVAL",
"EGL_LUMINANCE_SIZE",
"EGL_ALPHA_MASK_SIZE",
"EGL_COLOR_BUFFER_TYPE",
"EGL_RENDERABLE_TYPE",
"EGL_CONFORMANT"
};
int[] value = new int[1];
for(int i=0 ; i<attributes.length ; i++)
if(egl.eglGetConfigAttrib(display,config,attributes[i],value))
LOGI(String.format(Locale.getDefault(), " %s: %d\n",names[i],value[0]));
else
while(egl.eglGetError()!=EGL10.EGL_SUCCESS);
}
}
}

View File

@ -1,254 +0,0 @@
package com.reicast.emulator.emu;
import android.annotation.TargetApi;
import android.opengl.EGL14;
import android.opengl.EGLExt;
import android.opengl.GLSurfaceView;
import android.os.Build;
import android.util.Log;
import java.util.Locale;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public class GLCFactory14 {
private static void LOGI(String S) { Log.i("GL2JNIView-v6",S); }
private static void LOGW(String S) { Log.w("GL2JNIView-v6",S); }
private static void LOGE(String S) { Log.e("GL2JNIView-v6",S); }
public static class ContextFactory implements GLSurfaceView.EGLContextFactory
{
private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
public EGLContext createContext(EGL10 egl,EGLDisplay display,EGLConfig eglConfig)
{
EGLContext context = EGL10.EGL_NO_CONTEXT;
for ( int clientVersion = 3; clientVersion >= 2; clientVersion-- ) {
int[] attrList = { EGL_CONTEXT_CLIENT_VERSION, clientVersion, EGL14.EGL_NONE };
LOGI("Creating OpenGL ES " + clientVersion + " context");
checkEglError("Before eglCreateContext",egl);
context = egl.eglCreateContext(display,eglConfig,EGL10.EGL_NO_CONTEXT,attrList);
checkEglError("After eglCreateContext",egl);
if (context != EGL10.EGL_NO_CONTEXT) {
break;
}
}
return(context);
}
public void destroyContext(EGL10 egl,EGLDisplay display,EGLContext context)
{
LOGI("Destroying OpenGL ES X context");
egl.eglDestroyContext(display,context);
}
}
private static void checkEglError(String prompt,EGL10 egl)
{
int error;
while((error=egl.eglGetError()) != EGL14.EGL_SUCCESS)
LOGE(String.format(Locale.getDefault(), "%s: EGL error: 0x%x",prompt,error));
}
public static class ConfigChooser implements GLSurfaceView.EGLConfigChooser
{
// Subclasses can adjust these values:
protected int mRedSize;
protected int mGreenSize;
protected int mBlueSize;
protected int mAlphaSize;
protected int mDepthSize;
protected int mStencilSize;
private int[] mValue = new int[1];
public ConfigChooser(int r,int g,int b,int a,int depth,int stencil)
{
mRedSize = r;
mGreenSize = g;
mBlueSize = b;
mAlphaSize = a;
mDepthSize = depth;
mStencilSize = stencil;
}
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
mValue = new int[1];
int glAPIToTry = EGLExt.EGL_OPENGL_ES3_BIT_KHR;
int[] configSpec = null;
do {
EGL14.eglBindAPI(glAPIToTry);
int renderableType;
if (glAPIToTry == EGLExt.EGL_OPENGL_ES3_BIT_KHR) {
renderableType = EGLExt.EGL_OPENGL_ES3_BIT_KHR;
// If this API does not work, try ES2 next.
glAPIToTry = EGL14.EGL_OPENGL_ES2_BIT;
} else {
renderableType = EGL14.EGL_OPENGL_ES2_BIT;
// If this API does not work, try ES next.
glAPIToTry = EGL14.EGL_OPENGL_ES_API;
}
configSpec = new int[] {
EGL14.EGL_RED_SIZE, 4,
EGL14.EGL_GREEN_SIZE, 4,
EGL14.EGL_BLUE_SIZE, 4,
EGL14.EGL_RENDERABLE_TYPE, renderableType,
EGL14.EGL_DEPTH_SIZE, 24,
EGL14.EGL_NONE
};
if (!egl.eglChooseConfig(display, configSpec, null, 0, mValue)) {
configSpec[9] = 16;
if (!egl.eglChooseConfig(display, configSpec, null, 0, mValue)) {
throw new IllegalArgumentException("Could not get context count");
}
}
} while (glAPIToTry != EGL14.EGL_OPENGL_ES_API && mValue[0]<=0);
if (mValue[0]<=0) {
throw new IllegalArgumentException("No configs match configSpec");
}
// Get all matching configurations.
EGLConfig[] configs = new EGLConfig[mValue[0]];
if (GL2JNIView.DEBUG)
LOGW(String.format(Locale.getDefault(), "%d configurations", configs.length));
if (!egl.eglChooseConfig(display, configSpec, configs, mValue[0], mValue)) {
throw new IllegalArgumentException("Could not get config data");
}
for (int i = 0; i < configs.length; ++i) {
EGLConfig config = configs[i];
int d = findConfigAttrib(egl, display, config,
EGL14.EGL_DEPTH_SIZE, 0);
int s = findConfigAttrib(egl, display, config,
EGL14.EGL_STENCIL_SIZE, 0);
// We need at least mDepthSize and mStencilSize bits
if (d >= mDepthSize || s >= mStencilSize) {
// We want an *exact* match for red/green/blue/alpha
int r = findConfigAttrib(egl, display, config,
EGL14.EGL_RED_SIZE, 0);
int g = findConfigAttrib(egl, display, config,
EGL14.EGL_GREEN_SIZE, 0);
int b = findConfigAttrib(egl, display, config,
EGL14.EGL_BLUE_SIZE, 0);
int a = findConfigAttrib(egl, display, config,
EGL14.EGL_ALPHA_SIZE, 0);
if (r == mRedSize && g == mGreenSize && b == mBlueSize
&& a == mAlphaSize)
if (GL2JNIView.DEBUG) {
LOGW(String.format("Configuration %d:", i));
printConfig(egl, display, configs[i]);
}
return config;
}
}
throw new IllegalArgumentException("Could not find suitable EGL config");
}
private int findConfigAttrib(EGL10 egl,EGLDisplay display,EGLConfig config,int attribute,int defaultValue)
{
return(egl.eglGetConfigAttrib(display,config,attribute,mValue)? mValue[0] : defaultValue);
}
private void printConfig(EGL10 egl,EGLDisplay display,EGLConfig config)
{
final int[] attributes =
{
EGL14.EGL_BUFFER_SIZE,
EGL14.EGL_ALPHA_SIZE,
EGL14.EGL_BLUE_SIZE,
EGL14.EGL_GREEN_SIZE,
EGL14.EGL_RED_SIZE,
EGL14.EGL_DEPTH_SIZE,
EGL14.EGL_STENCIL_SIZE,
EGL14.EGL_CONFIG_CAVEAT,
EGL14.EGL_CONFIG_ID,
EGL14.EGL_LEVEL,
EGL14.EGL_MAX_PBUFFER_HEIGHT,
EGL14.EGL_MAX_PBUFFER_PIXELS,
EGL14.EGL_MAX_PBUFFER_WIDTH,
EGL14.EGL_NATIVE_RENDERABLE,
EGL14.EGL_NATIVE_VISUAL_ID,
EGL14.EGL_NATIVE_VISUAL_TYPE,
0x3030, // EGL14.EGL_PRESERVED_RESOURCES,
EGL14.EGL_SAMPLES,
EGL14.EGL_SAMPLE_BUFFERS,
EGL14.EGL_SURFACE_TYPE,
EGL14.EGL_TRANSPARENT_TYPE,
EGL14.EGL_TRANSPARENT_RED_VALUE,
EGL14.EGL_TRANSPARENT_GREEN_VALUE,
EGL14.EGL_TRANSPARENT_BLUE_VALUE,
EGL14.EGL_BIND_TO_TEXTURE_RGB,
EGL14.EGL_BIND_TO_TEXTURE_RGBA,
EGL14.EGL_MIN_SWAP_INTERVAL,
EGL14.EGL_MAX_SWAP_INTERVAL,
EGL14.EGL_LUMINANCE_SIZE,
EGL14.EGL_ALPHA_MASK_SIZE,
EGL14.EGL_COLOR_BUFFER_TYPE,
EGL14.EGL_RENDERABLE_TYPE,
EGL14.EGL_CONFORMANT
};
final String[] names =
{
"EGL_BUFFER_SIZE",
"EGL_ALPHA_SIZE",
"EGL_BLUE_SIZE",
"EGL_GREEN_SIZE",
"EGL_RED_SIZE",
"EGL_DEPTH_SIZE",
"EGL_STENCIL_SIZE",
"EGL_CONFIG_CAVEAT",
"EGL_CONFIG_ID",
"EGL_LEVEL",
"EGL_MAX_PBUFFER_HEIGHT",
"EGL_MAX_PBUFFER_PIXELS",
"EGL_MAX_PBUFFER_WIDTH",
"EGL_NATIVE_RENDERABLE",
"EGL_NATIVE_VISUAL_ID",
"EGL_NATIVE_VISUAL_TYPE",
"EGL_PRESERVED_RESOURCES",
"EGL_SAMPLES",
"EGL_SAMPLE_BUFFERS",
"EGL_SURFACE_TYPE",
"EGL_TRANSPARENT_TYPE",
"EGL_TRANSPARENT_RED_VALUE",
"EGL_TRANSPARENT_GREEN_VALUE",
"EGL_TRANSPARENT_BLUE_VALUE",
"EGL_BIND_TO_TEXTURE_RGB",
"EGL_BIND_TO_TEXTURE_RGBA",
"EGL_MIN_SWAP_INTERVAL",
"EGL_MAX_SWAP_INTERVAL",
"EGL_LUMINANCE_SIZE",
"EGL_ALPHA_MASK_SIZE",
"EGL_COLOR_BUFFER_TYPE",
"EGL_RENDERABLE_TYPE",
"EGL_CONFORMANT"
};
int[] value = new int[1];
for(int i=0 ; i<attributes.length ; i++)
if(egl.eglGetConfigAttrib(display,config,attributes[i],value))
LOGI(String.format(Locale.getDefault(), " %s: %d\n",names[i],value[0]));
else
while(egl.eglGetError()!=EGL14.EGL_SUCCESS);
}
}
}

View File

@ -1,164 +0,0 @@
package com.reicast.emulator.periph;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
public class VJoy {
public static final int key_CONT_B = 0x0002;
public static final int key_CONT_A = 0x0004;
public static final int key_CONT_START = 0x0008;
public static final int key_CONT_DPAD_UP = 0x0010;
public static final int key_CONT_DPAD_DOWN = 0x0020;
public static final int key_CONT_DPAD_LEFT = 0x0040;
public static final int key_CONT_DPAD_RIGHT = 0x0080;
public static final int key_CONT_Y = 0x0200;
public static final int key_CONT_X = 0x0400;
public static final int LAYER_TYPE_SOFTWARE = 1;
public static final int LAYER_TYPE_HARDWARE = 2;
public static int VJoyCount = 13;
public static float[][] baseVJoy() {
return new float[][] {
new float[] { 24+0, 24+64, 64,64, VJoy.key_CONT_DPAD_LEFT, 0},
new float[] { 24+64, 24+0, 64,64, VJoy.key_CONT_DPAD_UP, 0},
new float[] { 24+128, 24+64, 64,64, VJoy.key_CONT_DPAD_RIGHT, 0},
new float[] { 24+64, 24+128, 64,64, VJoy.key_CONT_DPAD_DOWN, 0},
new float[] { 440+0, 280+64, 64,64, VJoy.key_CONT_X, 0},
new float[] { 440+64, 280+0, 64,64, VJoy.key_CONT_Y, 0},
new float[] { 440+128, 280+64, 64,64, VJoy.key_CONT_B, 0},
new float[] { 440+64, 280+128, 64,64, VJoy.key_CONT_A, 0},
new float[] { 320-32, 360+32, 64,64, VJoy.key_CONT_START, 0},
new float[] { 440, 200, 90,64, -1, 0},
new float[] { 542, 200, 90,64, -2, 0},
new float[] { 0, 128+224, 128,128, -3, 0},
new float[] { 96, 320, 32,32, -4, 0},
new float[] { 20+0 , 288+0 , 64,64, key_CONT_DPAD_LEFT|key_CONT_DPAD_UP, 0},
new float[] { 20+128, 288+0 , 64,64, key_CONT_DPAD_RIGHT|key_CONT_DPAD_UP, 0},
new float[] { 20+0 , 288+128, 64,64, key_CONT_DPAD_LEFT|key_CONT_DPAD_DOWN, 0},
new float[] { 20+128, 288+128, 64,64, key_CONT_DPAD_RIGHT|key_CONT_DPAD_DOWN, 0},
};
}
public static float[][] readCustomVjoyValues(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return new float[][] {
// x-shift, y-shift, sizing-factor
new float[] { prefs.getFloat("touch_x_shift_dpad", 0),
prefs.getFloat("touch_y_shift_dpad", 0),
prefs.getFloat("touch_scale_dpad", 1)
}, // DPAD
new float[] { prefs.getFloat("touch_x_shift_buttons", 0),
prefs.getFloat("touch_y_shift_buttons", 0),
prefs.getFloat("touch_scale_buttons", 1)
}, // X, Y, B, A Buttons
new float[] { prefs.getFloat("touch_x_shift_start", 0),
prefs.getFloat("touch_y_shift_start", 0),
prefs.getFloat("touch_scale_start", 1)
}, // Start
new float[] { prefs.getFloat("touch_x_shift_left_trigger", 0),
prefs.getFloat("touch_y_shift_left_trigger", 0),
prefs.getFloat("touch_scale_left_trigger", 1)
}, // Left Trigger
new float[] { prefs.getFloat("touch_x_shift_right_trigger", 0),
prefs.getFloat("touch_y_shift_right_trigger", 0),
prefs.getFloat("touch_scale_right_trigger", 1)
}, // Right Trigger
new float[] { prefs.getFloat("touch_x_shift_analog", 0),
prefs.getFloat("touch_y_shift_analog", 0),
prefs.getFloat("touch_scale_analog", 1)
} // Analog Stick
};
}
public static float[][] getVjoy_d(float[][] vjoy_d_custom) {
return new float[][] {
new float[] { 20+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+64*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_LEFT},
new float[] { 20+64*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_UP},
new float[] { 20+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+64*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_RIGHT},
new float[] { 20+64*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_DOWN},
new float[] { 448+0*vjoy_d_custom[1][2]+vjoy_d_custom[1][0], 288+64*vjoy_d_custom[1][2]+vjoy_d_custom[1][1], 64*vjoy_d_custom[1][2],64*vjoy_d_custom[1][2], key_CONT_X},
new float[] { 448+64*vjoy_d_custom[1][2]+vjoy_d_custom[1][0], 288+0*vjoy_d_custom[1][2]+vjoy_d_custom[1][1], 64*vjoy_d_custom[1][2],64*vjoy_d_custom[1][2], key_CONT_Y},
new float[] { 448+128*vjoy_d_custom[1][2]+vjoy_d_custom[1][0], 288+64*vjoy_d_custom[1][2]+vjoy_d_custom[1][1], 64*vjoy_d_custom[1][2],64*vjoy_d_custom[1][2], key_CONT_B},
new float[] { 448+64*vjoy_d_custom[1][2]+vjoy_d_custom[1][0], 288+128*vjoy_d_custom[1][2]+vjoy_d_custom[1][1], 64*vjoy_d_custom[1][2],64*vjoy_d_custom[1][2], key_CONT_A},
new float[] { 320-32+vjoy_d_custom[2][0], 288+128+vjoy_d_custom[2][1], 64*vjoy_d_custom[2][2],64*vjoy_d_custom[2][2], key_CONT_START},
new float[] { 440+vjoy_d_custom[3][0], 200+vjoy_d_custom[3][1], 90*vjoy_d_custom[3][2],64*vjoy_d_custom[3][2], -1},
new float[] { 542+vjoy_d_custom[4][0], 200+vjoy_d_custom[4][1], 90*vjoy_d_custom[4][2],64*vjoy_d_custom[4][2], -2},
new float[] { 16+vjoy_d_custom[5][0], 24+32+vjoy_d_custom[5][1], 128*vjoy_d_custom[5][2],128*vjoy_d_custom[5][2], -3},
new float[] { 96+vjoy_d_custom[5][0], 320+vjoy_d_custom[5][1], 32*vjoy_d_custom[5][2],32*vjoy_d_custom[5][2], -4},
new float[] { 20+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_LEFT|key_CONT_DPAD_UP},
new float[] { 20+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_RIGHT|key_CONT_DPAD_UP},
new float[] { 20+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_LEFT|key_CONT_DPAD_DOWN},
new float[] { 20+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_RIGHT|key_CONT_DPAD_DOWN},
};
}
public static void writeCustomVjoyValues(float[][] vjoy_d_custom, Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
prefs.edit().putFloat("touch_x_shift_dpad", vjoy_d_custom[0][0]).apply();
prefs.edit().putFloat("touch_y_shift_dpad", vjoy_d_custom[0][1]).apply();
prefs.edit().putFloat("touch_scale_dpad", vjoy_d_custom[0][2]).apply();
prefs.edit().putFloat("touch_x_shift_buttons", vjoy_d_custom[1][0]).apply();
prefs.edit().putFloat("touch_y_shift_buttons", vjoy_d_custom[1][1]).apply();
prefs.edit().putFloat("touch_scale_buttons", vjoy_d_custom[1][2]).apply();
prefs.edit().putFloat("touch_x_shift_start", vjoy_d_custom[2][0]).apply();
prefs.edit().putFloat("touch_y_shift_start", vjoy_d_custom[2][1]).apply();
prefs.edit().putFloat("touch_scale_start", vjoy_d_custom[2][2]).apply();
prefs.edit().putFloat("touch_x_shift_left_trigger", vjoy_d_custom[3][0]).apply();
prefs.edit().putFloat("touch_y_shift_left_trigger", vjoy_d_custom[3][1]).apply();
prefs.edit().putFloat("touch_scale_left_trigger", vjoy_d_custom[3][2]).apply();
prefs.edit().putFloat("touch_x_shift_right_trigger", vjoy_d_custom[4][0]).apply();
prefs.edit().putFloat("touch_y_shift_right_trigger", vjoy_d_custom[4][1]).apply();
prefs.edit().putFloat("touch_scale_right_trigger", vjoy_d_custom[4][2]).apply();
prefs.edit().putFloat("touch_x_shift_analog", vjoy_d_custom[5][0]).apply();
prefs.edit().putFloat("touch_y_shift_analog", vjoy_d_custom[5][1]).apply();
prefs.edit().putFloat("touch_scale_analog", vjoy_d_custom[5][2]).apply();
}
public static void resetCustomVjoyValues(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
prefs.edit().remove("touch_x_shift_dpad").apply();
prefs.edit().remove("touch_y_shift_dpad").apply();
prefs.edit().remove("touch_scale_dpad").apply();
prefs.edit().remove("touch_x_shift_buttons").apply();
prefs.edit().remove("touch_y_shift_buttons").apply();
prefs.edit().remove("touch_scale_buttons").apply();
prefs.edit().remove("touch_x_shift_start").apply();
prefs.edit().remove("touch_y_shift_start").apply();
prefs.edit().remove("touch_scale_start").apply();
prefs.edit().remove("touch_x_shift_left_trigger").apply();
prefs.edit().remove("touch_y_shift_left_trigger").apply();
prefs.edit().remove("touch_scale_left_trigger").apply();
prefs.edit().remove("touch_x_shift_right_trigger").apply();
prefs.edit().remove("touch_y_shift_right_trigger").apply();
prefs.edit().remove("touch_scale_right_trigger").apply();
prefs.edit().remove("touch_x_shift_analog").apply();
prefs.edit().remove("touch_y_shift_analog").apply();
prefs.edit().remove("touch_scale_analog").apply();
}
}

View File

@ -9,7 +9,7 @@ def getVersionCode = { ->
def getVersionName = { ->
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'describe', '--always'
commandLine 'git', 'describe', '--tags', '--always'
standardOutput = stdout
}
return stdout.toString().trim()
@ -85,16 +85,16 @@ play {
}
dependencies {
compile 'com.android.support:support-v4:25.4.0'
compile 'com.android.support:appcompat-v7:25.4.0'
compile 'com.android.support:design:25.4.0'
compile 'com.android.support.constraint:constraint-layout:1.1.2'
compile 'org.bouncycastle:bcprov-jdk16:1.46'
compile 'commons-io:commons-io:2.6'
compile 'org.apache.commons:commons-lang3:3.7'
compile ('com.googlecode.json-simple:json-simple:1.1.1') {
implementation 'com.android.support:support-v4:25.4.0'
implementation 'com.android.support:appcompat-v7:25.4.0'
implementation 'com.android.support:design:25.4.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
implementation 'org.bouncycastle:bcprov-jdk16:1.46'
implementation 'commons-io:commons-io:2.6'
implementation 'org.apache.commons:commons-lang3:3.7'
implementation ('com.googlecode.json-simple:json-simple:1.1.1') {
exclude module: 'junit'
}
compile fileTree(include: ['*.jar'], dir: 'libs')
implementation fileTree(include: ['*.jar'], dir: 'libs')
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -16,6 +16,7 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_SERVICE" />
<uses-feature
android:glEsVersion="0x00020000"
@ -121,6 +122,7 @@
android:configChanges="orientation|navigation|screenSize|screenLayout|uiMode|keyboard|keyboardHidden"
android:screenOrientation="sensorLandscape"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />
</application>
</manifest>

View File

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

View File

@ -51,7 +51,7 @@ public class AboutFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.about_fragment, container, false);
}
@ -207,14 +207,14 @@ public class AboutFragment extends Fragment {
list.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
int position, long id) {
slidingGithub.open();
}
});
}
}
private JSONArray getContent(String urlString) throws IOException, JSONException {
HttpURLConnection conn = (HttpURLConnection) new URL(urlString).openConnection();
conn.setRequestMethod("GET");

View File

@ -0,0 +1,354 @@
package com.reicast.emulator;
/*
* File: CloudFragment.java
* Author: Luca D'Amico (Luca91)
* Last Edit: 11 May 2014
*
* Reference: http://forums.reicast.com/index.php?topic=160.msg422
*/
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;
import com.dropbox.client2.DropboxAPI;
import com.dropbox.client2.DropboxAPI.Entry;
import com.dropbox.client2.android.AndroidAuthSession;
import com.dropbox.client2.exception.DropboxException;
import com.dropbox.client2.session.AccessTokenPair;
import com.dropbox.client2.session.AppKeyPair;
import com.dropbox.client2.session.TokenPair;
import com.reicast.emulator.config.Config;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.ExecutionException;
public class CloudFragment extends Fragment {
Button uploadBtn;
Button downloadBtn;
AlertDialog.Builder confirmDialog = null;
boolean actionRequired=false;
public String task = "";
DropBoxClient client = null;
private String home_directory;
String[] vmus = {"vmu_save_A1.bin","vmu_save_A2.bin",
"vmu_save_B1.bin","vmu_save_B2.bin",
"vmu_save_C1.bin","vmu_save_C2.bin",
"vmu_save_D1.bin","vmu_save_D2.bin"};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.cloud_fragment, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
home_directory = mPrefs.getString(Config.pref_home,
Environment.getExternalStorageDirectory().getAbsolutePath());
buttonListener();
confirmDialog = new AlertDialog.Builder(getActivity());
setClient();
}
public void setClient(){
if(client==null)
client = new DropBoxClient(getActivity());
}
public void buttonListener() {
uploadBtn = (Button) getView().findViewById(R.id.uploadBtn);
uploadBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
confirmDialog.setMessage(R.string.uploadWarning);
confirmDialog.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setClient();
task = "Upload";
client.startLogin();
actionRequired = true;
}
});
confirmDialog.setNegativeButton(R.string.cancel, null);
confirmDialog.show();
}
});
downloadBtn = (Button) getView().findViewById(R.id.downloadBtn);
downloadBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
confirmDialog.setMessage(R.string.downloadWarning);
confirmDialog.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setClient();
task = "Download";
client.startLogin();
actionRequired = true;
}
});
confirmDialog.setNegativeButton(R.string.cancel, null);
confirmDialog.show();
}
});
}
@Override
public void onResume(){
super.onResume();
if (client.mDBApi != null) {
if (client.mDBApi.getSession().authenticationSuccessful()) {
try {
client.mDBApi.getSession().finishAuthentication();
TokenPair tokens = client.mDBApi.getSession(). getAccessTokenPair();
if(tokens == null)
Toast.makeText(getActivity(), "Failed to save session token!", Toast.LENGTH_SHORT).show();
else
client.storeKeys(tokens.key, tokens.secret);
} catch (IllegalStateException e) {
Log.i("Dropbox", "Error authenticating", e);
}
}
if(actionRequired){
for(int k=0;k<vmus.length;k++){
String result = "";
try {
String vmuPath = home_directory+"/"+vmus[k];
File vmu = new File(vmuPath);
if(vmu.exists() || task.equals("Download") ){
result = new netOperation(client, home_directory).execute(
task,vmuPath,vmus[k]).get();
}
else{
result = "Ok"; // The result is still ok, because the vmu bin doesn't exist ;)
Toast.makeText(getActivity(), vmus[k]+ " doesn't exist, skipping it!",
Toast.LENGTH_SHORT).show();
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
if(result.equals("Ok"))
Toast.makeText(getActivity(), "Task Completed!", Toast.LENGTH_SHORT).show();
else
Toast.makeText(getActivity(), "Task Failed!", Toast.LENGTH_SHORT).show();
}
}
actionRequired = false;
}
}
}
class DropBoxClient {
Context context;
final static private String APP_KEY = "7d7tw1t57sbzrj5";
final static private String APP_SECRET = "5xxqa2uctousyi2";
public DropboxAPI<AndroidAuthSession> mDBApi;
AndroidAuthSession session;
public DropBoxClient(Context context){
this.context = context;
session = buildSession();
mDBApi = new DropboxAPI<AndroidAuthSession>(session);
}
public void startLogin(){
mDBApi.getSession().startOAuth2Authentication(context);
}
public String[] getKeys() {
SharedPreferences prefs = context.getSharedPreferences("ReicastVMUUploader", 0);
String key = prefs.getString("DBoxKey", null);
String secret = prefs.getString("DBoxSecret", null);
if (key != null && secret != null) {
String[] ret = new String[2];
ret[0] = key;
ret[1] = secret;
return ret;
} else {
return null;
}
}
public void storeKeys(String key, String secret) {
SharedPreferences prefs = context.getSharedPreferences("ReicastVMUUploader", 0);
Editor edit = prefs.edit();
edit.putString("DBoxKey", key);
edit.putString("DBoxSecret", secret);
edit.commit();
}
private AndroidAuthSession buildSession() {
AppKeyPair appKeyPair = new AppKeyPair(APP_KEY, APP_SECRET);
AndroidAuthSession session;
String[] stored = getKeys();
if (stored != null) {
AccessTokenPair accessToken = new AccessTokenPair(stored[0], stored[1]);
session = new AndroidAuthSession(appKeyPair, accessToken);
} else {
session = new AndroidAuthSession(appKeyPair);
}
return session;
}
}
class netOperation extends AsyncTask<String, Void, String> {
DropBoxClient client = null;
private String home_directory;
public netOperation(DropBoxClient client, String home_directory){
this.client = client;
this.home_directory = home_directory;
}
public boolean uploadFile(String filePath, String fileName) {
File file = new File(filePath);
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
DropboxAPI.Entry response = null;
try {
response = client.mDBApi.putFileOverwrite("/"+fileName, inputStream, file.length(), null);
} catch (DropboxException e) {
e.printStackTrace();
}
Log.i("FileInfos", "The uploaded file's rev is: "+ response);
return true;
}
public boolean downloadFile(String filePath, String fileName) {
DropboxAPI.DropboxFileInfo info = null;
try {
Entry remoteFile = client.mDBApi.metadata("/"+fileName, 1, null, false, null);
if((remoteFile.rev != null) && (remoteFile.bytes > 0)){ // Avoid to download 0 bytes vmus!
File file = new File(filePath);
if(file.exists())
createBackupOfVmu(fileName);
FileOutputStream out = null;
try {
out = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
info = client.mDBApi.getFile("/"+fileName,null,out,null);
}
} catch (DropboxException e) {
e.printStackTrace();
}
Log.i("FileInfos", "The downloaded file's rev is: "+ info);
return true;
}
@Override
protected void onPostExecute(String result) {
}
@Override
protected String doInBackground(String... strings) {
if(strings[0].equals("Upload")){
if(uploadFile(strings[1],strings[2]))
return "Ok";
else
return "No";
}
else if(strings[0].equals("Download")){
if(downloadFile(strings[1],strings[2]))
return "Ok";
else
return "No";
}
else
return "Unknown";
}
@Override
protected void onPreExecute() {}
@Override
protected void onProgressUpdate(Void... values) {}
void createBackupOfVmu(String vmuName){
File backupDir = new File(home_directory+"/VmuBackups/");
if(!backupDir.exists()) {
backupDir.mkdirs();
}
File source = new File(home_directory+"/"+vmuName);
File destination = new File(home_directory+"/VmuBackups/"+vmuName);
if(!destination.exists()) {
try {
destination.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
InputStream in = new FileInputStream(source);
OutputStream out = new FileOutputStream(destination);
byte[] buffer = new byte[1024];
int length;
while ((length = in.read(buffer)) > 0){
out.write(buffer, 0, length);
}
in.close();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -24,7 +24,8 @@ public class Emulator extends Application {
public static final String pref_frameskip = "frame_skip";
public static final String pref_pvrrender = "pvr_render";
public static final String pref_syncedrender = "synced_render";
public static final String pref_cheatdisk = "cheat_disk";
public static final String pref_modvols = "modifier_volumes";
public static final String pref_bootdisk = "boot_disk";
public static final String pref_usereios = "use_reios";
public static boolean dynarecopt = true;
@ -42,7 +43,8 @@ public class Emulator extends Application {
public static int frameskip = 0;
public static boolean pvrrender = false;
public static boolean syncedrender = false;
public static String cheatdisk = "null";
public static boolean modvols = true;
public static String bootdisk = "null";
public static boolean usereios = false;
public static boolean nativeact = false;
@ -63,7 +65,8 @@ public class Emulator extends Application {
Emulator.frameskip = mPrefs.getInt(pref_frameskip, frameskip);
Emulator.pvrrender = mPrefs.getBoolean(pref_pvrrender, pvrrender);
Emulator.syncedrender = mPrefs.getBoolean(pref_syncedrender, syncedrender);
Emulator.cheatdisk = mPrefs.getString(pref_cheatdisk, cheatdisk);
Emulator.modvols = mPrefs.getBoolean(pref_modvols, modvols);
Emulator.bootdisk = mPrefs.getString(pref_bootdisk, bootdisk);
Emulator.usereios = mPrefs.getBoolean(pref_usereios, usereios);
Emulator.nativeact = mPrefs.getBoolean(pref_nativeact, nativeact);
}
@ -88,8 +91,9 @@ public class Emulator extends Application {
JNIdc.frameskip(Emulator.frameskip);
JNIdc.pvrrender(Emulator.pvrrender ? 1 : 0);
JNIdc.syncedrender(Emulator.syncedrender ? 1 : 0);
JNIdc.modvols(Emulator.modvols ? 1 : 0);
JNIdc.usereios(Emulator.usereios ? 1 : 0);
JNIdc.cheatdisk(Emulator.cheatdisk);
JNIdc.bootdisk(Emulator.bootdisk);
JNIdc.dreamtime(DreamTime.getDreamtime());
}

View File

@ -172,13 +172,12 @@ public class FileBrowser extends Fragment {
* findViewById(R.id.about).setOnTouchListener(viblist);
*/
File home = new File(mPrefs.getString(Config.pref_home, home_directory));
if (!home.exists() || !home.isDirectory()) {
String temp = mPrefs.getString(Config.pref_home, null);
if (temp == null || !new File(temp).isDirectory()) {
showToastMessage(getActivity().getString(R.string.config_home), Snackbar.LENGTH_LONG);
} else {
(new installGraphics()).execute();
installButtons();
}
if (!ImgBrowse && !games) {
new LocateGames(R.array.flash).execute(home_directory);
} else {
@ -186,47 +185,37 @@ public class FileBrowser extends Fragment {
}
}
private class installGraphics extends AsyncTask<String, Integer, String> {
@Override
protected String doInBackground(String... params) {
try {
File buttons = null;
String theme = mPrefs.getString(Config.pref_theme, null);
if (theme != null) {
buttons = new File(theme);
}
File file = new File(home_directory, "data/buttons.png");
if (buttons != null && buttons.exists()) {
InputStream in = new FileInputStream(buttons);
OutputStream out = new FileOutputStream(file);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
} else if (!file.exists()) {
org.apache.commons.io.FileUtils.touch(file);
InputStream png = getActivity().getAssets().open("buttons.png");
OutputStream fo = new FileOutputStream(file);
byte[] buffer = new byte[4096];
int read;
while ((read = png.read(buffer)) != -1) {
fo.write(buffer, 0, read);
}
png.close();
fo.flush();
fo.close();
}
} catch (FileNotFoundException fnf) {
fnf.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
private void installButtons() {
try {
File buttons = null;
String theme = mPrefs.getString(Config.pref_theme, null);
if (theme != null) {
buttons = new File(theme);
}
return null;
File file = new File(home_directory, "data/buttons.png");
InputStream in = null;
if (buttons != null && buttons.exists()) {
in = new FileInputStream(buttons);
} else if (!file.exists() || file.length() == 0) {
in = getActivity().getAssets().open("buttons.png");
}
if (in != null) {
OutputStream out = new FileOutputStream(file);
// Transfer bytes from in to out
byte[] buf = new byte[4096];
int len;
while ((len = in.read(buf)) != -1) {
out.write(buf, 0, len);
}
in.close();
out.flush();
out.close();
}
} catch (FileNotFoundException fnf) {
fnf.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}

View File

@ -0,0 +1,585 @@
package com.reicast.emulator;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Gravity;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.widget.PopupWindow;
import com.reicast.emulator.config.Config;
import com.reicast.emulator.emu.GL2JNIView;
import com.reicast.emulator.emu.JNIdc;
import com.reicast.emulator.emu.OnScreenMenu;
import com.reicast.emulator.emu.OnScreenMenu.FpsPopup;
import com.reicast.emulator.emu.OnScreenMenu.MainPopup;
import com.reicast.emulator.emu.OnScreenMenu.VmuPopup;
import com.reicast.emulator.periph.Gamepad;
import com.reicast.emulator.periph.MOGAInput;
import com.reicast.emulator.periph.SipEmulator;
import java.util.Arrays;
import java.util.HashMap;
import tv.ouya.console.api.OuyaController;
public class GL2JNIActivity extends Activity {
public GL2JNIView mView;
OnScreenMenu menu;
public MainPopup popUp;
VmuPopup vmuPop;
FpsPopup fpsPop;
MOGAInput moga = new MOGAInput();
private SharedPreferences prefs;
private Gamepad pad = new Gamepad();
public static byte[] syms;
@Override
protected void onCreate(Bundle icicle) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
prefs = PreferenceManager.getDefaultSharedPreferences(this);
if (prefs.getInt(Config.pref_rendertype, 2) == 2) {
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
}
Emulator app = (Emulator)getApplicationContext();
app.getConfigurationPrefs(prefs);
menu = new OnScreenMenu(GL2JNIActivity.this, prefs);
pad.isOuyaOrTV = pad.IsOuyaOrTV(GL2JNIActivity.this);
// pad.isNvidiaShield = pad.IsNvidiaShield();
/*
* try { //int rID =
* getResources().getIdentifier("fortyonepost.com.lfas:raw/syms.map",
* null, null); //get the file as a stream InputStream is =
* getResources().openRawResource(R.raw.syms);
*
* syms = new byte[(int) is.available()]; is.read(syms); is.close(); }
* catch (IOException e) { e.getMessage(); e.printStackTrace(); }
*/
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
pad.compat[0] = true;
pad.compat[1] = true;
pad.compat[2] = true;
pad.compat[3] = true;
}
String fileName = null;
// Call parent onCreate()
super.onCreate(icicle);
OuyaController.init(this);
// Populate device descriptor-to-player-map from preferences
pad.deviceDescriptor_PlayerNum.put(
prefs.getString(Gamepad.pref_player1, null), 0);
pad.deviceDescriptor_PlayerNum.put(
prefs.getString(Gamepad.pref_player2, null), 1);
pad.deviceDescriptor_PlayerNum.put(
prefs.getString(Gamepad.pref_player3, null), 2);
pad.deviceDescriptor_PlayerNum.put(
prefs.getString(Gamepad.pref_player4, null), 3);
pad.deviceDescriptor_PlayerNum.remove(null);
moga.onCreate(this, pad);
moga.mListener.setPlayerNum(1);
boolean controllerTwoConnected = false;
boolean controllerThreeConnected = false;
boolean controllerFourConnected = false;
for (HashMap.Entry<String, Integer> e : pad.deviceDescriptor_PlayerNum.entrySet()) {
String descriptor = e.getKey();
Integer playerNum = e.getValue();
switch (playerNum) {
case 1:
if (descriptor != null)
controllerTwoConnected = true;
break;
case 2:
if (descriptor != null)
controllerThreeConnected = true;
break;
case 3:
if (descriptor != null)
controllerFourConnected = true;
break;
}
}
JNIdc.initControllers(new boolean[] { controllerTwoConnected,
controllerThreeConnected, controllerFourConnected });
int joys[] = InputDevice.getDeviceIds();
for (int joy: joys) {
String descriptor = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
descriptor = InputDevice.getDevice(joy).getDescriptor();
} else {
descriptor = InputDevice.getDevice(joy).getName();
}
Log.d("reicast", "InputDevice ID: " + joy);
Log.d("reicast",
"InputDevice Name: "
+ InputDevice.getDevice(joy).getName());
Log.d("reicast", "InputDevice Descriptor: " + descriptor);
pad.deviceId_deviceDescriptor.put(joy, descriptor);
}
for (int joy :joys) {
Integer playerNum = pad.deviceDescriptor_PlayerNum
.get(pad.deviceId_deviceDescriptor.get(joy));
if (playerNum != null) {
String id = pad.portId[playerNum];
pad.custom[playerNum] = prefs.getBoolean(Gamepad.pref_js_modified + id, false);
pad.compat[playerNum] = prefs.getBoolean(Gamepad.pref_js_compat + id, false);
pad.joystick[playerNum] = prefs.getBoolean(Gamepad.pref_js_merged + id, false);
if (InputDevice.getDevice(joy).getName()
.contains(Gamepad.controllers_gamekey)) {
if (pad.custom[playerNum]) {
pad.setCustomMapping(id, playerNum, prefs);
} else {
pad.map[playerNum] = pad.getConsoleController();
}
} else if (!pad.compat[playerNum]) {
if (pad.custom[playerNum]) {
pad.setCustomMapping(id, playerNum, prefs);
} else if (InputDevice.getDevice(joy).getName()
.equals(Gamepad.controllers_sony)) {
pad.map[playerNum] = pad.getConsoleController();
} else if (InputDevice.getDevice(joy).getName()
.equals(Gamepad.controllers_xbox)) {
pad.map[playerNum] = pad.getConsoleController();
} else if (InputDevice.getDevice(joy).getName()
.contains(Gamepad.controllers_shield)) {
pad.map[playerNum] = pad.getConsoleController();
} else if (!pad.isActiveMoga[playerNum]) { // Ouya controller
pad.map[playerNum] = pad.getOUYAController();
}
} else {
pad.getCompatibilityMap(playerNum, id, prefs);
}
pad.initJoyStickLayout(playerNum);
} else {
pad.runCompatibilityMode(joy, prefs);
}
}
if (joys.length == 0) {
pad.fullCompatibilityMode(prefs);
}
app.loadConfigurationPrefs();
// When viewing a resource, pass its URI to the native code for opening
if (getIntent().getAction().equals("com.reicast.EMULATOR"))
fileName = Uri.decode(getIntent().getData().toString());
// Create the actual GLES view
mView = new GL2JNIView(GL2JNIActivity.this, fileName, false,
prefs.getInt(Config.pref_renderdepth, 24), 8, false);
setContentView(mView);
//setup mic
boolean micPluggedIn = prefs.getBoolean(Config.pref_mic, false);
if(micPluggedIn){
SipEmulator sip = new SipEmulator();
sip.startRecording();
JNIdc.setupMic(sip);
}
popUp = menu.new MainPopup(this);
vmuPop = menu.new VmuPopup(this);
if(prefs.getBoolean(Config.pref_vmu, false)){
//kind of a hack - if the user last had the vmu on screen
//inverse it and then "toggle"
prefs.edit().putBoolean(Config.pref_vmu, false).apply();
//can only display a popup after onCreate
mView.post(new Runnable() {
public void run() {
toggleVmu();
}
});
}
JNIdc.setupVmu(menu.getVmu());
if (prefs.getBoolean(Config.pref_showfps, false)) {
fpsPop = menu.new FpsPopup(this);
mView.setFpsDisplay(fpsPop);
mView.post(new Runnable() {
public void run() {
displayFPS();
}
});
}
}
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
Integer playerNum = Arrays.asList(pad.name).indexOf(event.getDeviceId());
if (playerNum == -1) {
playerNum = pad.deviceDescriptor_PlayerNum
.get(pad.deviceId_deviceDescriptor.get(event.getDeviceId()));
} else {
playerNum = -1;
}
if (playerNum == null || playerNum == -1)
return false;
if (!pad.compat[playerNum]) {
// Joystick
if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
// do other things with joystick
float LS_X = event.getAxisValue(OuyaController.AXIS_LS_X);
float LS_Y = event.getAxisValue(OuyaController.AXIS_LS_Y);
float RS_X = event.getAxisValue(OuyaController.AXIS_RS_X);
float RS_Y = event.getAxisValue(OuyaController.AXIS_RS_Y);
float L2 = event.getAxisValue(OuyaController.AXIS_L2);
float R2 = event.getAxisValue(OuyaController.AXIS_R2);
if (!pad.joystick[playerNum]) {
pad.previousLS_X[playerNum] = pad.globalLS_X[playerNum];
pad.previousLS_Y[playerNum] = pad.globalLS_Y[playerNum];
pad.globalLS_X[playerNum] = LS_X;
pad.globalLS_Y[playerNum] = LS_Y;
}
GL2JNIView.jx[playerNum] = (int) (LS_X * 126);
GL2JNIView.jy[playerNum] = (int) (LS_Y * 126);
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
if (prefs.getBoolean(Gamepad.pref_js_rbuttons + pad.portId[playerNum], true)) {
if (RS_Y > 0.25) {
handle_key(playerNum, pad.map[playerNum][0]/* A */, true);
pad.wasKeyStick[playerNum] = true;
} else if (RS_Y < 0.25) {
handle_key(playerNum, pad.map[playerNum][1]/* B */, true);
pad.wasKeyStick[playerNum] = true;
} else if (pad.wasKeyStick[playerNum]){
handle_key(playerNum, pad.map[playerNum][0], false);
handle_key(playerNum, pad.map[playerNum][1], false);
pad.wasKeyStick[playerNum] = false;
}
} else {
if (RS_Y > 0.25) {
GL2JNIView.rt[playerNum] = (int) (RS_Y * 255);
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
} else if (RS_Y < 0.25) {
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
GL2JNIView.lt[playerNum] = (int) (-(RS_Y) * 255);
}
}
}
}
mView.pushInput();
// Only handle Left Stick on an Xbox 360 controller if there was
// some actual motion on the stick,
// so otherwise the event can be handled as a DPAD event
return (pad.joystick[playerNum] || (!(pad.globalLS_X[playerNum] == pad.previousLS_X[playerNum])
|| !(pad.globalLS_Y[playerNum] == pad.previousLS_Y[playerNum])))
&& (!(pad.previousLS_X[playerNum] == 0.0f) || !(pad.previousLS_Y[playerNum] == 0.0f));
}
public boolean motionEventHandler(Integer playerNum, com.bda.controller.MotionEvent event) {
if (playerNum == null || playerNum == -1)
return false;
if (!pad.compat[playerNum]) {
// do other things with joystick
float LS_X = event.getAxisValue(OuyaController.AXIS_LS_X);
float LS_Y = event.getAxisValue(OuyaController.AXIS_LS_Y);
float RS_X = event.getAxisValue(OuyaController.AXIS_RS_X);
float RS_Y = event.getAxisValue(OuyaController.AXIS_RS_Y);
float L2 = event.getAxisValue(OuyaController.AXIS_L2);
float R2 = event.getAxisValue(OuyaController.AXIS_R2);
if (!pad.joystick[playerNum]) {
pad.previousLS_X[playerNum] = pad.globalLS_X[playerNum];
pad.previousLS_Y[playerNum] = pad.globalLS_Y[playerNum];
pad.globalLS_X[playerNum] = LS_X;
pad.globalLS_Y[playerNum] = LS_Y;
}
GL2JNIView.jx[playerNum] = (int) (LS_X * 126);
GL2JNIView.jy[playerNum] = (int) (LS_Y * 126);
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
if (prefs.getBoolean(Gamepad.pref_js_rbuttons + pad.portId[playerNum], true)) {
if (RS_Y > 0.25) {
handle_key(playerNum, pad.map[playerNum][0]/* A */, true);
pad.wasKeyStick[playerNum] = true;
} else if (RS_Y < 0.25) {
handle_key(playerNum, pad.map[playerNum][1]/* B */, true);
pad.wasKeyStick[playerNum] = true;
} else if (pad.wasKeyStick[playerNum]){
handle_key(playerNum, pad.map[playerNum][0], false);
handle_key(playerNum, pad.map[playerNum][1], false);
pad.wasKeyStick[playerNum] = false;
}
} else {
if (RS_Y > 0.25) {
GL2JNIView.rt[playerNum] = (int) (RS_Y * 255);
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
} else if (RS_Y < 0.25) {
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
GL2JNIView.lt[playerNum] = (int) (-(RS_Y) * 255);
}
}
}
mView.pushInput();
// Only handle Left Stick on an Xbox 360 controller if there was
// some actual motion on the stick,
// so otherwise the event can be handled as a DPAD event
return (pad.joystick[playerNum] || (!(pad.globalLS_X[playerNum] == pad.previousLS_X[playerNum])
|| !(pad.globalLS_Y[playerNum] == pad.previousLS_Y[playerNum])))
&& (!(pad.previousLS_X[playerNum] == 0.0f) || !(pad.previousLS_Y[playerNum] == 0.0f));
}
public boolean simulatedTouchEvent(int playerNum, float L2, float R2) {
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
mView.pushInput();
return true;
}
public boolean handle_key(Integer playerNum, int kc, boolean down) {
if (playerNum == null || playerNum == -1)
return false;
if (kc == pad.getSelectButtonCode()) {
return false;
}
boolean rav = false;
for (int i = 0; i < pad.map[playerNum].length; i += 2) {
if (pad.map[playerNum][i + 0] == kc) {
if (down)
GL2JNIView.kcode_raw[playerNum] &= ~pad.map[playerNum][i + 1];
else
GL2JNIView.kcode_raw[playerNum] |= pad.map[playerNum][i + 1];
rav = true;
break;
}
}
mView.pushInput();
return rav;
}
public void displayPopUp(PopupWindow popUp) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
popUp.showAtLocation(mView, Gravity.BOTTOM, 0, 60);
} else {
popUp.showAtLocation(mView, Gravity.BOTTOM, 0, 0);
}
popUp.update(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
}
public void displayDebug(PopupWindow popUpDebug) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
popUpDebug.showAtLocation(mView, Gravity.BOTTOM, 0, 60);
} else {
popUpDebug.showAtLocation(mView, Gravity.BOTTOM, 0, 0);
}
popUpDebug.update(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
}
public void displayFPS() {
fpsPop.showAtLocation(mView, Gravity.TOP | Gravity.LEFT, 20, 20);
fpsPop.update(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}
public void toggleVmu() {
boolean showFloating = !prefs.getBoolean(Config.pref_vmu, false);
if (showFloating) {
if (popUp.isShowing()) {
popUp.dismiss();
}
//remove from popup menu
popUp.hideVmu();
//add to floating window
vmuPop.showVmu();
vmuPop.showAtLocation(mView, Gravity.TOP | Gravity.RIGHT, 4, 4);
vmuPop.update(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
} else {
vmuPop.dismiss();
//remove from floating window
vmuPop.hideVmu();
//add back to popup menu
popUp.showVmu();
}
prefs.edit().putBoolean(Config.pref_vmu, showFloating).apply();
}
public void displayConfig(PopupWindow popUpConfig) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
popUpConfig.showAtLocation(mView, Gravity.BOTTOM, 0, 60);
} else {
popUpConfig.showAtLocation(mView, Gravity.BOTTOM, 0, 0);
}
popUpConfig.update(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
}
public boolean onKeyUp(int keyCode, KeyEvent event) {
Integer playerNum = Arrays.asList(pad.name).indexOf(event.getDeviceId());
if (playerNum == -1) {
playerNum = pad.deviceDescriptor_PlayerNum
.get(pad.deviceId_deviceDescriptor.get(event.getDeviceId()));
} else {
playerNum = -1;
}
if (playerNum != null && playerNum != -1) {
if (pad.compat[playerNum] || pad.custom[playerNum]) {
String id = pad.portId[playerNum];
if (keyCode == prefs.getInt(Gamepad.pref_button_l + id,
KeyEvent.KEYCODE_BUTTON_L1)
|| keyCode == prefs.getInt(Gamepad.pref_button_r + id,
KeyEvent.KEYCODE_BUTTON_R1)) {
return simulatedTouchEvent(playerNum, 0.0f, 0.0f);
}
}
}
return handle_key(playerNum, keyCode, false)
|| super.onKeyUp(keyCode, event);
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
Integer playerNum = Arrays.asList(pad.name).indexOf(event.getDeviceId());
if (playerNum == -1) {
playerNum = pad.deviceDescriptor_PlayerNum
.get(pad.deviceId_deviceDescriptor.get(event.getDeviceId()));
} else {
playerNum = -1;
}
if (playerNum != null && playerNum != -1) {
if (pad.compat[playerNum] || pad.custom[playerNum]) {
String id = pad.portId[playerNum];
if (keyCode == prefs.getInt(Gamepad.pref_button_l + id, KeyEvent.KEYCODE_BUTTON_L1)) {
return simulatedTouchEvent(playerNum, 1.0f, 0.0f);
}
if (keyCode == prefs.getInt(Gamepad.pref_button_r + id, KeyEvent.KEYCODE_BUTTON_R1)) {
return simulatedTouchEvent(playerNum, 0.0f, 1.0f);
}
}
}
if (handle_key(playerNum, keyCode, true)) {
if (playerNum == 0)
JNIdc.hide_osd();
return true;
}
if (keyCode == pad.getSelectButtonCode()) {
return showMenu();
}
if (ViewConfiguration.get(this).hasPermanentMenuKey()) {
if (keyCode == KeyEvent.KEYCODE_MENU) {
return showMenu();
}
}
if (keyCode == KeyEvent.KEYCODE_BACK) {
return showMenu();
}
return super.onKeyDown(keyCode, event);
}
public GL2JNIView getGameView() {
return mView;
}
public void screenGrab() {
mView.screenGrab();
}
private boolean showMenu() {
if (popUp != null) {
if (!menu.dismissPopUps()) {
if (!popUp.isShowing()) {
displayPopUp(popUp);
} else {
popUp.dismiss();
}
} else {
popUp.dismiss();
}
}
return true;
}
public boolean serviceRunning(Class<?> javaclass) {
ActivityManager manager = (ActivityManager)
getSystemService(Context.ACTIVITY_SERVICE);
try {
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (javaclass.getName().equals(
service.service.getClassName())) {
return true;
}
}
} catch (NullPointerException e) {
e.printStackTrace();
}
return false;
}
@Override
protected void onPause() {
super.onPause();
mView.onPause();
JNIdc.pause();
moga.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
mView.onDestroy();
JNIdc.destroy();
moga.onDestroy();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
@Override
protected void onResume() {
super.onResume();
mView.onResume();
moga.onResume();
}
}

View File

@ -68,13 +68,20 @@ public class GL2JNINative extends NativeActivity {
pad.isOuyaOrTV = pad.IsOuyaOrTV(GL2JNINative.this);
// isNvidiaShield = Gamepad.IsNvidiaShield();
RegisterNative(false);
Emulator app = (Emulator)getApplicationContext();
app.getConfigurationPrefs(prefs);
menu = new OnScreenMenu(GL2JNINative.this, prefs);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
pad.compat[0] = true;
pad.compat[1] = true;
pad.compat[2] = true;
pad.compat[3] = true;
}
String fileName = null;
// Call parent onCreate()
@ -105,18 +112,18 @@ public class GL2JNINative extends NativeActivity {
Integer playerNum = e.getValue();
switch (playerNum) {
case 1:
if (descriptor != null)
controllerTwoConnected = true;
break;
case 2:
if (descriptor != null)
controllerThreeConnected = true;
break;
case 3:
if (descriptor != null)
controllerFourConnected = true;
break;
case 1:
if (descriptor != null)
controllerTwoConnected = true;
break;
case 2:
if (descriptor != null)
controllerThreeConnected = true;
break;
case 3:
if (descriptor != null)
controllerFourConnected = true;
break;
}
}
@ -197,7 +204,7 @@ public class GL2JNINative extends NativeActivity {
sip.startRecording();
JNIdc.setupMic(sip);
}
popUp = menu.new MainPopup(this);
vmuPop = menu.new VmuPopup(this);
if(prefs.getBoolean(Config.pref_vmu, false)){
@ -222,14 +229,14 @@ public class GL2JNINative extends NativeActivity {
});
}
}
public boolean simulatedTouchEvent(int playerNum, float L2, float R2) {
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
mView.pushInput();
return true;
}
public void displayPopUp(PopupWindow popUp) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
popUp.showAtLocation(mView, Gravity.BOTTOM, 0, 60);
@ -239,7 +246,7 @@ public class GL2JNINative extends NativeActivity {
popUp.update(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
}
public void displayDebug(PopupWindow popUpDebug) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
popUpDebug.showAtLocation(mView, Gravity.BOTTOM, 0, 60);
@ -276,7 +283,7 @@ public class GL2JNINative extends NativeActivity {
}
prefs.edit().putBoolean(Config.pref_vmu, showFloating).apply();
}
public void displayConfig(PopupWindow popUpConfig) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
popUpConfig.showAtLocation(mView, Gravity.BOTTOM, 0, 60);
@ -286,7 +293,7 @@ public class GL2JNINative extends NativeActivity {
popUpConfig.update(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
}
public boolean motionEventHandler(Integer playerNum, com.bda.controller.MotionEvent event) {
if (playerNum == null || playerNum == -1)
return false;
@ -385,7 +392,7 @@ public class GL2JNINative extends NativeActivity {
GL2JNIView.jx[playerNum] = (int) (LS_X * 126);
GL2JNIView.jy[playerNum] = (int) (LS_Y * 126);
GL2JNIView.lt[playerNum] = (int) (L2 * 255);
GL2JNIView.rt[playerNum] = (int) (R2 * 255);
@ -493,7 +500,7 @@ public class GL2JNINative extends NativeActivity {
if (keyCode == prefs.getInt(Gamepad.pref_button_l + id,
KeyEvent.KEYCODE_BUTTON_L1)
|| keyCode == prefs.getInt(Gamepad.pref_button_r + id,
KeyEvent.KEYCODE_BUTTON_R1)) {
KeyEvent.KEYCODE_BUTTON_R1)) {
return simulatedTouchEvent(playerNum, 0.0f, 0.0f);
} else {
return handle_key(playerNum, keyCode, false);
@ -503,10 +510,10 @@ public class GL2JNINative extends NativeActivity {
return false;
}
// public boolean OnNativeMotion(int device, int source, int action, int x,
// public boolean OnNativeMotion(int device, int source, int action, int x,
// int y, boolean newEvent) {
public boolean OnNativeMotion(int device, int source, int action, int x,
int y) {
int y) {
Integer playerNum = pad.playerNumX.get(device);
if (playerNum != null && playerNum != -1) {
Log.d("reicast", playerNum + " - " + device + ": " + source);
@ -547,7 +554,7 @@ public class GL2JNINative extends NativeActivity {
public void screenGrab() {
mView.screenGrab();
}
private boolean showMenu() {
if (popUp != null) {
if (!menu.dismissPopUps()) {
@ -567,22 +574,18 @@ public class GL2JNINative extends NativeActivity {
protected void onPause() {
super.onPause();
mView.onPause();
JNIdc.pause();
moga.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
mView.onDestroy();
JNIdc.destroy();
moga.onDestroy();
}
@Override
protected void onStop() {
JNIdc.stop();
mView.onStop();
super.onStop();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);

View File

@ -2,14 +2,12 @@ package com.reicast.emulator;
import android.Manifest;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@ -20,6 +18,8 @@ import android.support.design.widget.NavigationView;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
@ -52,7 +52,7 @@ public class MainActivity extends AppCompatActivity implements
private SharedPreferences mPrefs;
private boolean hasAndroidMarket = false;
private UncaughtExceptionHandler mUEHandler;
Gamepad pad = new Gamepad();
@ -61,7 +61,7 @@ public class MainActivity extends AppCompatActivity implements
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getWindow().getDecorView().setOnSystemUiVisibilityChangeListener (new OnSystemUiVisibilityChangeListener() {
public void onSystemUiVisibilityChange(int visibility) {
@ -69,16 +69,16 @@ public class MainActivity extends AppCompatActivity implements
getWindow().getDecorView().setSystemUiVisibility(
// View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
});
} else {
getWindow().setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
@ -130,15 +130,15 @@ public class MainActivity extends AppCompatActivity implements
onGameSelected(Uri.parse(intent.getData().toString()));
// Flush the intent to prevent multiple calls
getIntent().setData(null);
setIntent(null);
Config.externalIntent = true;
setIntent(null);
Config.externalIntent = true;
}
}
// Check that the activity is using the layout version with
// the fragment_container FrameLayout
if (findViewById(R.id.fragment_container) != null) {
onMainBrowseSelected(true, null, false, null);
onMainBrowseSelected(true, null, false, null);
}
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
@ -160,10 +160,10 @@ public class MainActivity extends AppCompatActivity implements
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
if (!hasAndroidMarket) {
if (!hasAndroidMarket) {
navigationView.getMenu().findItem(R.id.rateme_menu).setEnabled(false);
navigationView.getMenu().findItem(R.id.rateme_menu).setVisible(false);
}
}
navigationView.setNavigationItemSelectedListener(this);
final SearchView searchView = (SearchView) findViewById(R.id.searchView);
@ -172,9 +172,9 @@ public class MainActivity extends AppCompatActivity implements
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
onMainBrowseSelected(true, mPrefs.getString(Config.pref_games,
Environment.getExternalStorageDirectory().getAbsolutePath()),
true, query);
onMainBrowseSelected(true, mPrefs.getString(Config.pref_games,
Environment.getExternalStorageDirectory().getAbsolutePath()),
true, query);
searchView.onActionViewCollapsed();
return false;
}
@ -192,7 +192,7 @@ public class MainActivity extends AppCompatActivity implements
/**
* Display a dialog to notify the user of prior crash
*
*
* @param error
* A generalized summary of the crash cause
*/
@ -216,13 +216,13 @@ public class MainActivity extends AppCompatActivity implements
builder.show();
}
public static boolean isBiosExisting(String home_directory) {
return new File (home_directory, "data/dc_boot.bin").exists();
}
public static boolean isBiosExisting(String home_directory) {
return new File (home_directory, "data/dc_boot.bin").exists();
}
public static boolean isFlashExisting(String home_directory) {
public static boolean isFlashExisting(String home_directory) {
return new File (home_directory, "data/dc_flash.bin").exists();
}
}
public void onGameSelected(Uri uri) {
if (Config.readOutput("uname -a").equals(getString(R.string.error_kernel))) {
@ -231,37 +231,37 @@ public class MainActivity extends AppCompatActivity implements
String home_directory = mPrefs.getString(Config.pref_home,
Environment.getExternalStorageDirectory().getAbsolutePath());
if (!isBiosExisting(home_directory)) {
launchBIOSdetection();
return;
}
if (!isBiosExisting(home_directory)) {
launchBIOSdetection();
return;
}
if (!isFlashExisting(home_directory)) {
launchBIOSdetection();
return;
}
launchBIOSdetection();
return;
}
JNIdc.config(home_directory);
Emulator.nativeact = PreferenceManager.getDefaultSharedPreferences(
getApplicationContext()).getBoolean(Emulator.pref_nativeact, Emulator.nativeact);
if (Emulator.nativeact) {
startActivity(new Intent("com.reicast.EMULATOR", uri, getApplicationContext(),
GL2JNINative.class));
} else {
startActivity(new Intent("com.reicast.EMULATOR", uri, getApplicationContext(),
GL2JNIActivity.class));
}
Emulator.nativeact = PreferenceManager.getDefaultSharedPreferences(
getApplicationContext()).getBoolean(Emulator.pref_nativeact, Emulator.nativeact);
if (Emulator.nativeact) {
startActivity(new Intent("com.reicast.EMULATOR", uri, getApplicationContext(),
GL2JNINative.class));
} else {
startActivity(new Intent("com.reicast.EMULATOR", uri, getApplicationContext(),
GL2JNIActivity.class));
}
}
private void launchBIOSdetection() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.bios_selection);
builder.setPositiveButton(R.string.browse,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
onMainBrowseSelected(false,
Environment.getExternalStorageDirectory().getAbsolutePath(),
false, null);
String home_directory = mPrefs.getString(Config.pref_home,
Environment.getExternalStorageDirectory().getAbsolutePath());
onMainBrowseSelected(false, home_directory, false, null);
}
});
builder.setNegativeButton(R.string.gdrive,
@ -292,29 +292,29 @@ public class MainActivity extends AppCompatActivity implements
return;
}
/**
* Launch the browser activity with specified parameters
*
* @param browse
* Conditional for image files or folders
* @param path
* The root path of the browser fragment
* @param games
* Conditional for viewing games or BIOS
* @param query
* Search parameters to limit list items
*/
/**
* Launch the browser activity with specified parameters
*
* @param browse
* Conditional for image files or folders
* @param path
* The root path of the browser fragment
* @param games
* Conditional for viewing games or BIOS
* @param query
* Search parameters to limit list items
*/
public void onMainBrowseSelected(boolean browse, String path, boolean games, String query) {
FileBrowser firstFragment = new FileBrowser();
Bundle args = new Bundle();
// args.putBoolean("ImgBrowse", false);
args.putBoolean("ImgBrowse", browse);
args.putBoolean("ImgBrowse", browse);
// specify ImgBrowse option. true = images, false = folders only
args.putString("browse_entry", path);
// specify a path for selecting folder options
args.putBoolean("games_entry", games);
// specify if the desired path is for games or data
args.putString("search_params", query);
args.putString("search_params", query);
firstFragment.setArguments(args);
// In case this activity was started with special instructions from
@ -326,7 +326,7 @@ public class MainActivity extends AppCompatActivity implements
.beginTransaction()
.replace(R.id.fragment_container, firstFragment, "MAIN_BROWSER")
.addToBackStack(null).commit();
setTitle(R.string.browser);
setTitle(R.string.browser);
}
@Override
@ -360,11 +360,20 @@ public class MainActivity extends AppCompatActivity implements
return super.onKeyDown(keyCode, event);
}
private void launchMainFragment() {
onMainBrowseSelected(true, null, false, null);
onMainBrowseSelected(true, null, false, null);
}
public void onSettingsReload(Fragment options) {
getSupportFragmentManager().beginTransaction().remove(options).commit();
OptionsFragment optionsFrag = new OptionsFragment();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, optionsFrag, "OPTIONS_FRAG")
.addToBackStack(null).commit();
}
@Override
protected void onPause() {
super.onPause();
@ -399,14 +408,14 @@ public class MainActivity extends AppCompatActivity implements
fragment.moga.onResume();
}
}
CloudFragment cloudfragment = (CloudFragment) getSupportFragmentManager()
.findFragmentByTag("CLOUD_FRAG");
if (cloudfragment != null && cloudfragment.isVisible()) {
cloudfragment.onResume();
}
}
@Override
public void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
@ -439,9 +448,8 @@ public class MainActivity extends AppCompatActivity implements
browseFrag.setArguments(args);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, browseFrag,
"MAIN_BROWSER").addToBackStack(null)
.commit();
.replace(R.id.fragment_container, browseFrag, "MAIN_BROWSER")
.addToBackStack(null).commit();
setTitle(R.string.browser);
drawer.closeDrawer(GravityCompat.START);
return true;
@ -458,8 +466,7 @@ public class MainActivity extends AppCompatActivity implements
optionsFrag = new OptionsFragment();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container,
optionsFrag, "OPTIONS_FRAG")
.replace(R.id.fragment_container, optionsFrag, "OPTIONS_FRAG")
.addToBackStack(null).commit();
setTitle(R.string.settings);
drawer.closeDrawer(GravityCompat.START);
@ -477,8 +484,8 @@ public class MainActivity extends AppCompatActivity implements
inputFrag = new InputFragment();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, inputFrag,
"INPUT_FRAG").addToBackStack(null).commit();
.replace(R.id.fragment_container, inputFrag, "INPUT_FRAG")
.addToBackStack(null).commit();
setTitle(R.string.input);
drawer.closeDrawer(GravityCompat.START);
return true;
@ -495,8 +502,8 @@ public class MainActivity extends AppCompatActivity implements
aboutFrag = new AboutFragment();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, aboutFrag,
"ABOUT_FRAG").addToBackStack(null).commit();
.replace(R.id.fragment_container, aboutFrag, "ABOUT_FRAG")
.addToBackStack(null).commit();
setTitle(R.string.about);
drawer.closeDrawer(GravityCompat.START);
return true;
@ -513,8 +520,7 @@ public class MainActivity extends AppCompatActivity implements
cloudFrag = new CloudFragment();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container,
cloudFrag, "CLOUD_FRAG")
.replace(R.id.fragment_container, cloudFrag, "CLOUD_FRAG")
.addToBackStack(null).commit();
setTitle(R.string.cloud);
drawer.closeDrawer(GravityCompat.START);
@ -522,8 +528,8 @@ public class MainActivity extends AppCompatActivity implements
case R.id.rateme_menu:
// vib.vibrate(50);
startActivity(new Intent(Intent.ACTION_VIEW, Uri
.parse("market://details?id=" + getPackageName())));
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse("market://details?id=" + getPackageName())));
//setTitle(R.string.rateme);
drawer.closeDrawer(GravityCompat.START);
return true;
@ -546,11 +552,11 @@ public class MainActivity extends AppCompatActivity implements
if (hasFocus && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
public boolean isCallable(Intent intent) {

View File

@ -79,7 +79,7 @@ public class XMLParser extends AsyncTask<String, Integer, String> {
this.childview = childview;
this.mCallback = mCallback;
}
public void setGameID(String id) {
this.gameId = id;
initializeDefaults();
@ -157,7 +157,7 @@ public class XMLParser extends AsyncTask<String, Integer, String> {
}
}
} catch (Exception e) {
}
}
@ -168,7 +168,7 @@ public class XMLParser extends AsyncTask<String, Integer, String> {
} else {
((ImageView) childview.findViewById(R.id.item_icon)).setImageBitmap(coverart);
}
if (mPrefs.getBoolean(Config.pref_gamedetails, false)) {
childview.findViewById(R.id.childview).setOnLongClickListener(
new OnLongClickListener() {
@ -202,7 +202,7 @@ public class XMLParser extends AsyncTask<String, Integer, String> {
childview.setTag(game_name);
}
private void initializeDefaults() {
game_details = mContext.getString(R.string.info_unavailable);
final String nameLower = game.getName().toLowerCase(
@ -218,7 +218,7 @@ public class XMLParser extends AsyncTask<String, Integer, String> {
public boolean isNetworkAvailable() {
ConnectivityManager connectivityManager = (ConnectivityManager) mContext
.getSystemService(Context.CONNECTIVITY_SERVICE);
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mWifi = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
NetworkInfo mMobile = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
@ -232,7 +232,7 @@ public class XMLParser extends AsyncTask<String, Integer, String> {
public Drawable getGameIcon() {
return game_icon;
}
public Bitmap getGameCover() {
return coverart;
}
@ -240,7 +240,7 @@ public class XMLParser extends AsyncTask<String, Integer, String> {
public String getGameTitle() {
return game_name;
}
public String getGameDetails() {
return game_details;
}

View File

@ -15,7 +15,6 @@ public class Config {
public static final String pref_showfps = "show_fps";
public static final String pref_rendertype = "render_type";
public static final String pref_renderdepth = "depth_render";
public static final String pref_egl14 = "use_egl14";
public static final String pref_touchvibe = "touch_vibration_enabled";
public static final String pref_vibrationDuration = "vibration_duration";
@ -32,7 +31,7 @@ public class Config {
/**
* Read the output of a shell command
*
*
* @param command
* The shell command being issued to the terminal
*/

View File

@ -30,7 +30,7 @@ public class EditVJoyActivity extends Activity {
GL2JNIView mView;
PopupWindow popUp;
LayoutParams params;
private float[][] vjoy_d_cached;
View addbut(int x, OnClickListener ocl) {
@ -46,7 +46,7 @@ public class EditVJoyActivity extends Activity {
@Override
protected void onCreate(Bundle icicle) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
popUp = createVJoyPopup();
// Call parent onCreate()
@ -65,7 +65,7 @@ public class EditVJoyActivity extends Activity {
vjoy_d_cached = VJoy.readCustomVjoyValues(getApplicationContext());
JNIdc.show_osd();
JNIdc.show_osd();
}
@Override
@ -76,17 +76,22 @@ public class EditVJoyActivity extends Activity {
@Override
protected void onStop() {
mView.onStop();
super.onStop();
// mView.onStop();
}
@Override
protected void onResume() {
super.onResume();
mView.onResume();
}
@Override
protected void onDestroy() {
super.onDestroy();
mView.onDestroy();
}
PopupWindow createVJoyPopup() {
final PopupWindow popUp = new PopupWindow(this);
int p = OnScreenMenu.getPixelsFromDp(60, this);
@ -146,7 +151,7 @@ public class EditVJoyActivity extends Activity {
} else
return super.onKeyDown(keyCode, event);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);

View File

@ -59,7 +59,7 @@ public class InputFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.input_fragment, container, false);
}
@ -109,34 +109,34 @@ public class InputFragment extends Fragment {
final SeekBar vibSeek = (SeekBar) getView().findViewById(R.id.vib_seekBar);
if (sharedPreferences.getBoolean(Config.pref_touchvibe, true)) {
vibLay.setVisibility(View.VISIBLE);
vibLay.setVisibility(View.VISIBLE);
} else {
vibLay.setVisibility(View.GONE);
vibLay.setVisibility(View.GONE);
}
duration.setText(String.valueOf(Config.vibrationDuration + " ms"));
vibSeek.setProgress(Config.vibrationDuration);
vibSeek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
duration.setText(String.valueOf(progress + 5 + " ms"));
}
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
duration.setText(String.valueOf(progress + 5 + " ms"));
}
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public void onStopTrackingTouch(SeekBar seekBar) {
int progress = seekBar.getProgress() + 5;
sharedPreferences.edit().putInt(Config.pref_vibrationDuration, progress).apply();
Config.vibrationDuration = progress;
vib.vibrate(progress);
}
public void onStopTrackingTouch(SeekBar seekBar) {
int progress = seekBar.getProgress() + 5;
sharedPreferences.edit().putInt(Config.pref_vibrationDuration, progress).apply();
Config.vibrationDuration = progress;
vib.vibrate(progress);
}
});
OnCheckedChangeListener touch_vibration = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
boolean isChecked) {
sharedPreferences.edit()
.putBoolean(Config.pref_touchvibe, isChecked).apply();
vibLay.setVisibility( isChecked ? View.VISIBLE : View.GONE );
@ -163,7 +163,7 @@ public class InputFragment extends Fragment {
micPluggedIntoFirstController
.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
boolean isChecked) {
sharedPreferences.edit().putBoolean(Config.pref_mic, isChecked).apply();
}
});
@ -406,7 +406,7 @@ public class InputFragment extends Fragment {
});
builder.setOnKeyListener(new Dialog.OnKeyListener() {
public boolean onKey(DialogInterface dialog, int keyCode,
KeyEvent event) {
KeyEvent event) {
return mapDevice(keyCode, event);
}
});
@ -452,20 +452,20 @@ public class InputFragment extends Fragment {
}
switch (listenForButton) {
case 0:
return false;
case 1:
sharedPreferences.edit().putString(Gamepad.pref_player1, descriptor).apply();
break;
case 2:
sharedPreferences.edit().putString(Gamepad.pref_player2, descriptor).apply();
break;
case 3:
sharedPreferences.edit().putString(Gamepad.pref_player3, descriptor).apply();
break;
case 4:
sharedPreferences.edit().putString(Gamepad.pref_player4, descriptor).apply();
break;
case 0:
return false;
case 1:
sharedPreferences.edit().putString(Gamepad.pref_player1, descriptor).apply();
break;
case 2:
sharedPreferences.edit().putString(Gamepad.pref_player2, descriptor).apply();
break;
case 3:
sharedPreferences.edit().putString(Gamepad.pref_player3, descriptor).apply();
break;
case 4:
sharedPreferences.edit().putString(Gamepad.pref_player4, descriptor).apply();
break;
}
Log.d("New port " + listenForButton + " controller:", descriptor);
@ -479,18 +479,18 @@ public class InputFragment extends Fragment {
private void removeController(int playerNum) {
switch (playerNum) {
case 1:
sharedPreferences.edit().putString(Gamepad.pref_player1, null).apply();
break;
case 2:
sharedPreferences.edit().putString(Gamepad.pref_player2, null).apply();
break;
case 3:
sharedPreferences.edit().putString(Gamepad.pref_player3, null).apply();
break;
case 4:
sharedPreferences.edit().putString(Gamepad.pref_player4, null).apply();
break;
case 1:
sharedPreferences.edit().putString(Gamepad.pref_player1, null).apply();
break;
case 2:
sharedPreferences.edit().putString(Gamepad.pref_player2, null).apply();
break;
case 3:
sharedPreferences.edit().putString(Gamepad.pref_player3, null).apply();
break;
case 4:
sharedPreferences.edit().putString(Gamepad.pref_player4, null).apply();
break;
}
updateControllers();
@ -519,13 +519,13 @@ public class InputFragment extends Fragment {
public void onStateEvent(StateEvent event) {
if (event.getState() == StateEvent.STATE_CONNECTION &&
event.getAction() == MOGAInput.ACTION_CONNECTED) {
event.getAction() == MOGAInput.ACTION_CONNECTED) {
int mControllerVersion = moga.mController
.getState(Controller.STATE_CURRENT_PRODUCT_VERSION);
.getState(Controller.STATE_CURRENT_PRODUCT_VERSION);
if (mControllerVersion == Controller.ACTION_VERSION_MOGA ||
mControllerVersion == Controller.ACTION_VERSION_MOGAPRO) {
mControllerVersion == Controller.ACTION_VERSION_MOGAPRO) {
pad.isActiveMoga[playerNum] = true;
}
}

View File

@ -73,7 +73,7 @@ public class InputModFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.input_mod_fragment, container, false);
}
@ -89,7 +89,7 @@ public class InputModFragment extends Fragment {
if (b != null) {
playerNum = b.getInt("portNumber", -1);
}
switchJoystickDpadEnabled = (CompoundButton) getView().findViewById(
R.id.switchJoystickDpadEnabled);
switchRightStickLREnabled = (CompoundButton) getView().findViewById(
@ -101,41 +101,41 @@ public class InputModFragment extends Fragment {
OnCheckedChangeListener joystick_mode = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
boolean isChecked) {
mPrefs.edit().putBoolean(Gamepad.pref_js_merged + player, isChecked).apply();
}
};
switchJoystickDpadEnabled.setOnCheckedChangeListener(joystick_mode);
OnCheckedChangeListener rstick_mode = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
boolean isChecked) {
mPrefs.edit().putBoolean(Gamepad.pref_js_rbuttons + player, isChecked).apply();
}
};
switchRightStickLREnabled.setOnCheckedChangeListener(rstick_mode);
OnCheckedChangeListener modified_layout = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
boolean isChecked) {
mPrefs.edit().putBoolean(Gamepad.pref_js_modified + player, isChecked).apply();
}
};
switchModifiedLayoutEnabled.setOnCheckedChangeListener(modified_layout);
OnCheckedChangeListener compat_mode = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
boolean isChecked) {
mPrefs.edit().putBoolean(Gamepad.pref_js_compat + player, isChecked).apply();
if (isChecked) {
selectController();
}
}
};
switchCompatibilityEnabled.setOnCheckedChangeListener(compat_mode);
mKey = new mapKeyCode(getActivity());
@ -358,11 +358,11 @@ public class InputModFragment extends Fragment {
player_spnr.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view,
int pos, long id) {
int pos, long id) {
String selection = parent.getItemAtPosition(pos).toString();
player = "_"
+ selection.substring(selection.lastIndexOf(" ") + 1,
selection.length());
selection.length());
playerNum = pos;
updateController(player);
}
@ -377,7 +377,7 @@ public class InputModFragment extends Fragment {
/**
* Retrieve an image to serve as a visual representation
*
*
* @param x
* The x start value of the image within the atlas
* @param y
@ -430,7 +430,7 @@ public class InputModFragment extends Fragment {
/**
* Prompt the user to specify the controller to modify
*
*
*/
private void selectController() {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
@ -464,7 +464,7 @@ public class InputModFragment extends Fragment {
/**
* Prompt the user for the button to be assigned
*
*
* @param button
* The name of the emulator button being defined
* @param output
@ -498,7 +498,7 @@ public class InputModFragment extends Fragment {
/**
* Assign the user button to the emulator button
*
*
* @param keyCode
* The keycode generated by the button being assigned
* @param event
@ -549,7 +549,7 @@ public class InputModFragment extends Fragment {
if (label.contains(":")) {
label = label.substring(0, label.indexOf(":"));
}
output.setText(label + ": " + ev.getAction());
}
@ -561,6 +561,8 @@ public class InputModFragment extends Fragment {
private void updateController(String player) {
switchJoystickDpadEnabled.setChecked(mPrefs.getBoolean(
Gamepad.pref_js_merged + player, false));
switchRightStickLREnabled.setChecked(mPrefs.getBoolean(
Gamepad.pref_js_rbuttons + player, true));
switchModifiedLayoutEnabled.setChecked(mPrefs.getBoolean(
Gamepad.pref_js_modified + player, false));
switchCompatibilityEnabled.setChecked(mPrefs.getBoolean(

View File

@ -1,7 +1,9 @@
package com.reicast.emulator.config;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
@ -62,18 +64,19 @@ public class OptionsFragment extends Fragment {
private File sdcard = Environment.getExternalStorageDirectory();
private String home_directory = sdcard.getAbsolutePath();
private String game_directory = sdcard.getAbsolutePath();
private String[] codes;
// Container Activity must implement this interface
public interface OnClickListener {
void onMainBrowseSelected(boolean browse, String path_entry, boolean games, String query);
void onMainBrowseSelected(boolean browse, String path_entry, boolean games, String query);
void onSettingsReload(Fragment options);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
@ -100,16 +103,16 @@ public class OptionsFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.configure_fragment, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
// Specialized handler for devices with an extSdCard mount for external
HashSet<String> extStorage = FileBrowser.getExternalMounts();
if (extStorage != null && !extStorage.isEmpty()) {
@ -120,7 +123,7 @@ public class OptionsFragment extends Fragment {
}
}
}
home_directory = mPrefs.getString(Config.pref_home, home_directory);
Emulator app = (Emulator) getActivity().getApplicationContext();
app.getConfigurationPrefs(mPrefs);
@ -137,7 +140,7 @@ public class OptionsFragment extends Fragment {
mainBrowse.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
mPrefs.edit().remove(Config.pref_home).apply();
hideSoftKeyBoard();
hideSoftKeyBoard();
mCallback.onMainBrowseSelected(false, home_directory, false, null);
}
});
@ -163,11 +166,11 @@ public class OptionsFragment extends Fragment {
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
});
OnCheckedChangeListener reios_options = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
boolean isChecked) {
mPrefs.edit().putBoolean(Emulator.pref_usereios, isChecked).apply();
}
};
@ -175,11 +178,11 @@ public class OptionsFragment extends Fragment {
R.id.reios_option);
reios_opt.setChecked(mPrefs.getBoolean(Emulator.pref_usereios, false));
reios_opt.setOnCheckedChangeListener(reios_options);
OnCheckedChangeListener details_options = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
boolean isChecked) {
mPrefs.edit().putBoolean(Config.pref_gamedetails, isChecked).apply();
if (!isChecked) {
File dir = new File(getActivity().getExternalFilesDir(null), "images");
@ -209,7 +212,7 @@ public class OptionsFragment extends Fragment {
if (editBrowse.getText() != null) {
game_directory = editGames.getText().toString();
}
hideSoftKeyBoard();
hideSoftKeyBoard();
mCallback.onMainBrowseSelected(false, game_directory, true, null);
}
});
@ -243,12 +246,12 @@ public class OptionsFragment extends Fragment {
bios_spnr.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view,
int pos, long id) {
flashBios(codes[pos]);
int pos, long id) {
flashBios(codes[pos]);
}
public void onNothingSelected(AdapterView<?> arg0) {
}
});
@ -256,7 +259,7 @@ public class OptionsFragment extends Fragment {
OnCheckedChangeListener native_options = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
boolean isChecked) {
mPrefs.edit().putBoolean(Emulator.pref_nativeact, isChecked).apply();
Emulator.nativeact = isChecked;
}
@ -269,7 +272,7 @@ public class OptionsFragment extends Fragment {
OnCheckedChangeListener dynarec_options = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
boolean isChecked) {
mPrefs.edit().putBoolean(Emulator.pref_dynarecopt, isChecked).apply();
Emulator.dynarecopt = isChecked;
}
@ -282,7 +285,7 @@ public class OptionsFragment extends Fragment {
OnCheckedChangeListener unstable_option = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
boolean isChecked) {
mPrefs.edit().putBoolean(Emulator.pref_unstable, isChecked).apply();
Emulator.unstableopt = isChecked;
}
@ -311,7 +314,7 @@ public class OptionsFragment extends Fragment {
cable_spnr.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view,
int pos, long id) {
int pos, long id) {
mPrefs.edit().putInt(Emulator.pref_cable, pos + 1).apply();
Emulator.cable = pos + 1;
}
@ -324,10 +327,8 @@ public class OptionsFragment extends Fragment {
// String[] regions = ArrayUtils.remove(parentActivity.getResources()
// .getStringArray(R.array.region), 4);
String[] regions = getResources()
.getStringArray(R.array.region);
Spinner region_spnr = (Spinner) getView().findViewById(
R.id.region_spinner);
String[] regions = getResources().getStringArray(R.array.region);
Spinner region_spnr = (Spinner) getView().findViewById(R.id.region_spinner);
ArrayAdapter<String> regionAdapter = new ArrayAdapter<String>(
getActivity(), R.layout.spinner_selected, regions);
regionAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
@ -458,7 +459,7 @@ public class OptionsFragment extends Fragment {
pvr_render.setChecked(Emulator.pvrrender);
pvr_render.setOnCheckedChangeListener(pvr_rendering);
OnCheckedChangeListener synchronous = new OnCheckedChangeListener() {
OnCheckedChangeListener synchronous = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mPrefs.edit().putBoolean(Emulator.pref_syncedrender, isChecked).apply();
Emulator.syncedrender = isChecked;
@ -468,42 +469,53 @@ public class OptionsFragment extends Fragment {
synced_render.setChecked(Emulator.syncedrender);
synced_render.setOnCheckedChangeListener(synchronous);
final EditText cheatEdit = (EditText) getView().findViewById(R.id.cheat_disk);
String disk = Emulator.cheatdisk;
if (disk != null && disk.contains("/")) {
cheatEdit.setText(disk.substring(disk.lastIndexOf("/"),
disk.length()));
} else {
cheatEdit.setText(disk);
}
OnCheckedChangeListener mod_volumes = new OnCheckedChangeListener() {
cheatEdit.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
if (cheatEdit.getText() != null) {
String disk = cheatEdit.getText().toString();
if (disk.contains("/")) {
cheatEdit.setText(disk.substring(disk.lastIndexOf("/"),
disk.length()));
} else {
cheatEdit.setText(disk);
}
mPrefs.edit().putString(Emulator.pref_cheatdisk, disk).apply();
Emulator.cheatdisk = disk;
}
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mPrefs.edit().putBoolean(Emulator.pref_modvols, isChecked).apply();
Emulator.modvols = isChecked;
}
};
CompoundButton modifier_volumes = (CompoundButton) getView().findViewById(R.id.modvols_option);
modifier_volumes.setChecked(Emulator.modvols);
modifier_volumes.setOnCheckedChangeListener(mod_volumes);
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
});
// final EditText bootdiskEdit = (EditText) getView().findViewById(R.id.boot_disk);
// String disk = Emulator.bootdisk;
// if (disk != null && disk.contains("/")) {
// bootdiskEdit.setText(disk.substring(disk.lastIndexOf("/"),
// disk.length()));
// } else {
// bootdiskEdit.setText(disk);
// }
//
// bootdiskEdit.addTextChangedListener(new TextWatcher() {
// public void afterTextChanged(Editable s) {
// if (bootdiskEdit.getText() != null) {
// String disk = bootdiskEdit.getText().toString();
// if (disk.contains("/")) {
// bootdiskEdit.setText(disk.substring(disk.lastIndexOf("/"),
// disk.length()));
// } else {
// bootdiskEdit.setText(disk);
// }
// mPrefs.edit().putString(Emulator.pref_bootdisk, disk).apply();
// Emulator.bootdisk = disk;
// }
// }
//
// public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// }
//
// public void onTextChanged(CharSequence s, int start, int before, int count) {
// }
// });
final CompoundButton fps_opt = (CompoundButton) getView().findViewById(R.id.fps_option);
OnCheckedChangeListener fps_options = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
boolean isChecked) {
mPrefs.edit().putBoolean(Config.pref_showfps, isChecked).apply();
}
};
@ -511,38 +523,13 @@ public class OptionsFragment extends Fragment {
fps_opt.setChecked(counter);
fps_opt.setOnCheckedChangeListener(fps_options);
final CompoundButton use_egl14_opt = (CompoundButton) getView().findViewById(R.id.force_gpu_option);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
OnCheckedChangeListener force_gpu_options = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mPrefs.edit().putBoolean(Config.pref_egl14, isChecked).apply();
}
};
boolean enhanced = mPrefs.getBoolean(Config.pref_egl14, false);
use_egl14_opt.setChecked(enhanced);
use_egl14_opt.setOnCheckedChangeListener(force_gpu_options);
} else {
use_egl14_opt.setEnabled(false);
}
CompoundButton force_software_opt = (CompoundButton) getView().findViewById(
R.id.software_option);
OnCheckedChangeListener force_software = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mPrefs.edit()
.putInt(Config.pref_rendertype, isChecked
? GL2JNIView.LAYER_TYPE_SOFTWARE : GL2JNIView.LAYER_TYPE_HARDWARE
).apply();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (isChecked) {
use_egl14_opt.setEnabled(false);
mPrefs.edit().putBoolean(Config.pref_egl14, false).apply();
} else {
use_egl14_opt.setEnabled(true);
}
}
mPrefs.edit().putInt(Config.pref_rendertype, isChecked ?
GL2JNIView.LAYER_TYPE_SOFTWARE : GL2JNIView.LAYER_TYPE_HARDWARE).apply();
}
};
int software = mPrefs.getInt(Config.pref_rendertype, GL2JNIView.LAYER_TYPE_HARDWARE);
@ -583,8 +570,25 @@ public class OptionsFragment extends Fragment {
}
});
Button resetEmu = (Button) getView().findViewById(R.id.reset_emu_settings);
resetEmu.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
AlertDialog.Builder b = new AlertDialog.Builder(getActivity());
b.setIcon(android.R.drawable.ic_dialog_alert);
b.setTitle(getActivity().getString(R.string.reset_emu_title) + "?");
b.setMessage(getActivity().getString(R.string.reset_emu_details));
b.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
resetEmuSettings();
}
});
b.setNegativeButton(android.R.string.no, null);
b.show();
}
});
}
private final class LocateThemes extends AsyncTask<String, Integer, List<File>> {
@Override
protected List<File> doInBackground(String... paths) {
@ -652,7 +656,7 @@ public class OptionsFragment extends Fragment {
iMm.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
}
}
private void copy(File src, File dst) throws IOException {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
try (InputStream in = new FileInputStream(src)) {
@ -681,7 +685,7 @@ public class OptionsFragment extends Fragment {
}
}
}
private void flashBios(String localized) {
File local = new File(home_directory, "data/dc_flash[" + localized
+ "].bin");
@ -701,6 +705,32 @@ public class OptionsFragment extends Fragment {
}
}
private void resetEmuSettings() {
mPrefs.edit().remove(Emulator.pref_usereios).apply();
mPrefs.edit().remove(Config.pref_gamedetails).apply();
mPrefs.edit().remove(Emulator.pref_nativeact).apply();
mPrefs.edit().remove(Emulator.pref_dynarecopt).apply();
mPrefs.edit().remove(Emulator.pref_unstable).apply();
mPrefs.edit().remove(Emulator.pref_cable).apply();
mPrefs.edit().remove(Emulator.pref_dcregion).apply();
mPrefs.edit().remove(Emulator.pref_broadcast).apply();
mPrefs.edit().remove(Emulator.pref_limitfps).apply();
mPrefs.edit().remove(Emulator.pref_mipmaps).apply();
mPrefs.edit().remove(Emulator.pref_widescreen).apply();
mPrefs.edit().remove(Emulator.pref_frameskip).apply();
mPrefs.edit().remove(Emulator.pref_pvrrender).apply();
mPrefs.edit().remove(Emulator.pref_syncedrender).apply();
mPrefs.edit().remove(Emulator.pref_modvols).apply();
// mPrefs.edit().remove(Emulator.pref_bootdisk).apply();
mPrefs.edit().remove(Config.pref_showfps).apply();
mPrefs.edit().remove(Config.pref_rendertype).apply();
mPrefs.edit().remove(Emulator.pref_nosound).apply();
mPrefs.edit().remove(Config.pref_renderdepth).apply();
mPrefs.edit().remove(Config.pref_theme).apply();
mCallback.onSettingsReload(this);
}
private void showToastMessage(String message, int duration) {
ConstraintLayout layout = (ConstraintLayout) getActivity().findViewById(R.id.mainui_layout);
Snackbar snackbar = Snackbar.make(layout, message, duration);

View File

@ -59,7 +59,7 @@ public class GenerateLogs extends AsyncTask<String, Integer, String> {
/**
* Obtain the specific parameters of the current device
*
*
*/
private String discoverCPUData() {
String s = "MODEL: " + Build.MODEL;
@ -108,7 +108,7 @@ public class GenerateLogs extends AsyncTask<String, Integer, String> {
/**
* Read the output of a shell command
*
*
* @param command
* The shell command being issued to the terminal
*/
@ -153,7 +153,7 @@ public class GenerateLogs extends AsyncTask<String, Integer, String> {
}
try {
mLogcatProc = Runtime.getRuntime().exec(
new String[] { "logcat", "-d", "AndroidRuntime:E *:S" });
new String[] { "logcat", "-ds", "AndroidRuntime:E" });
reader = new BufferedReader(new InputStreamReader(
mLogcatProc.getInputStream()));
String line;
@ -187,7 +187,7 @@ public class GenerateLogs extends AsyncTask<String, Integer, String> {
mLogcatProc = null;
reader = null;
mLogcatProc = Runtime.getRuntime().exec(
new String[] { "logcat", "-d", "reicast:V *:S" });
new String[] { "logcat", "-ds", "reicast:V" });
reader = new BufferedReader(new InputStreamReader(
mLogcatProc.getInputStream()));
log.append(separator);
@ -203,7 +203,7 @@ public class GenerateLogs extends AsyncTask<String, Integer, String> {
mLogcatProc = null;
reader = null;
mLogcatProc = Runtime.getRuntime().exec(
new String[] { "logcat", "-d", "GL2JNIView:E *:S" });
new String[] { "logcat", "-ds", "GL2JNIView:E" });
reader = new BufferedReader(new InputStreamReader(
mLogcatProc.getInputStream()));
log.append(separator);

View File

@ -114,7 +114,7 @@ public class GitAdapter extends BaseAdapter {
}
private void displayCommit(final String sha, String message, String url,
Context context) {
Context context) {
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setCancelable(true);
builder.setTitle(sha.substring(0,7));
@ -138,7 +138,7 @@ public class GitAdapter extends BaseAdapter {
@SuppressLint("SetJavaScriptEnabled")
@SuppressWarnings("deprecation")
private WebView configureWebview(String url, Context context,
WebView mWebView) {
WebView mWebView) {
mWebView.getSettings().setSupportZoom(true);
mWebView.getSettings().setBuiltInZoomControls(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {

View File

@ -0,0 +1,714 @@
package com.reicast.emulator.emu;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.opengl.GLSurfaceView;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.Vibrator;
import android.preference.PreferenceManager;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.ScaleGestureDetector.SimpleOnScaleGestureListener;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;
import com.android.util.FileUtils;
import com.reicast.emulator.Emulator;
import com.reicast.emulator.GL2JNIActivity;
import com.reicast.emulator.GL2JNINative;
import com.reicast.emulator.config.Config;
import com.reicast.emulator.emu.OnScreenMenu.FpsPopup;
import com.reicast.emulator.periph.VJoy;
import java.io.UnsupportedEncodingException;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
/**
* A simple GLSurfaceView sub-class that demonstrate how to perform
* OpenGL ES 2.0 rendering into a GL Surface. Note the following important
* details:
*
* - The class must use a custom context factory to enable 2.0 rendering.
* See ContextFactory class definition below.
*
* - The class must use a custom EGLConfigChooser to be able to select
* an EGLConfig that supports 2.0. This is done by providing a config
* specification to eglChooseConfig() that has the attribute
* EGL10.ELG_RENDERABLE_TYPE containing the EGL_OPENGL_ES2_BIT flag
* set. See ConfigChooser class definition below.
*
* - The class must select the surface's format, then choose an EGLConfig
* that matches it exactly (with regards to red/green/blue/alpha channels
* bit depths). Failure to do so would result in an EGL_BAD_MATCH error.
*/
public class GL2JNIView extends GLSurfaceView
{
public static final boolean DEBUG = false;
public static final int LAYER_TYPE_SOFTWARE = 1;
public static final int LAYER_TYPE_HARDWARE = 2;
private static String fileName;
//private AudioThread audioThread;
private EmuThread ethd;
private Handler handler = new Handler();
private static int sWidth;
private static int sHeight;
Vibrator vib;
private boolean editVjoyMode = false;
private int selectedVjoyElement = -1;
private ScaleGestureDetector scaleGestureDetector;
public float[][] vjoy_d_custom;
private static final float[][] vjoy = VJoy.baseVJoy();
Renderer rend;
private boolean touchVibrationEnabled;
private int vibrationDuration;
Context context;
public void restoreCustomVjoyValues(float[][] vjoy_d_cached) {
vjoy_d_custom = vjoy_d_cached;
VJoy.writeCustomVjoyValues(vjoy_d_cached, context);
resetEditMode();
requestLayout();
}
public void setFpsDisplay(FpsPopup fpsPop) {
rend.fpsPop = fpsPop;
}
public GL2JNIView(Context context) {
super(context);
}
public GL2JNIView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public GL2JNIView(Context context, String newFileName,
boolean translucent, int depth, int stencil, boolean editVjoyMode) {
super(context);
this.context = context;
this.editVjoyMode = editVjoyMode;
setKeepScreenOn(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
setOnSystemUiVisibilityChangeListener (new OnSystemUiVisibilityChangeListener() {
public void onSystemUiVisibilityChange(int visibility) {
if ((visibility & SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
GL2JNIView.this.setSystemUiVisibility(
SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| SYSTEM_UI_FLAG_FULLSCREEN
| SYSTEM_UI_FLAG_HIDE_NAVIGATION);
requestLayout();
}
}
});
}
setPreserveEGLContextOnPause(true);
vib=(Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
DisplayMetrics metrics = new DisplayMetrics();
//((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(metrics);
((WindowManager) context.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay().getMetrics(metrics);
final float scale = context.getResources().getDisplayMetrics().density;
sWidth = (int) (metrics.widthPixels * scale + 0.5f);
sHeight = (int) (metrics.heightPixels * scale + 0.5f);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
JNIdc.config(prefs.getString(Config.pref_home,
Environment.getExternalStorageDirectory().getAbsolutePath()));
ethd = new EmuThread(!Emulator.nosound);
touchVibrationEnabled = prefs.getBoolean(Config.pref_touchvibe, true);
vibrationDuration = prefs.getInt(Config.pref_vibrationDuration, 20);
this.setLayerType(prefs.getInt(Config.pref_rendertype, LAYER_TYPE_HARDWARE), null);
vjoy_d_custom = VJoy.readCustomVjoyValues(context);
scaleGestureDetector = new ScaleGestureDetector(context, new OscOnScaleGestureListener());
// This is the game we are going to run
fileName = newFileName;
if (Emulator.nativeact) {
if (GL2JNINative.syms != null)
JNIdc.data(1, GL2JNINative.syms);
} else {
if (GL2JNIActivity.syms != null)
JNIdc.data(1, GL2JNIActivity.syms);
}
JNIdc.init(fileName);
// By default, GLSurfaceView() creates a RGB_565 opaque surface.
// If we want a translucent one, we should change the surface's
// format here, using PixelFormat.TRANSLUCENT for GL Surfaces
// is interpreted as any 32-bit surface with alpha by SurfaceFlinger.
if(translucent)
this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
else
this.getHolder().setFormat(PixelFormat.RGBX_8888);
// Setup the context factory for 2.0 rendering.
// See ContextFactory class definition below
setEGLContextFactory(new GLCFactory.ContextFactory());
// We need to choose an EGLConfig that matches the format of
// our surface exactly. This is going to be done in our
// custom config chooser. See ConfigChooser class definition
// below.
setEGLConfigChooser(new GLCFactory.ConfigChooser(8, 8, 8, translucent ? 8 : 0, depth, stencil));
// Set the renderer responsible for frame rendering
setRenderer(rend=new Renderer(this));
pushInput(); //initializes controller codes
ethd.start();
}
public GLSurfaceView.Renderer getRenderer()
{
return rend;
}
private void reset_analog()
{
int j=11;
vjoy[j+1][0]=vjoy[j][0]+vjoy[j][2]/2-vjoy[j+1][2]/2;
vjoy[j+1][1]=vjoy[j][1]+vjoy[j][3]/2-vjoy[j+1][3]/2;
JNIdc.vjoy(j+1, vjoy[j+1][0], vjoy[j+1][1], vjoy[j+1][2], vjoy[j+1][3]);
}
int get_anal(int j, int axis)
{
return (int) (((vjoy[j+1][axis]+vjoy[j+1][axis+2]/2) - vjoy[j][axis] - vjoy[j][axis+2]/2)*254/vjoy[j][axis+2]);
}
float vbase(float p, float m, float scl)
{
return (int) ( m - (m -p)*scl);
}
float vbase(float p, float scl)
{
return (int) (p*scl );
}
public boolean isTablet() {
return (getContext().getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom)
{
super.onLayout(changed, left, top, right, bottom);
//dcpx/cm = dcpx/px * px/cm
float magic = isTablet() ? 0.8f : 0.7f;
float scl = 480.0f/getHeight() * getContext().getResources().getDisplayMetrics().density * magic;
float scl_dc = getHeight()/480.0f;
float tx = ((getWidth()-640.0f*scl_dc)/2)/scl_dc;
float a_x = -tx+ 24*scl;
float a_y=- 24*scl;
float[][] vjoy_d = VJoy.getVjoy_d(vjoy_d_custom);
for (int i=0;i<vjoy.length;i++)
{
if (vjoy_d[i][0] == 288)
vjoy[i][0] = vjoy_d[i][0];
else if (vjoy_d[i][0]-vjoy_d_custom[getElementIdFromButtonId(i)][0] < 320)
vjoy[i][0] = a_x + vbase(vjoy_d[i][0],scl);
else
vjoy[i][0] = -a_x + vbase(vjoy_d[i][0],640,scl);
vjoy[i][1] = a_y + vbase(vjoy_d[i][1],480,scl);
vjoy[i][2] = vbase(vjoy_d[i][2],scl);
vjoy[i][3] = vbase(vjoy_d[i][3],scl);
}
for (int i=0;i<VJoy.VJoyCount;i++)
JNIdc.vjoy(i,vjoy[i][0],vjoy[i][1],vjoy[i][2],vjoy[i][3]);
reset_analog();
VJoy.writeCustomVjoyValues(vjoy_d_custom, context);
}
int anal_id=-1, lt_id=-1, rt_id=-1;
public void resetEditMode() {
editLastX = 0;
editLastY = 0;
}
private static int getElementIdFromButtonId(int buttonId) {
if (buttonId <= 3)
return 0; // DPAD
else if (buttonId <= 7)
return 1; // X, Y, B, A Buttons
else if (buttonId == 8)
return 2; // Start
else if (buttonId == 9)
return 3; // Left Trigger
else if (buttonId == 10)
return 4; // Right Trigger
else if (buttonId <= 12)
return 5; // Analog
else
return 0; // DPAD diagonials
}
public static int[] kcode_raw = { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF };
public static int[] lt = new int[4];
public static int[] rt = new int[4];
public static int[] jx = new int[4];
public static int[] jy = new int[4];
float editLastX = 0, editLastY = 0;
@Override public boolean onTouchEvent(final MotionEvent event)
{
JNIdc.show_osd();
scaleGestureDetector.onTouchEvent(event);
float ty = 0.0f;
float scl = getHeight()/480.0f;
float tx = (getWidth()-640.0f*scl)/2;
int rv = 0xFFFF;
int aid = event.getActionMasked();
int pid = event.getActionIndex();
if (editVjoyMode && selectedVjoyElement != -1 && aid == MotionEvent.ACTION_MOVE && !scaleGestureDetector.isInProgress()) {
float x = (event.getX()-tx)/scl;
float y = (event.getY()-ty)/scl;
if (editLastX != 0 && editLastY != 0) {
float deltaX = x - editLastX;
float deltaY = y - editLastY;
vjoy_d_custom[selectedVjoyElement][0] += isTablet() ? deltaX * 2 : deltaX;
vjoy_d_custom[selectedVjoyElement][1] += isTablet() ? deltaY * 2 : deltaY;
requestLayout();
}
editLastX = x;
editLastY = y;
return true;
}
for (int i=0;i<event.getPointerCount();i++)
{
float x = (event.getX(i)-tx)/scl;
float y = (event.getY(i)-ty)/scl;
if (anal_id != event.getPointerId(i))
{
if (aid == MotionEvent.ACTION_POINTER_UP && pid==i)
continue;
for (int j=0;j<vjoy.length;j++)
{
if(x>vjoy[j][0] && x<=(vjoy[j][0]+vjoy[j][2]))
{
/*
//Disable pressure sensitive R/L
//Doesn't really work properly
int pre=(int)(event.getPressure(i)*255);
if (pre>20)
{
pre-=20;
pre*=7;
}
if (pre>255) pre=255;
*/
int pre = 255;
if (y>vjoy[j][1] && y<=(vjoy[j][1]+vjoy[j][3]))
{
if (vjoy[j][4]>=-2)
{
if (vjoy[j][5]==0)
if (!editVjoyMode && touchVibrationEnabled)
vib.vibrate(vibrationDuration);
vjoy[j][5]=2;
}
if (vjoy[j][4]==-3)
{
if (editVjoyMode) {
selectedVjoyElement = 5; // Analog
resetEditMode();
} else {
vjoy[j+1][0]=x-vjoy[j+1][2]/2;
vjoy[j+1][1]=y-vjoy[j+1][3]/2;
JNIdc.vjoy(j+1, vjoy[j+1][0], vjoy[j+1][1] , vjoy[j+1][2], vjoy[j+1][3]);
anal_id=event.getPointerId(i);
}
}
else if (vjoy[j][4]==-4);
else if(vjoy[j][4]==-1) {
if (editVjoyMode) {
selectedVjoyElement = 3; // Left Trigger
resetEditMode();
} else {
lt[0]=pre;
lt_id=event.getPointerId(i);
}
}
else if (vjoy[j][4]==-2) {
if (editVjoyMode) {
selectedVjoyElement = 4; // Right Trigger
resetEditMode();
} else{
rt[0]=pre;
rt_id=event.getPointerId(i);
}
}
else {
if (editVjoyMode) {
selectedVjoyElement = getElementIdFromButtonId(j);
resetEditMode();
} else
rv&=~(int)vjoy[j][4];
}
}
}
}
}
else
{
if (x<vjoy[11][0])
x=vjoy[11][0];
else if (x>(vjoy[11][0]+vjoy[11][2]))
x=vjoy[11][0]+vjoy[11][2];
if (y<vjoy[11][1])
y=vjoy[11][1];
else if (y>(vjoy[11][1]+vjoy[11][3]))
y=vjoy[11][1]+vjoy[11][3];
int j=11;
vjoy[j+1][0]=x-vjoy[j+1][2]/2;
vjoy[j+1][1]=y-vjoy[j+1][3]/2;
JNIdc.vjoy(j+1, vjoy[j+1][0], vjoy[j+1][1] , vjoy[j+1][2], vjoy[j+1][3]);
}
}
for (int j=0;j<vjoy.length;j++)
{
if (vjoy[j][5]==2)
vjoy[j][5]=1;
else if (vjoy[j][5]==1)
vjoy[j][5]=0;
}
switch(aid)
{
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
selectedVjoyElement = -1;
reset_analog();
anal_id=-1;
rv=0xFFFF;
rt[0]=0;
lt[0]=0;
lt_id=-1;
rt_id=-1;
for (int j=0;j<vjoy.length;j++)
vjoy[j][5]=0;
break;
case MotionEvent.ACTION_POINTER_UP:
if (event.getPointerId(event.getActionIndex())==anal_id)
{
reset_analog();
anal_id=-1;
}
else if (event.getPointerId(event.getActionIndex())==lt_id)
{
lt[0]=0;
lt_id=-1;
}
else if (event.getPointerId(event.getActionIndex())==rt_id)
{
rt[0]=0;
rt_id=-1;
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
case MotionEvent.ACTION_DOWN:
break;
}
kcode_raw[0] = rv;
jx[0] = get_anal(11, 0);
jy[0] = get_anal(11, 1);
pushInput();
return(true);
}
private class OscOnScaleGestureListener extends
SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
if (editVjoyMode && selectedVjoyElement != -1) {
vjoy_d_custom[selectedVjoyElement][2] *= detector.getScaleFactor();
requestLayout();
return true;
}
return false;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
selectedVjoyElement = -1;
}
}
public void pushInput(){
JNIdc.kcode(kcode_raw,lt,rt,jx,jy);
}
private static class Renderer implements GLSurfaceView.Renderer
{
private GL2JNIView mView;
private FPSCounter fps = new FPSCounter();
private FpsPopup fpsPop;
public Renderer (GL2JNIView mView) {
this.mView = mView;
}
public void onDrawFrame(GL10 gl)
{
if (fpsPop != null && fpsPop.isShowing()) {
fps.logFrame();
}
JNIdc.rendframe();
if(mView.takeScreenshot){
mView.takeScreenshot = false;
FileUtils.saveScreenshot(mView.getContext(), mView.getWidth(), mView.getHeight(), gl);
}
}
public void onSurfaceChanged(GL10 gl,int width,int height)
{
gl.glViewport(0, 0, width, height);
JNIdc.rendinit(width,height);
}
public void onSurfaceCreated(GL10 gl,EGLConfig config)
{
onSurfaceChanged(gl, 800, 480);
}
public class FPSCounter {
long startTime = System.nanoTime();
int frames = 0;
public void logFrame() {
frames++;
if (System.nanoTime() - startTime >= 1000000000) {
mView.post(new Runnable() {
public void run() {
if (frames > 0) {
fpsPop.setText(frames);
}
}
});
startTime = System.nanoTime();
frames = 0;
}
}
}
}
public void audioDisable(boolean disabled) {
if (disabled) {
ethd.Player.pause();
} else {
ethd.Player.play();
}
}
public void fastForward(boolean enabled) {
if (enabled) {
ethd.setPriority(Thread.MIN_PRIORITY);
} else {
ethd.setPriority(Thread.NORM_PRIORITY);
}
}
class EmuThread extends Thread
{
AudioTrack Player;
long pos; //write position
long size; //size in frames
private boolean sound;
public EmuThread(boolean sound) {
this.sound = sound;
}
@Override public void run()
{
if (sound) {
int min=AudioTrack.getMinBufferSize(44100,AudioFormat.CHANNEL_OUT_STEREO,AudioFormat.ENCODING_PCM_16BIT);
if (2048>min)
min=2048;
Player = new AudioTrack(
AudioManager.STREAM_MUSIC,
44100,
AudioFormat.CHANNEL_OUT_STEREO,
AudioFormat.ENCODING_PCM_16BIT,
min,
AudioTrack.MODE_STREAM
);
size=min/4;
pos=0;
Log.i("audcfg", "Audio streaming: buffer size " + min + " samples / " + min/44100.0 + " ms");
Player.play();
}
JNIdc.run(this);
}
int WriteBuffer(short[] samples, int wait)
{
if (sound) {
int newdata=samples.length/2;
if (wait==0)
{
//user bytes = write-read
//available = size - (write - play)
long used=pos-Player.getPlaybackHeadPosition();
long avail=size-used;
//Log.i("audcfg", "u: " + used + " a: " + avail);
if (avail<newdata)
return 0;
}
pos+=newdata;
Player.write(samples, 0, samples.length);
}
return 1;
}
void showMessage(final String msg) {
handler.post(new Runnable() {
public void run() {
Log.d(context.getApplicationContext().getPackageName(), msg);
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
});
}
void coreMessage(byte[] msg) {
try {
showMessage(new String(msg, "UTF-8"));
}
catch (UnsupportedEncodingException e) {
showMessage("coreMessage: Failed to display error");
}
}
void Die() {
showMessage("Something went wrong and reicast crashed.\nPlease report this on the reicast forums.");
((Activity) context).finish();
}
}
public void onDestroy() {
// Workaround for ANR when returning to menu
System.exit(0);
try {
ethd.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@TargetApi(19)
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
GL2JNIView.this.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
requestLayout();
}
}
private boolean takeScreenshot = false;
public void screenGrab() {
takeScreenshot = true;
}
}

View File

@ -0,0 +1,241 @@
package com.reicast.emulator.emu;
import android.opengl.GLSurfaceView;
import android.util.Log;
import java.util.Locale;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
public class GLCFactory {
private static void LOGI(String S) { Log.i("GL2JNIView",S); }
private static void LOGW(String S) { Log.w("GL2JNIView",S); }
private static void LOGE(String S) { Log.e("GL2JNIView",S); }
private int DEPTH_COMPONENT16_NONLINEAR_NV = 0x8E2C;
private int EGL_DEPTH_ENCODING_NV = 0x30E2;
private int EGL_DEPTH_ENCODING_NONLINEAR_NV = 0x30E3;
public static class ContextFactory implements GLSurfaceView.EGLContextFactory
{
private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
public EGLContext createContext(EGL10 egl,EGLDisplay display,EGLConfig eglConfig)
{
int[] attrList = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
LOGI("Creating OpenGL ES 2.0 context");
checkEglError("Before eglCreateContext",egl);
EGLContext context = egl.eglCreateContext(display,eglConfig,EGL10.EGL_NO_CONTEXT,attrList);
checkEglError("After eglCreateContext",egl);
return(context);
}
public void destroyContext(EGL10 egl,EGLDisplay display,EGLContext context)
{
LOGI("Destroying OpenGL ES 2.0 context");
egl.eglDestroyContext(display,context);
}
}
private static void checkEglError(String prompt,EGL10 egl)
{
int error;
while((error=egl.eglGetError()) != EGL10.EGL_SUCCESS)
LOGE(String.format("%s: EGL error: 0x%x",prompt,error));
}
public static class ConfigChooser implements GLSurfaceView.EGLConfigChooser
{
// Subclasses can adjust these values:
protected int mRedSize;
protected int mGreenSize;
protected int mBlueSize;
protected int mAlphaSize;
protected int mDepthSize;
protected int mStencilSize;
private int[] mValue = new int[1];
public ConfigChooser(int r,int g,int b,int a,int depth,int stencil)
{
mRedSize = r;
mGreenSize = g;
mBlueSize = b;
mAlphaSize = a;
mDepthSize = depth;
mStencilSize = stencil;
}
// This EGL config specification is used to specify 2.0 rendering.
// We use a minimum size of 4 bits for red/green/blue, but will
// perform actual matching in chooseConfig() below.
private static final int EGL_OPENGL_ES2_BIT = 4;
private static final int[] cfgAttrs =
{
EGL10.EGL_RED_SIZE, 4,
EGL10.EGL_GREEN_SIZE, 4,
EGL10.EGL_BLUE_SIZE, 4,
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL10.EGL_DEPTH_SIZE, 24,
EGL10.EGL_NONE
};
public EGLConfig chooseConfig(EGL10 egl,EGLDisplay display)
{
// Get the number of minimally matching EGL configurations
int[] cfgCount = new int[1];
egl.eglChooseConfig(display,cfgAttrs,null,0,cfgCount);
if (cfgCount[0]<=0)
{
cfgAttrs[9]=16;
egl.eglChooseConfig(display,cfgAttrs,null,0,cfgCount);
}
if (cfgCount[0]<=0)
throw new IllegalArgumentException("No configs match configSpec");
// Allocate then read the array of minimally matching EGL configs
EGLConfig[] configs = new EGLConfig[cfgCount[0]];
egl.eglChooseConfig(display,cfgAttrs,configs,cfgCount[0],cfgCount);
if (GL2JNIView.DEBUG)
printConfigs(egl,display,configs);
// Now return the "best" one
return(chooseConfig(egl,display,configs));
}
public EGLConfig chooseConfig(EGL10 egl,EGLDisplay display,EGLConfig[] configs)
{
for (EGLConfig config : configs)
{
int d = findConfigAttrib(egl,display,config,EGL10.EGL_DEPTH_SIZE,0);
int s = findConfigAttrib(egl,display,config,EGL10.EGL_STENCIL_SIZE,0);
// We need at least mDepthSize and mStencilSize bits
if (d>=mDepthSize || s>=mStencilSize)
{
// We want an *exact* match for red/green/blue/alpha
int r = findConfigAttrib(egl,display,config,EGL10.EGL_RED_SIZE, 0);
int g = findConfigAttrib(egl,display,config,EGL10.EGL_GREEN_SIZE,0);
int b = findConfigAttrib(egl,display,config,EGL10.EGL_BLUE_SIZE, 0);
int a = findConfigAttrib(egl,display,config,EGL10.EGL_ALPHA_SIZE,0);
if(r==mRedSize && g==mGreenSize && b==mBlueSize && a==mAlphaSize)
return(config);
}
}
return(null);
}
private int findConfigAttrib(EGL10 egl,EGLDisplay display,EGLConfig config,int attribute,int defaultValue)
{
return(egl.eglGetConfigAttrib(display,config,attribute,mValue)? mValue[0] : defaultValue);
}
private void printConfigs(EGL10 egl,EGLDisplay display,EGLConfig[] configs)
{
LOGW(String.format(Locale.getDefault(), "%d configurations", configs.length));
for(int i=0 ; i<configs.length ; i++)
{
LOGW(String.format(Locale.getDefault(), "Configuration %d:", i));
printConfig(egl,display,configs[i]);
}
}
private void printConfig(EGL10 egl,EGLDisplay display,EGLConfig config)
{
final int[] attributes =
{
EGL10.EGL_BUFFER_SIZE,
EGL10.EGL_ALPHA_SIZE,
EGL10.EGL_BLUE_SIZE,
EGL10.EGL_GREEN_SIZE,
EGL10.EGL_RED_SIZE,
EGL10.EGL_DEPTH_SIZE,
EGL10.EGL_STENCIL_SIZE,
EGL10.EGL_CONFIG_CAVEAT,
EGL10.EGL_CONFIG_ID,
EGL10.EGL_LEVEL,
EGL10.EGL_MAX_PBUFFER_HEIGHT,
EGL10.EGL_MAX_PBUFFER_PIXELS,
EGL10.EGL_MAX_PBUFFER_WIDTH,
EGL10.EGL_NATIVE_RENDERABLE,
EGL10.EGL_NATIVE_VISUAL_ID,
EGL10.EGL_NATIVE_VISUAL_TYPE,
0x3030, // EGL10.EGL_PRESERVED_RESOURCES,
EGL10.EGL_SAMPLES,
EGL10.EGL_SAMPLE_BUFFERS,
EGL10.EGL_SURFACE_TYPE,
EGL10.EGL_TRANSPARENT_TYPE,
EGL10.EGL_TRANSPARENT_RED_VALUE,
EGL10.EGL_TRANSPARENT_GREEN_VALUE,
EGL10.EGL_TRANSPARENT_BLUE_VALUE,
0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB,
0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA,
0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL,
0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL,
EGL10.EGL_LUMINANCE_SIZE,
EGL10.EGL_ALPHA_MASK_SIZE,
EGL10.EGL_COLOR_BUFFER_TYPE,
EGL10.EGL_RENDERABLE_TYPE,
0x3042 // EGL10.EGL_CONFORMANT
};
final String[] names =
{
"EGL_BUFFER_SIZE",
"EGL_ALPHA_SIZE",
"EGL_BLUE_SIZE",
"EGL_GREEN_SIZE",
"EGL_RED_SIZE",
"EGL_DEPTH_SIZE",
"EGL_STENCIL_SIZE",
"EGL_CONFIG_CAVEAT",
"EGL_CONFIG_ID",
"EGL_LEVEL",
"EGL_MAX_PBUFFER_HEIGHT",
"EGL_MAX_PBUFFER_PIXELS",
"EGL_MAX_PBUFFER_WIDTH",
"EGL_NATIVE_RENDERABLE",
"EGL_NATIVE_VISUAL_ID",
"EGL_NATIVE_VISUAL_TYPE",
"EGL_PRESERVED_RESOURCES",
"EGL_SAMPLES",
"EGL_SAMPLE_BUFFERS",
"EGL_SURFACE_TYPE",
"EGL_TRANSPARENT_TYPE",
"EGL_TRANSPARENT_RED_VALUE",
"EGL_TRANSPARENT_GREEN_VALUE",
"EGL_TRANSPARENT_BLUE_VALUE",
"EGL_BIND_TO_TEXTURE_RGB",
"EGL_BIND_TO_TEXTURE_RGBA",
"EGL_MIN_SWAP_INTERVAL",
"EGL_MAX_SWAP_INTERVAL",
"EGL_LUMINANCE_SIZE",
"EGL_ALPHA_MASK_SIZE",
"EGL_COLOR_BUFFER_TYPE",
"EGL_RENDERABLE_TYPE",
"EGL_CONFORMANT"
};
int[] value = new int[1];
for (int i=0 ; i<attributes.length ; i++)
if (egl.eglGetConfigAttrib(display,config,attributes[i],value))
LOGI(String.format(Locale.getDefault(), " %s: %d\n",names[i],value[0]));
else
while(egl.eglGetError()!=EGL10.EGL_SUCCESS);
}
}
}

View File

@ -0,0 +1,275 @@
package com.reicast.emulator.emu;
import android.annotation.TargetApi;
import android.opengl.EGL14;
import android.opengl.EGLConfig;
import android.opengl.EGLContext;
import android.opengl.EGLDisplay;
import android.opengl.EGLExt;
import android.opengl.EGLSurface;
import android.opengl.GLES20;
import android.os.Build;
import android.util.Log;
import android.view.Window;
import java.util.Locale;
import javax.microedition.khronos.egl.EGL10;
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public class GLCFactory14 {
private static void LOGI(String S) { Log.i("GL2JNIView-v6",S); }
private static void LOGW(String S) { Log.w("GL2JNIView-v6",S); }
private static void LOGE(String S) { Log.e("GL2JNIView-v6",S); }
private int DEPTH_COMPONENT16_NONLINEAR_NV = 0x8E2C;
private int EGL_DEPTH_ENCODING_NV = 0x30E2;
private int EGL_DEPTH_ENCODING_NONLINEAR_NV = 0x30E3;
private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
private void configureWindow() {
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
}
public EGLDisplay getDisplay() {
EGLDisplay eglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
if (eglDisplay == EGL14.EGL_NO_DISPLAY) {
throw new RuntimeException("eglGetDisplay failed");
}
int[] major = new int[1];
int[] minor = new int[1];
if (!EGL14.eglInitialize(eglDisplay, major, 0, minor, 0)) {
throw new RuntimeException("eglInitialize failed");
}
if (minor[0] < 4) {
throw new RuntimeException("EGL 1.4 required");
}
return eglDisplay;
}
public void terminate(EGLDisplay display) {
EGL14.eglTerminate(display);
}
public EGLContext createContext(EGLDisplay display, EGLConfig eglConfig)
{
EGLContext context = EGL14.EGL_NO_CONTEXT;
for ( int clientVersion = 3; clientVersion >= 2; clientVersion-- ) {
int[] attrList = { EGL_CONTEXT_CLIENT_VERSION, clientVersion, EGL14.EGL_NONE };
LOGI("Creating OpenGL ES " + clientVersion + " context");
context = EGL14.eglCreateContext(display, eglConfig, EGL14.EGL_NO_CONTEXT, attrList, 0);
if (context != EGL14.EGL_NO_CONTEXT) {
break;
}
}
return(context);
}
public void destroyContext(EGLDisplay display, EGLContext context) {
EGL14.eglDestroyContext(display, context);
}
private static void checkEglError(String prompt,EGL10 egl)
{
int error;
while((error=egl.eglGetError()) != EGL14.EGL_SUCCESS)
LOGE(String.format(Locale.getDefault(), "%s: EGL error: 0x%x",prompt,error));
}
// Subclasses can adjust these values:
protected int mRedSize;
protected int mGreenSize;
protected int mBlueSize;
protected int mAlphaSize;
protected int mDepthSize;
protected int mStencilSize;
private int[] mValue = new int[1];
public EGLConfig chooseConfig(EGLDisplay display) {
mValue = new int[1];
int glAPIToTry = EGLExt.EGL_OPENGL_ES3_BIT_KHR;
int[] configSpec = null;
do {
EGL14.eglBindAPI(glAPIToTry);
int renderableType;
if (glAPIToTry == EGLExt.EGL_OPENGL_ES3_BIT_KHR) {
renderableType = EGLExt.EGL_OPENGL_ES3_BIT_KHR;
// If this API does not work, try ES2 next.
glAPIToTry = EGL14.EGL_OPENGL_ES2_BIT;
} else {
renderableType = EGL14.EGL_OPENGL_ES2_BIT;
// If this API does not work, is a potato.
glAPIToTry = EGL10.EGL_NONE;
}
// This EGL config specification is used to specify 3.0 rendering.
// We use a minimum size of 8 bits for red/green/blue, but will
// perform actual matching in chooseConfig() below.
configSpec = new int[] {
EGL14.EGL_RED_SIZE, 8,
EGL14.EGL_GREEN_SIZE, 8,
EGL14.EGL_BLUE_SIZE, 8,
EGL14.EGL_RENDERABLE_TYPE, renderableType,
EGL14.EGL_DEPTH_SIZE, 16,
EGL14.EGL_NONE
};
if (!EGL14.eglChooseConfig(display, configSpec, 0,null, 0, 0, mValue, 0)) {
configSpec[9] = 16;
if (!EGL14.eglChooseConfig(display, configSpec, 0,null, 0, 0, mValue, 0)) {
throw new IllegalArgumentException("Could not get context count");
}
}
} while (glAPIToTry != EGL10.EGL_NONE && mValue[0]<=0);
if (mValue[0]<=0) {
throw new IllegalArgumentException("No configs match configSpec");
}
// Get all matching configurations.
EGLConfig[] configs = new EGLConfig[mValue[0]];
if (GL2JNIView.DEBUG)
LOGW(String.format(Locale.getDefault(), "%d configurations", configs.length));
if (!EGL14.eglChooseConfig(display, configSpec, 0, configs,0, mValue[0], mValue, 0)) {
throw new IllegalArgumentException("Could not get config data");
}
for (int i = 0; i < configs.length; ++i) {
EGLConfig config = configs[i];
int d = findConfigAttrib(display, config, EGL14.EGL_DEPTH_SIZE, 0);
int s = findConfigAttrib(display, config, EGL14.EGL_STENCIL_SIZE, 0);
// We need at least mDepthSize and mStencilSize bits
if (d >= mDepthSize || s >= mStencilSize) {
// We want an *exact* match for red/green/blue/alpha
int r = findConfigAttrib(display, config, EGL14.EGL_RED_SIZE, 0);
int g = findConfigAttrib(display, config, EGL14.EGL_GREEN_SIZE, 0);
int b = findConfigAttrib(display, config, EGL14.EGL_BLUE_SIZE, 0);
int a = findConfigAttrib(display, config, EGL14.EGL_ALPHA_SIZE, 0);
if (r == mRedSize && g == mGreenSize && b == mBlueSize
&& a == mAlphaSize)
if (GL2JNIView.DEBUG) {
LOGW(String.format("Configuration %d:", i));
printConfig(display, configs[i]);
}
return config;
}
}
throw new IllegalArgumentException("Could not find suitable EGL config");
}
private int findConfigAttrib(EGLDisplay display, EGLConfig config, int defaultValue, int attribute) {
int[] value = new int[1];
if (EGL14.eglGetConfigAttrib(display, config, attribute, value, 0)) {
return value[0];
}
return defaultValue;
}
private void printConfig(EGLDisplay display, EGLConfig config)
{
final int[] attributes =
{
EGL14.EGL_BUFFER_SIZE,
EGL14.EGL_ALPHA_SIZE,
EGL14.EGL_BLUE_SIZE,
EGL14.EGL_GREEN_SIZE,
EGL14.EGL_RED_SIZE,
EGL14.EGL_DEPTH_SIZE,
EGL14.EGL_STENCIL_SIZE,
EGL14.EGL_CONFIG_CAVEAT,
EGL14.EGL_CONFIG_ID,
EGL14.EGL_LEVEL,
EGL14.EGL_MAX_PBUFFER_HEIGHT,
EGL14.EGL_MAX_PBUFFER_PIXELS,
EGL14.EGL_MAX_PBUFFER_WIDTH,
EGL14.EGL_NATIVE_RENDERABLE,
EGL14.EGL_NATIVE_VISUAL_ID,
EGL14.EGL_NATIVE_VISUAL_TYPE,
0x3030, // EGL14.EGL_PRESERVED_RESOURCES,
EGL14.EGL_SAMPLES,
EGL14.EGL_SAMPLE_BUFFERS,
EGL14.EGL_SURFACE_TYPE,
EGL14.EGL_TRANSPARENT_TYPE,
EGL14.EGL_TRANSPARENT_RED_VALUE,
EGL14.EGL_TRANSPARENT_GREEN_VALUE,
EGL14.EGL_TRANSPARENT_BLUE_VALUE,
EGL14.EGL_BIND_TO_TEXTURE_RGB,
EGL14.EGL_BIND_TO_TEXTURE_RGBA,
EGL14.EGL_MIN_SWAP_INTERVAL,
EGL14.EGL_MAX_SWAP_INTERVAL,
EGL14.EGL_LUMINANCE_SIZE,
EGL14.EGL_ALPHA_MASK_SIZE,
EGL14.EGL_COLOR_BUFFER_TYPE,
EGL14.EGL_RENDERABLE_TYPE,
EGL14.EGL_CONFORMANT
};
final String[] names =
{
"EGL_BUFFER_SIZE",
"EGL_ALPHA_SIZE",
"EGL_BLUE_SIZE",
"EGL_GREEN_SIZE",
"EGL_RED_SIZE",
"EGL_DEPTH_SIZE",
"EGL_STENCIL_SIZE",
"EGL_CONFIG_CAVEAT",
"EGL_CONFIG_ID",
"EGL_LEVEL",
"EGL_MAX_PBUFFER_HEIGHT",
"EGL_MAX_PBUFFER_PIXELS",
"EGL_MAX_PBUFFER_WIDTH",
"EGL_NATIVE_RENDERABLE",
"EGL_NATIVE_VISUAL_ID",
"EGL_NATIVE_VISUAL_TYPE",
"EGL_PRESERVED_RESOURCES",
"EGL_SAMPLES",
"EGL_SAMPLE_BUFFERS",
"EGL_SURFACE_TYPE",
"EGL_TRANSPARENT_TYPE",
"EGL_TRANSPARENT_RED_VALUE",
"EGL_TRANSPARENT_GREEN_VALUE",
"EGL_TRANSPARENT_BLUE_VALUE",
"EGL_BIND_TO_TEXTURE_RGB",
"EGL_BIND_TO_TEXTURE_RGBA",
"EGL_MIN_SWAP_INTERVAL",
"EGL_MAX_SWAP_INTERVAL",
"EGL_LUMINANCE_SIZE",
"EGL_ALPHA_MASK_SIZE",
"EGL_COLOR_BUFFER_TYPE",
"EGL_RENDERABLE_TYPE",
"EGL_CONFORMANT"
};
int[] value = new int[1];
for(int i=0 ; i<attributes.length ; i++)
if(EGL14.eglGetConfigAttrib(display, config, attributes[i], value,0))
LOGI(String.format(Locale.getDefault(), " %s: %d\n",names[i],value[0]));
else
while(EGL14.eglGetError() != EGL14.EGL_SUCCESS);
}
public EGLSurface createWindowSurface(EGLDisplay display, EGLConfig config, Window window) {
EGLSurface eglSurface = EGL14.eglCreateWindowSurface(display, config, window, null, 0);
return eglSurface;
}
public void destroySurface(EGLDisplay display, EGLSurface window) {
EGL14.eglDestroySurface(display, window);
}
}

View File

@ -8,7 +8,8 @@ public final class JNIdc
public static native void config(String dirName);
public static native void init(String fileName);
public static native void run(Object track);
public static native void stop();
public static native void pause();
public static native void destroy();
public static native int send(int cmd, int opt);
public static native int data(int cmd, byte[] data);
@ -26,7 +27,7 @@ public final class JNIdc
public static native void setupMic(Object sip);
public static native void diskSwap(String disk);
public static native void vmuSwap();
public static native void setupVmu(Object sip);
public static native void setupVmu(Object sip);
public static native void dynarec(int dynarec);
public static native void idleskip(int idleskip);
public static native void unstable(int unstable);
@ -42,7 +43,8 @@ public final class JNIdc
public static native void frameskip(int frames);
public static native void pvrrender(int render);
public static native void syncedrender(int sync);
public static native void cheatdisk(String disk);
public static native void modvols(int volumes);
public static native void bootdisk(String disk);
public static native void usereios(int reios);
public static native void dreamtime(long clock);
@ -51,6 +53,6 @@ public final class JNIdc
}
public static void hide_osd() {
JNIdc.vjoy(13, 0,0,0,0);
JNIdc.vjoy(13, 0,0,0,0);
}
}

View File

@ -106,11 +106,11 @@ public class OnScreenMenu {
popups.remove(window);
if (mContext instanceof GL2JNINative) {
((GL2JNINative) mContext)
.displayPopUp(((GL2JNINative) OnScreenMenu.this.mContext).popUp);
.displayPopUp(((GL2JNINative) OnScreenMenu.this.mContext).popUp);
}
if (mContext instanceof GL2JNIActivity) {
((GL2JNIActivity) mContext)
.displayPopUp(((GL2JNIActivity) OnScreenMenu.this.mContext).popUp);
.displayPopUp(((GL2JNIActivity) OnScreenMenu.this.mContext).popUp);
}
}
@ -130,7 +130,7 @@ public class OnScreenMenu {
};
Button buttonBack = (Button) hlay.findViewById(R.id.buttonBack);
addimg(buttonBack, R.drawable.up, clickBack);
OnClickListener clickClearCache = new OnClickListener() {
public void onClick(View v) {
JNIdc.send(0, 0); // Killing texture cache
@ -139,7 +139,7 @@ public class OnScreenMenu {
};
Button buttonCache = (Button) hlay.findViewById(R.id.buttonClearCache);
addimg(buttonCache, R.drawable.clear_cache, clickClearCache);
OnClickListener clickProfilerOne = new OnClickListener() {
public void onClick(View v) {
JNIdc.send(1, 3000); // sample_Start(param);
@ -148,7 +148,7 @@ public class OnScreenMenu {
};
Button buttonProfilerOne = (Button) hlay.findViewById(R.id.buttonProfilerOne);
addimg(buttonProfilerOne, R.drawable.profiler, clickProfilerOne);
OnClickListener clickProfilerTwo = new OnClickListener() {
public void onClick(View v) {
JNIdc.send(1, 0); // sample_Start(param);
@ -157,7 +157,7 @@ public class OnScreenMenu {
};
Button buttonProfilerTwo = (Button) hlay.findViewById(R.id.buttonProfilerTwo);
addimg(buttonProfilerTwo, R.drawable.profiler, clickProfilerTwo);
OnClickListener clickPrintStats = new OnClickListener() {
public void onClick(View v) {
JNIdc.send(0, 2);
@ -179,7 +179,7 @@ public class OnScreenMenu {
}
if (mContext instanceof GL2JNIActivity) {
((GL2JNIActivity) mContext)
.displayConfig(new ConfigPopup(mContext));
.displayConfig(new ConfigPopup(mContext));
}
}
@ -277,22 +277,22 @@ public class OnScreenMenu {
if (audio) {
if (mContext instanceof GL2JNINative) {
((GL2JNINative) mContext).mView
.audioDisable(true);
.audioDisable(true);
}
if (mContext instanceof GL2JNIActivity) {
((GL2JNIActivity) mContext).mView
.audioDisable(true);
.audioDisable(true);
}
audio = false;
addimg(audiosetting, R.drawable.enable_sound, this);
} else {
if (mContext instanceof GL2JNINative) {
((GL2JNINative) mContext).mView
.audioDisable(false);
.audioDisable(false);
}
if (mContext instanceof GL2JNIActivity) {
((GL2JNIActivity) mContext).mView
.audioDisable(false);
.audioDisable(false);
}
audio = true;
addimg(audiosetting, R.drawable.mute_sound, this);
@ -314,11 +314,11 @@ public class OnScreenMenu {
if (boosted) {
if (mContext instanceof GL2JNINative) {
((GL2JNINative) mContext).mView
.audioDisable(!audio);
.audioDisable(!audio);
}
if (mContext instanceof GL2JNIActivity) {
((GL2JNIActivity) mContext).mView
.audioDisable(!audio);
.audioDisable(!audio);
}
JNIdc.nosound(!audio ? 1 : 0);
audiosetting.setEnabled(true);
@ -331,7 +331,7 @@ public class OnScreenMenu {
}
if (mContext instanceof GL2JNIActivity) {
((GL2JNIActivity) mContext).mView
.fastForward(false);
.fastForward(false);
}
boosted = false;
addimg(fastforward, R.drawable.star, this);
@ -341,7 +341,7 @@ public class OnScreenMenu {
}
if (mContext instanceof GL2JNIActivity) {
((GL2JNIActivity) mContext).mView
.audioDisable(true);
.audioDisable(true);
}
JNIdc.nosound(1);
audiosetting.setEnabled(false);
@ -379,7 +379,7 @@ public class OnScreenMenu {
/**
* Toggle the frameskip button visibility by current value
*
*
* @param fdown
* The frameskip reduction button view
* @param fup
@ -417,7 +417,7 @@ public class OnScreenMenu {
return vmuLcd;
}
View addbut(int x, String l, OnClickListener ocl) {
View addbut(int x, String l, OnClickListener ocl) {
Button but = new Button(mContext);
Drawable image = mContext.getResources().getDrawable(x);
image.setBounds(0, 0, 72, 72);
@ -425,8 +425,8 @@ public class OnScreenMenu {
but.setOnClickListener(ocl);
return but;
}
Button addimg(Button but, int x, OnClickListener ocl) {
Button addimg(Button but, int x, OnClickListener ocl) {
Drawable image = mContext.getResources().getDrawable(x);
image.setBounds(0, 0, 72, 72);
but.setCompoundDrawables(image, null, null, null);
@ -461,7 +461,7 @@ public class OnScreenMenu {
vmuLcd.configureScale(96);
vlay.addView(vmuLcd, vparams);
}
public void hideVmu() {
vlay.removeView(vmuLcd);
}
@ -469,10 +469,10 @@ public class OnScreenMenu {
}
public class MainPopup extends PopupWindow {
private LinearLayout vmuIcon;
LinearLayout.LayoutParams params;
private LinearLayout.LayoutParams setVmuParams() {
int vpX = getPixelsFromDp(72, mContext);
int vpY = getPixelsFromDp(52, mContext);
@ -487,15 +487,15 @@ public class OnScreenMenu {
public MainPopup(Context c) {
super(c);
setBackgroundDrawable(new BitmapDrawable());
View shell = mContext.getLayoutInflater().inflate(R.layout.menu_popup_main, null);
ScrollView hlay = (ScrollView) shell.findViewById(R.id.menuMain);
vmuIcon = (LinearLayout) hlay.findViewById(R.id.vmuIcon);
vmuLcd.configureScale(72);
params = setVmuParams();
vmuIcon.addView(vmuLcd, params);
OnClickListener clickDisk = new OnClickListener() {
public void onClick(View v) {
JNIdc.diskSwap(null);
@ -513,7 +513,7 @@ public class OnScreenMenu {
};
Button buttonVmuSwap = (Button) hlay.findViewById(R.id.buttonVmuSwap);
addimg(buttonVmuSwap, R.drawable.vmu_swap, clickVmuSwap);
OnClickListener clickOptions = new OnClickListener() {
public void onClick(View v) {
displayConfigPopup(MainPopup.this);
@ -523,7 +523,7 @@ public class OnScreenMenu {
};
Button buttonOptions = (Button) hlay.findViewById(R.id.buttonOptions);
addimg(buttonOptions, R.drawable.config, clickOptions);
OnClickListener clickDebugging = new OnClickListener() {
public void onClick(View v) {
displayDebugPopup(MainPopup.this);
@ -533,7 +533,7 @@ public class OnScreenMenu {
};
Button buttonDebugging = (Button) hlay.findViewById(R.id.buttonDebugging);
addimg(buttonDebugging, R.drawable.disk_unknown, clickDebugging);
OnClickListener clickScreenshot = new OnClickListener() {
public void onClick(View v) {
// screenshot
@ -549,7 +549,7 @@ public class OnScreenMenu {
};
Button buttonScreenshot = (Button) hlay.findViewById(R.id.buttonScreenshot);
addimg(buttonScreenshot, R.drawable.print_stats, clickScreenshot);
OnClickListener clickExit = new OnClickListener() {
public void onClick(View v) {
if (Config.externalIntent) {
@ -567,11 +567,11 @@ public class OnScreenMenu {
setContentView(shell);
setFocusable(true);
}
public void hideVmu() {
vmuIcon.removeView(vmuLcd);
}
public void showVmu() {
vmuLcd.configureScale(72);
params = setVmuParams();

View File

@ -71,7 +71,7 @@ public class Gamepad {
// public boolean isNvidiaShield;
public static final int Xperia_Touchpad = 1048584;
public static final int key_CONT_B = 0x0002;
public static final int key_CONT_A = 0x0004;
public static final int key_CONT_START = 0x0008;
@ -131,12 +131,12 @@ public class Gamepad {
getStartButtonCode(), key_CONT_START,
getSelectButtonCode(), getSelectButtonCode()
};
};
}
public int[] setModifiedKeys(String id, int playerNum, SharedPreferences mPrefs) {
return new int[] {
mPrefs.getInt(pref_button_a + id, OuyaController.BUTTON_O), key_CONT_A,
return new int[] {
mPrefs.getInt(pref_button_a + id, OuyaController.BUTTON_O), key_CONT_A,
mPrefs.getInt(pref_button_b + id, OuyaController.BUTTON_A), key_CONT_B,
mPrefs.getInt(pref_button_x + id, OuyaController.BUTTON_U), key_CONT_X,
mPrefs.getInt(pref_button_y + id, OuyaController.BUTTON_Y), key_CONT_Y,
@ -161,7 +161,7 @@ public class Gamepad {
return pMan.hasSystemFeature(PackageManager.FEATURE_TELEVISION)
|| OuyaFacade.getInstance().isRunningOnOUYAHardware();
}
public int getStartButtonCode() {
return KeyEvent.KEYCODE_BUTTON_START;
}
@ -175,7 +175,7 @@ public class Gamepad {
|| android.os.Build.DEVICE.equals("roth")
|| android.os.Build.PRODUCT.equals("thor");
}
public void setCustomMapping(String id, int playerNum, SharedPreferences prefs) {
map[playerNum] = setModifiedKeys(id, playerNum, prefs);
}
@ -186,7 +186,7 @@ public class Gamepad {
globalLS_Y[playerNum] = previousLS_Y[playerNum] = 0.0f;
}
}
public void runCompatibilityMode(int joy, SharedPreferences prefs) {
for (int n = 0; n < 4; n++) {
if (compat[n]) {
@ -197,7 +197,7 @@ public class Gamepad {
}
}
}
public void fullCompatibilityMode(SharedPreferences prefs) {
for (int n = 0; n < 4; n++) {
runCompatibilityMode(n, prefs);

View File

@ -25,13 +25,13 @@ import java.util.Arrays;
/*
*/
*/
public final class MOGAInput
{
private SharedPreferences prefs;
static final int DELAY = 1000 / 50; // 50 Hz
public static final int ACTION_CONNECTED = Controller.ACTION_CONNECTED;
static final int ACTION_DISCONNECTED = Controller.ACTION_DISCONNECTED;
static final int ACTION_VERSION_MOGA = Controller.ACTION_VERSION_MOGA;
@ -134,11 +134,11 @@ public final class MOGAInput
public class ExampleControllerListener implements ControllerListener
{
int playerNum;
public void setPlayerNum(int playerNum) {
this.playerNum = playerNum;
}
public void onKeyEvent(KeyEvent event)
{
boolean keydown = false;

View File

@ -1,21 +1,21 @@
/**
* 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.reicast.emulator.periph;
@ -37,11 +37,11 @@ import java.util.List;
* 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>
@ -50,7 +50,7 @@ public class MogaHack
{
public static void init( Controller controller, Context context )
{
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT)
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT)
{
boolean mIsBound = false;
java.lang.reflect.Field fIsBound = null;
@ -64,7 +64,7 @@ public class MogaHack
mIsBound = fIsBound.getBoolean( controller );
fServiceConnection = cMogaController.getDeclaredField( "mServiceConnection" );
fServiceConnection.setAccessible( true );
mServiceConnection = ( android.content.ServiceConnection ) fServiceConnection.get( controller );
mServiceConnection = ( android.content.ServiceConnection ) fServiceConnection.get( controller );
}
catch( NoSuchFieldException e )
{
@ -92,7 +92,7 @@ public class MogaHack
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 );

View File

@ -8,19 +8,19 @@ import android.util.Log;
import java.util.concurrent.ConcurrentLinkedQueue;
public class SipEmulator extends Thread {
static final String TAG = "SipEmulator";
//one second of audio data in bytes
static final int BUFFER_SIZE = 22050;
//this needs to get set to the amount the mic normally sends per data request
//...cant be bigger than a maple packet
// 240 16 (or 14) bit samples
static final int ONE_BLIP_SIZE = 480; //ALSO DEFINED IN maple_devs.h
private AudioRecord record;
private ConcurrentLinkedQueue<byte[]> bytesReadBuffer;
private boolean continueRecording;
private boolean firstGet;
@ -29,31 +29,31 @@ public class SipEmulator extends Thread {
== 176.4 kbit/s
== 22050 bytes/s
*/
public SipEmulator(){
Log.d(TAG, "SipEmulator constructor called");
init();
}
private void init(){
Log.d(TAG, "SipEmulator init called");
record = new AudioRecord(
MediaRecorder.AudioSource.VOICE_RECOGNITION,
11025,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT,
MediaRecorder.AudioSource.VOICE_RECOGNITION,
11025,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT,
BUFFER_SIZE);
bytesReadBuffer = new ConcurrentLinkedQueue<byte[]>();
continueRecording = false;
firstGet = true;
}
public void startRecording(){
Log.d(TAG, "SipEmulator startRecording called");
if(continueRecording){
@ -63,13 +63,13 @@ public class SipEmulator extends Thread {
continueRecording = true;
this.start();
}
public void stopRecording(){
Log.d(TAG, "SipEmulator stopRecording called");
continueRecording = false;
record.stop();
}
public byte[] getData(){
//Log.d(TAG, "SipEmulator getData called");
//Log.d(TAG, "SipEmulator getData bytesReadBuffer size: "+bytesReadBuffer.size());
@ -79,26 +79,26 @@ public class SipEmulator extends Thread {
}
return bytesReadBuffer.poll();
}
private byte[] catchUp(){
Log.d(TAG, "SipEmulator catchUp");
byte[] last = bytesReadBuffer.poll();
bytesReadBuffer.clear();
return last;
}
public void configSomething(int what, int setting){
Log.d(TAG, "SipEmulator configSomething called");
}
public void run() {
Log.d(TAG, "recordThread starting");
while(continueRecording){
byte[] freshData = new byte[ONE_BLIP_SIZE];
// read blocks
record.read(freshData, 0, ONE_BLIP_SIZE);
record.read(freshData, 0, ONE_BLIP_SIZE);
if(!firstGet){
bytesReadBuffer.add(freshData);
}

View File

@ -0,0 +1,164 @@
package com.reicast.emulator.periph;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
public class VJoy {
public static final int key_CONT_B = 0x0002;
public static final int key_CONT_A = 0x0004;
public static final int key_CONT_START = 0x0008;
public static final int key_CONT_DPAD_UP = 0x0010;
public static final int key_CONT_DPAD_DOWN = 0x0020;
public static final int key_CONT_DPAD_LEFT = 0x0040;
public static final int key_CONT_DPAD_RIGHT = 0x0080;
public static final int key_CONT_Y = 0x0200;
public static final int key_CONT_X = 0x0400;
public static final int LAYER_TYPE_SOFTWARE = 1;
public static final int LAYER_TYPE_HARDWARE = 2;
public static int VJoyCount = 13;
public static float[][] baseVJoy() {
return new float[][] {
new float[] { 24+0, 24+64, 64,64, VJoy.key_CONT_DPAD_LEFT, 0},
new float[] { 24+64, 24+0, 64,64, VJoy.key_CONT_DPAD_UP, 0},
new float[] { 24+128, 24+64, 64,64, VJoy.key_CONT_DPAD_RIGHT, 0},
new float[] { 24+64, 24+128, 64,64, VJoy.key_CONT_DPAD_DOWN, 0},
new float[] { 440+0, 280+64, 64,64, VJoy.key_CONT_X, 0},
new float[] { 440+64, 280+0, 64,64, VJoy.key_CONT_Y, 0},
new float[] { 440+128, 280+64, 64,64, VJoy.key_CONT_B, 0},
new float[] { 440+64, 280+128, 64,64, VJoy.key_CONT_A, 0},
new float[] { 320-32, 360+32, 64,64, VJoy.key_CONT_START, 0},
new float[] { 440, 200, 90,64, -1, 0},
new float[] { 542, 200, 90,64, -2, 0},
new float[] { 0, 128+224, 128,128, -3, 0},
new float[] { 96, 320, 32,32, -4, 0},
new float[] { 20+0 , 288+0 , 64,64, key_CONT_DPAD_LEFT|key_CONT_DPAD_UP, 0},
new float[] { 20+128, 288+0 , 64,64, key_CONT_DPAD_RIGHT|key_CONT_DPAD_UP, 0},
new float[] { 20+0 , 288+128, 64,64, key_CONT_DPAD_LEFT|key_CONT_DPAD_DOWN, 0},
new float[] { 20+128, 288+128, 64,64, key_CONT_DPAD_RIGHT|key_CONT_DPAD_DOWN, 0},
};
}
public static float[][] readCustomVjoyValues(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return new float[][] {
// x-shift, y-shift, sizing-factor
new float[] { prefs.getFloat("touch_x_shift_dpad", 0),
prefs.getFloat("touch_y_shift_dpad", 0),
prefs.getFloat("touch_scale_dpad", 1)
}, // DPAD
new float[] { prefs.getFloat("touch_x_shift_buttons", 0),
prefs.getFloat("touch_y_shift_buttons", 0),
prefs.getFloat("touch_scale_buttons", 1)
}, // X, Y, B, A Buttons
new float[] { prefs.getFloat("touch_x_shift_start", 0),
prefs.getFloat("touch_y_shift_start", 0),
prefs.getFloat("touch_scale_start", 1)
}, // Start
new float[] { prefs.getFloat("touch_x_shift_left_trigger", 0),
prefs.getFloat("touch_y_shift_left_trigger", 0),
prefs.getFloat("touch_scale_left_trigger", 1)
}, // Left Trigger
new float[] { prefs.getFloat("touch_x_shift_right_trigger", 0),
prefs.getFloat("touch_y_shift_right_trigger", 0),
prefs.getFloat("touch_scale_right_trigger", 1)
}, // Right Trigger
new float[] { prefs.getFloat("touch_x_shift_analog", 0),
prefs.getFloat("touch_y_shift_analog", 0),
prefs.getFloat("touch_scale_analog", 1)
} // Analog Stick
};
}
public static float[][] getVjoy_d(float[][] vjoy_d_custom) {
return new float[][] {
new float[] { 20+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+64*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_LEFT},
new float[] { 20+64*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_UP},
new float[] { 20+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+64*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_RIGHT},
new float[] { 20+64*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_DOWN},
new float[] { 448+0*vjoy_d_custom[1][2]+vjoy_d_custom[1][0], 288+64*vjoy_d_custom[1][2]+vjoy_d_custom[1][1], 64*vjoy_d_custom[1][2],64*vjoy_d_custom[1][2], key_CONT_X},
new float[] { 448+64*vjoy_d_custom[1][2]+vjoy_d_custom[1][0], 288+0*vjoy_d_custom[1][2]+vjoy_d_custom[1][1], 64*vjoy_d_custom[1][2],64*vjoy_d_custom[1][2], key_CONT_Y},
new float[] { 448+128*vjoy_d_custom[1][2]+vjoy_d_custom[1][0], 288+64*vjoy_d_custom[1][2]+vjoy_d_custom[1][1], 64*vjoy_d_custom[1][2],64*vjoy_d_custom[1][2], key_CONT_B},
new float[] { 448+64*vjoy_d_custom[1][2]+vjoy_d_custom[1][0], 288+128*vjoy_d_custom[1][2]+vjoy_d_custom[1][1], 64*vjoy_d_custom[1][2],64*vjoy_d_custom[1][2], key_CONT_A},
new float[] { 320-32+vjoy_d_custom[2][0], 288+128+vjoy_d_custom[2][1], 64*vjoy_d_custom[2][2],64*vjoy_d_custom[2][2], key_CONT_START},
new float[] { 440+vjoy_d_custom[3][0], 200+vjoy_d_custom[3][1], 90*vjoy_d_custom[3][2],64*vjoy_d_custom[3][2], -1},
new float[] { 542+vjoy_d_custom[4][0], 200+vjoy_d_custom[4][1], 90*vjoy_d_custom[4][2],64*vjoy_d_custom[4][2], -2},
new float[] { 16+vjoy_d_custom[5][0], 24+32+vjoy_d_custom[5][1], 128*vjoy_d_custom[5][2],128*vjoy_d_custom[5][2], -3},
new float[] { 96+vjoy_d_custom[5][0], 320+vjoy_d_custom[5][1], 32*vjoy_d_custom[5][2],32*vjoy_d_custom[5][2], -4},
new float[] { 20+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_LEFT|key_CONT_DPAD_UP},
new float[] { 20+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_RIGHT|key_CONT_DPAD_UP},
new float[] { 20+0*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_LEFT|key_CONT_DPAD_DOWN},
new float[] { 20+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][0], 288+128*vjoy_d_custom[0][2]+vjoy_d_custom[0][1], 64*vjoy_d_custom[0][2],64*vjoy_d_custom[0][2], key_CONT_DPAD_RIGHT|key_CONT_DPAD_DOWN},
};
}
public static void writeCustomVjoyValues(float[][] vjoy_d_custom, Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
prefs.edit().putFloat("touch_x_shift_dpad", vjoy_d_custom[0][0]).apply();
prefs.edit().putFloat("touch_y_shift_dpad", vjoy_d_custom[0][1]).apply();
prefs.edit().putFloat("touch_scale_dpad", vjoy_d_custom[0][2]).apply();
prefs.edit().putFloat("touch_x_shift_buttons", vjoy_d_custom[1][0]).apply();
prefs.edit().putFloat("touch_y_shift_buttons", vjoy_d_custom[1][1]).apply();
prefs.edit().putFloat("touch_scale_buttons", vjoy_d_custom[1][2]).apply();
prefs.edit().putFloat("touch_x_shift_start", vjoy_d_custom[2][0]).apply();
prefs.edit().putFloat("touch_y_shift_start", vjoy_d_custom[2][1]).apply();
prefs.edit().putFloat("touch_scale_start", vjoy_d_custom[2][2]).apply();
prefs.edit().putFloat("touch_x_shift_left_trigger", vjoy_d_custom[3][0]).apply();
prefs.edit().putFloat("touch_y_shift_left_trigger", vjoy_d_custom[3][1]).apply();
prefs.edit().putFloat("touch_scale_left_trigger", vjoy_d_custom[3][2]).apply();
prefs.edit().putFloat("touch_x_shift_right_trigger", vjoy_d_custom[4][0]).apply();
prefs.edit().putFloat("touch_y_shift_right_trigger", vjoy_d_custom[4][1]).apply();
prefs.edit().putFloat("touch_scale_right_trigger", vjoy_d_custom[4][2]).apply();
prefs.edit().putFloat("touch_x_shift_analog", vjoy_d_custom[5][0]).apply();
prefs.edit().putFloat("touch_y_shift_analog", vjoy_d_custom[5][1]).apply();
prefs.edit().putFloat("touch_scale_analog", vjoy_d_custom[5][2]).apply();
}
public static void resetCustomVjoyValues(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
prefs.edit().remove("touch_x_shift_dpad").apply();
prefs.edit().remove("touch_y_shift_dpad").apply();
prefs.edit().remove("touch_scale_dpad").apply();
prefs.edit().remove("touch_x_shift_buttons").apply();
prefs.edit().remove("touch_y_shift_buttons").apply();
prefs.edit().remove("touch_scale_buttons").apply();
prefs.edit().remove("touch_x_shift_start").apply();
prefs.edit().remove("touch_y_shift_start").apply();
prefs.edit().remove("touch_scale_start").apply();
prefs.edit().remove("touch_x_shift_left_trigger").apply();
prefs.edit().remove("touch_y_shift_left_trigger").apply();
prefs.edit().remove("touch_scale_left_trigger").apply();
prefs.edit().remove("touch_x_shift_right_trigger").apply();
prefs.edit().remove("touch_y_shift_right_trigger").apply();
prefs.edit().remove("touch_scale_right_trigger").apply();
prefs.edit().remove("touch_x_shift_analog").apply();
prefs.edit().remove("touch_y_shift_analog").apply();
prefs.edit().remove("touch_scale_analog").apply();
}
}

View File

@ -11,26 +11,26 @@ import android.view.View;
import com.reicast.emulator.emu.OnScreenMenu;
public class VmuLcd extends View {
public final static int w = 48;
public final static int h = 32;
private int[] image = new int[w*h];
private Bitmap current = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
private float scale;
private Paint paint;
public VmuLcd(Context context) {
super(context);
paint = new Paint();
scale = (float)OnScreenMenu.getPixelsFromDp(60, getContext()) / w;
Log.d("VmuLcd", "scale: "+scale);
}
public void configureScale(int dp) {
scale = (float)OnScreenMenu.getPixelsFromDp(dp, getContext()) / w;
}
public void updateBytes(byte[] data){
for(int i=0; i<h; i++){
for(int j=0; j<w; j++){

View File

@ -1,3 +1,4 @@
APP_STL := c++_static
APP_ABI := armeabi-v7a x86 #mips
#NDK_TOOLCHAIN_VERSION := 4.8
APP_SHORT_COMMANDS := true

View File

@ -25,7 +25,8 @@ extern "C"
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_config(JNIEnv *env,jobject obj,jstring dirName) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_init(JNIEnv *env,jobject obj,jstring fileName) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_run(JNIEnv *env,jobject obj,jobject emu_thread) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_stop(JNIEnv *env,jobject obj) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_pause(JNIEnv *env,jobject obj) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_destroy(JNIEnv *env,jobject obj) __attribute__((visibility("default")));
JNIEXPORT jint JNICALL Java_com_reicast_emulator_emu_JNIdc_send(JNIEnv *env,jobject obj,jint id, jint v) __attribute__((visibility("default")));
JNIEXPORT jint JNICALL Java_com_reicast_emulator_emu_JNIdc_data(JNIEnv *env,jobject obj,jint id, jbyteArray d) __attribute__((visibility("default")));
@ -59,7 +60,8 @@ extern "C"
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_frameskip(JNIEnv *env,jobject obj, jint frames) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_pvrrender(JNIEnv *env,jobject obj, jint render) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_syncedrender(JNIEnv *env,jobject obj, jint sync) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_cheatdisk(JNIEnv *env,jobject obj, jstring disk) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_modvols(JNIEnv *env,jobject obj, jint volumes) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_bootdisk(JNIEnv *env,jobject obj, jstring disk) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_usereios(JNIEnv *env,jobject obj, jint reios) __attribute__((visibility("default")));
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_dreamtime(JNIEnv *env,jobject obj, jlong clock) __attribute__((visibility("default")));
};
@ -139,7 +141,12 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_syncedrender(JNIEnv *
settings.pvr.SynchronousRendering = sync;
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_cheatdisk(JNIEnv *env,jobject obj, jstring disk)
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_modvols(JNIEnv *env,jobject obj, jint volumes)
{
settings.rend.ModifierVolumes = volumes;
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_bootdisk(JNIEnv *env,jobject obj, jstring disk)
{
}
@ -158,6 +165,7 @@ void egl_stealcntx();
void SetApplicationPath(wchar *path);
int dc_init(int argc,wchar* argv[]);
void dc_run();
void dc_pause();
void dc_term();
void mcfg_Create(MapleDeviceType type,u32 bus,u32 port);
@ -368,7 +376,12 @@ JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_setupVmu(JNIEnv *env,
//jpix=env->NewByteArray(1536);
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_stop(JNIEnv *env,jobject obj)
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_pause(JNIEnv *env,jobject obj)
{
dc_pause();
}
JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_destroy(JNIEnv *env,jobject obj)
{
dc_term();
}

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Some files were not shown because too many files have changed in this diff Show More