Hello community,

here is the log from the commit of package libretro-handy for openSUSE:Factory 
checked in at 2020-08-17 12:01:14
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libretro-handy (Old)
 and      /work/SRC/openSUSE:Factory/.libretro-handy.new.3399 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libretro-handy"

Mon Aug 17 12:01:14 2020 rev:2 rq:826803 version:0~git20200625

Changes:
--------
--- /work/SRC/openSUSE:Factory/libretro-handy/libretro-handy.changes    
2020-02-11 22:24:08.671526127 +0100
+++ /work/SRC/openSUSE:Factory/.libretro-handy.new.3399/libretro-handy.changes  
2020-08-17 12:01:38.662569343 +0200
@@ -1,0 +2,10 @@
+Sat Aug 08 09:53:47 UTC 2020 - i...@guoyunhe.me
+
+- Update to version 0~git20200625:
+  * libretro: Add CORE_DIR to include path
+  * color depth no restart, add 555 format
+  * use blargg blip buffer
+  * fix superclip renderer
+  * fix mikie irq
+
+-------------------------------------------------------------------

Old:
----
  libretro-handy-0~git20200107.tar.xz

New:
----
  libretro-handy-0~git20200625.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libretro-handy.spec ++++++
--- /var/tmp/diff_new_pack.npnDNO/_old  2020-08-17 12:01:40.370570295 +0200
+++ /var/tmp/diff_new_pack.npnDNO/_new  2020-08-17 12:01:40.370570295 +0200
@@ -17,10 +17,10 @@
 
 
 Name:           libretro-handy
-Version:        0~git20200107
+Version:        0~git20200625
 Release:        0
 Summary:        Handy libretro core for Atari Lynx
-License:        GPL-2.0
+License:        GPL-2.0-only
 URL:            http://www.retroarch.com
 Source:         %{name}-%{version}.tar.xz
 

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.npnDNO/_old  2020-08-17 12:01:40.422570324 +0200
+++ /var/tmp/diff_new_pack.npnDNO/_new  2020-08-17 12:01:40.422570324 +0200
@@ -3,4 +3,4 @@
                 <param name="url">https://github.com/libretro/mgba.git</param>
               <param 
name="changesrevision">24fb0a5ba23689aa4c0c9620ae6b5659d419fefb</param></service><service
 name="tar_scm">
                 <param 
name="url">https://github.com/libretro/libretro-handy.git</param>
-              <param 
name="changesrevision">10f515163f875af5bd20c5170cb1ce7139de6fe4</param></service></servicedata>
\ No newline at end of file
+              <param 
name="changesrevision">128a3cdbdefa2d88168473290a45e1eaee97130b</param></service></servicedata>
\ No newline at end of file

++++++ libretro-handy-0~git20200107.tar.xz -> 
libretro-handy-0~git20200625.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libretro-handy-0~git20200107/Makefile 
new/libretro-handy-0~git20200625/Makefile
--- old/libretro-handy-0~git20200107/Makefile   2020-01-07 17:39:39.000000000 
+0100
+++ new/libretro-handy-0~git20200625/Makefile   2020-06-25 22:54:05.000000000 
+0200
@@ -1,3 +1,6 @@
+DEBUG = 0
+FRONTEND_SUPPORTS_RGB565 = 1
+
 TARGET_NAME := handy
 GIT_VERSION := " $(shell git rev-parse --short HEAD || echo unknown)"
 ifneq ($(GIT_VERSION)," unknown")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libretro-handy-0~git20200107/Makefile.common 
new/libretro-handy-0~git20200625/Makefile.common
--- old/libretro-handy-0~git20200107/Makefile.common    2020-01-07 
17:39:39.000000000 +0100
+++ new/libretro-handy-0~git20200625/Makefile.common    2020-06-25 
22:54:05.000000000 +0200
@@ -1,10 +1,13 @@
-LIBRETRO_COMM_DIR  = $(CORE_DIR)/libretro-common
-
 INCFLAGS = -I$(CORE_DIR)/lynx \
-                         -I$(CORE_DIR)/libretro
+           -I$(CORE_DIR)/libretro \
+           -I$(CORE_DIR)
 
 ifneq (,$(findstring msvc2003,$(platform)))
-INCFLAGS += -I$(LIBRETRO_COMM_DIR)/include/compat/msvc
+   INCFLAGS += -I$(LIBRETRO_COMM_DIR)/include/compat/msvc
+endif
+
+ifeq ($(FRONTEND_SUPPORTS_RGB565), 1)
+   FLAGS += -DFRONTEND_SUPPORTS_RGB565
 endif
 
 SOURCES_CXX := $(CORE_DIR)/lynx/lynxdec.cpp \
@@ -16,4 +19,6 @@
        $(CORE_DIR)/lynx/susie.cpp \
        $(CORE_DIR)/lynx/system.cpp \
        $(CORE_DIR)/lynx/eeprom.cpp \
-       $(CORE_DIR)/libretro/libretro.cpp
+       $(CORE_DIR)/libretro/libretro.cpp \
+       $(CORE_DIR)/blip/Blip_Buffer.cpp \
+       $(CORE_DIR)/blip/Stereo_Buffer.cpp
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libretro-handy-0~git20200107/blip/Blip_Buffer.cpp 
new/libretro-handy-0~git20200625/blip/Blip_Buffer.cpp
--- old/libretro-handy-0~git20200107/blip/Blip_Buffer.cpp       1970-01-01 
01:00:00.000000000 +0100
+++ new/libretro-handy-0~git20200625/blip/Blip_Buffer.cpp       2020-06-25 
22:54:05.000000000 +0200
@@ -0,0 +1,240 @@
+// Blip_Buffer 0.4.1. http://www.slack.net/~ant/
+
+#include <blip/Blip_Buffer.h>
+
+#include <assert.h>
+#include <climits>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+
+/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
+can redistribute it and/or modify it under the terms of the GNU Lesser
+General Public License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version. This
+module 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 Lesser General Public License for more
+details. You should have received a copy of the GNU Lesser General Public
+License along with this module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#ifdef BLARGG_ENABLE_OPTIMIZER
+       #include BLARGG_ENABLE_OPTIMIZER
+#endif
+
+Blip_Buffer::Blip_Buffer()
+{
+       factor_       = (blip_u64)ULLONG_MAX;
+       offset_       = 0;
+       buffer_       = 0;
+       buffer_size_  = 0;
+       sample_rate_  = 0;
+       reader_accum_ = 0;
+       bass_shift_   = 0;
+       clock_rate_   = 0;
+       bass_freq_    = 16;
+       length_       = 0;
+}
+
+Blip_Buffer::~Blip_Buffer()
+{
+   if (buffer_)
+      free( buffer_ );
+}
+
+void Blip_Buffer::clear( int entire_buffer )
+{
+       offset_      = 0;
+       reader_accum_ = 0;
+       modified_    = 0;
+       if ( buffer_ )
+       {
+               long count = (entire_buffer ? buffer_size_ : samples_avail());
+               memset( buffer_, 0, (count + blip_buffer_extra_) * sizeof 
(buf_t_) );
+       }
+}
+
+Blip_Buffer::blargg_err_t Blip_Buffer::set_sample_rate( long new_rate, int 
msec )
+{
+       // start with maximum length that resampled time can represent
+       blip_s64 new_size = (ULLONG_MAX >> BLIP_BUFFER_ACCURACY) - 
blip_buffer_extra_ - 64;
+
+       // simple safety check, since code elsewhere may not be safe for sizes 
approaching (2 ^ 31).
+       if(new_size > ((1LL << 30) - 1))
+        new_size = (1LL << 30) - 1;
+
+       if ( msec != blip_max_length )
+       {
+               blip_s64 s = ((blip_s64)new_rate * (msec + 1) + 999) / 1000;
+               if ( s < new_size )
+                       new_size = s;
+               else
+                       assert( 0 ); // fails if requested buffer length 
exceeds limit
+       }
+       
+       if ( buffer_size_ != new_size )
+       {
+               void* p = realloc( buffer_, (new_size + blip_buffer_extra_) * 
sizeof *buffer_ );
+               if ( !p )
+                       return "Out of memory";
+
+               buffer_ = (buf_t_*) p;
+       }
+       
+       buffer_size_ = new_size;
+       
+       // update things based on the sample rate
+       sample_rate_ = new_rate;
+       length_ = new_size * 1000 / new_rate - 1;
+       if ( msec )
+               assert( length_ == msec ); // ensure length is same as that 
passed in
+       if ( clock_rate_ )
+               clock_rate( clock_rate_ );
+       bass_freq( bass_freq_ );
+       
+       clear();
+       
+       return 0; // success
+}
+
+blip_resampled_time_t Blip_Buffer::clock_rate_factor( long rate ) const
+{
+       double ratio = (double) sample_rate_ / rate;
+       blip_s64 factor = (blip_s64) floor( ratio * (1LL << 
BLIP_BUFFER_ACCURACY) + 0.5 );
+       assert( factor > 0 || !sample_rate_ ); // fails if clock/output ratio 
is too large
+       return (blip_resampled_time_t) factor;
+}
+
+void Blip_Buffer::bass_freq( int freq )
+{
+       bass_freq_ = freq;
+       int shift = 31;
+       if ( freq > 0 )
+       {
+               shift = 13;
+               long f = (freq << 16) / sample_rate_;
+               while ( (f >>= 1) && --shift ) { }
+       }
+       bass_shift_ = shift;
+}
+
+void Blip_Buffer::end_frame( blip_time_t t )
+{
+       offset_ += t * factor_;
+       assert( samples_avail() <= (long) buffer_size_ ); // time outside 
buffer length
+}
+
+void Blip_Buffer::remove_silence( long count )
+{
+       assert( count <= samples_avail() ); // tried to remove more samples 
than available
+       offset_ -= (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY;
+}
+
+long Blip_Buffer::count_samples( blip_time_t t ) const
+{
+       unsigned long last_sample  = resampled_time( t ) >> 
BLIP_BUFFER_ACCURACY;
+       unsigned long first_sample = offset_ >> BLIP_BUFFER_ACCURACY;
+       return (long) (last_sample - first_sample);
+}
+
+blip_time_t Blip_Buffer::count_clocks( long count ) const
+{
+       if ( !factor_ )
+       {
+               assert( 0 ); // sample rate and clock rates must be set first
+               return 0;
+       }
+       
+       if ( count > buffer_size_ )
+               count = buffer_size_;
+       blip_resampled_time_t time = (blip_resampled_time_t) count << 
BLIP_BUFFER_ACCURACY;
+       return (blip_time_t) ((time - offset_ + factor_ - 1) / factor_);
+}
+
+void Blip_Buffer::remove_samples( long count )
+{
+       if ( count )
+       {
+               remove_silence( count );
+               
+               // copy remaining samples to beginning and clear old samples
+               long remain = samples_avail() + blip_buffer_extra_;
+               memmove( buffer_, buffer_ + count, remain * sizeof *buffer_ );
+               memset( buffer_ + remain, 0, count * sizeof *buffer_ );
+       }
+}
+
+// Blip_Synth_
+
+Blip_Synth_Fast_::Blip_Synth_Fast_()
+{
+       buf = 0;
+       last_amp = 0;
+       delta_factor = 0;
+}
+
+void Blip_Synth_Fast_::volume_unit( double new_unit )
+{
+       delta_factor = int (new_unit * (1L << blip_sample_bits) + 0.5);
+}
+
+long Blip_Buffer::read_samples( blip_sample_t* BLIP_RESTRICT out, long 
max_samples, int stereo )
+{
+       long count = samples_avail();
+       if ( count > max_samples )
+               count = max_samples;
+       
+       if ( count )
+       {
+               int const bass = BLIP_READER_BASS( *this );
+               BLIP_READER_BEGIN( reader, *this );
+               
+#ifndef WANT_STEREO_SOUND
+               if ( !stereo )
+               {
+                       for ( blip_long n = count; n; --n )
+                       {
+                               blip_long s = BLIP_READER_READ( reader );
+                               if ( (blip_sample_t) s != s )
+                                       s = 0x7FFF - (s >> 24);
+                               *out++ = (blip_sample_t) s;
+                               BLIP_READER_NEXT( reader, bass );
+                       }
+               }
+               else
+#endif
+               {
+                       for ( blip_long n = count; n; --n )
+                       {
+                               blip_long s = BLIP_READER_READ( reader );
+                               if ( (blip_sample_t) s != s )
+                                       s = 0x7FFF - (s >> 24);
+                               *out = (blip_sample_t) s;
+                               out += 2;
+                               BLIP_READER_NEXT( reader, bass );
+                       }
+               }
+               BLIP_READER_END( reader, *this );
+               
+               remove_samples( count );
+       }
+       return count;
+}
+
+void Blip_Buffer::mix_samples( blip_sample_t const* in, long count )
+{
+       buf_t_* out = buffer_ + (offset_ >> BLIP_BUFFER_ACCURACY) + 
blip_widest_impulse_ / 2;
+       
+       int const sample_shift = blip_sample_bits - 16;
+       int prev = 0;
+       while ( count-- )
+       {
+               blip_long s = (blip_long) *in++ << sample_shift;
+               *out += s - prev;
+               prev = s;
+               ++out;
+       }
+       *out -= prev;
+}
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libretro-handy-0~git20200107/blip/Blip_Buffer.h 
new/libretro-handy-0~git20200625/blip/Blip_Buffer.h
--- old/libretro-handy-0~git20200107/blip/Blip_Buffer.h 1970-01-01 
01:00:00.000000000 +0100
+++ new/libretro-handy-0~git20200625/blip/Blip_Buffer.h 2020-06-25 
22:54:05.000000000 +0200
@@ -0,0 +1,384 @@
+// Band-limited sound synthesis buffer
+// Various changes and hacks for use in Mednafen.
+
+#ifdef __GNUC__
+ #define blip_inline inline __attribute__((always_inline))
+#else
+ #define blip_inline inline
+#endif
+
+#include <limits.h>
+#include <stdint.h>
+
+// Blip_Buffer 0.4.1
+#ifndef BLIP_BUFFER_H
+#define BLIP_BUFFER_H
+
+// Internal
+typedef int32_t blip_long;
+typedef uint32_t blip_ulong;
+typedef int64_t blip_s64;
+typedef uint64_t blip_u64;
+
+// Time unit at source clock rate
+typedef blip_long blip_time_t;
+
+// Output samples are 16-bit signed, with a range of -32768 to 32767
+typedef short blip_sample_t;
+enum { blip_sample_max = 32767 };
+
+class Blip_Buffer {
+public:
+       typedef const char* blargg_err_t;
+       
+       // Set output sample rate and buffer length in milliseconds (1/1000 
sec, defaults
+       // to 1/4 second), then clear buffer. Returns NULL on success, 
otherwise if there
+       // isn't enough memory, returns error without affecting current buffer 
setup.
+       blargg_err_t set_sample_rate( long samples_per_sec, int msec_length = 
1000 / 4 );
+       
+       // Set number of source time units per second
+       void clock_rate( long );
+       
+       // End current time frame of specified duration and make its samples 
available
+       // (along with any still-unread samples) for reading with 
read_samples(). Begins
+       // a new time frame at the end of the current frame.
+       void end_frame( blip_time_t time );
+       
+       // Read at most 'max_samples' out of buffer into 'dest', removing them 
from from
+       // the buffer. Returns number of samples actually read and removed. If 
stereo is
+       // true, increments 'dest' one extra time after writing each sample, to 
allow
+       // easy interleving of two channels into a stereo output buffer.
+       long read_samples( blip_sample_t* dest, long max_samples, int stereo = 
0 );
+       
+// Additional optional features
+
+       // Current output sample rate
+       long sample_rate() const;
+       
+       // Length of buffer, in milliseconds
+       int length() const;
+       
+       // Number of source time units per second
+       long clock_rate() const;
+       
+       // Set frequency high-pass filter frequency, where higher values reduce 
bass more
+       void bass_freq( int frequency );
+       
+       // Number of samples delay from synthesis to samples read out
+       int output_latency() const;
+       
+       // Remove all available samples and clear buffer to silence. If 
'entire_buffer' is
+       // false, just clears out any samples waiting rather than the entire 
buffer.
+       void clear( int entire_buffer = 1 );
+       
+       // Number of samples available for reading with read_samples()
+       long samples_avail() const;
+       
+       // Remove 'count' samples from those waiting to be read
+       void remove_samples( long count );
+       
+// Experimental features
+       
+       // Count number of clocks needed until 'count' samples will be 
available.
+       // If buffer can't even hold 'count' samples, returns number of clocks 
until
+       // buffer becomes full.
+       blip_time_t count_clocks( long count ) const;
+       
+       // Number of raw samples that can be mixed within frame of specified 
duration.
+       long count_samples( blip_time_t duration ) const;
+       
+       // Mix 'count' samples from 'buf' into buffer.
+       void mix_samples( blip_sample_t const* buf, long count );
+       
+       // not documented yet
+       void set_modified() { modified_ = 1; }
+       int clear_modified() { int b = modified_; modified_ = 0; return b; }
+       typedef blip_u64 blip_resampled_time_t;
+       void remove_silence( long count );
+       blip_resampled_time_t resampled_duration( int t ) const     { return t 
* factor_; }
+       blip_resampled_time_t resampled_time( blip_time_t t ) const { return t 
* factor_ + offset_; }
+       blip_resampled_time_t clock_rate_factor( long clock_rate ) const;
+public:
+       Blip_Buffer();
+       ~Blip_Buffer();
+       
+       // Deprecated
+       typedef blip_resampled_time_t resampled_time_t;
+       blargg_err_t sample_rate( long r ) { return set_sample_rate( r ); }
+       blargg_err_t sample_rate( long r, int msec ) { return set_sample_rate( 
r, msec ); }
+private:
+       // noncopyable
+       Blip_Buffer( const Blip_Buffer& );
+       Blip_Buffer& operator = ( const Blip_Buffer& );
+public:
+       typedef blip_time_t buf_t_;
+       blip_u64 factor_;
+       blip_resampled_time_t offset_;
+       buf_t_* buffer_;
+       blip_long buffer_size_;
+       blip_long reader_accum_;
+       int bass_shift_;
+private:
+       long sample_rate_;
+       long clock_rate_;
+       int bass_freq_;
+       int length_;
+       int modified_;
+       friend class Blip_Reader;
+};
+
+#ifdef HAVE_CONFIG_H
+       #include "config.h"
+#endif
+
+#define BLIP_BUFFER_ACCURACY 32
+#define BLIP_PHASE_BITS 8
+
+// Number of bits in resample ratio fraction. Higher values give a more 
accurate ratio
+// but reduce maximum buffer size.
+//#ifndef BLIP_BUFFER_ACCURACY
+//     #define BLIP_BUFFER_ACCURACY 16
+//#endif
+
+// Number bits in phase offset. Fewer than 6 bits (64 phase offsets) results in
+// noticeable broadband noise when synthesizing high frequency square waves.
+// Affects size of Blip_Synth objects since they store the waveform directly.
+//#ifndef BLIP_PHASE_BITS
+//     #if BLIP_BUFFER_FAST
+//             #define BLIP_PHASE_BITS 8
+//     #else
+//             #define BLIP_PHASE_BITS 6
+//     #endif
+//#endif
+
+       // Internal
+       typedef blip_u64 blip_resampled_time_t;
+       int const blip_widest_impulse_ = 16;
+       int const blip_buffer_extra_ = blip_widest_impulse_ + 2;
+       int const blip_res = 1 << BLIP_PHASE_BITS;
+       class blip_eq_t;
+       
+       class Blip_Synth_Fast_ {
+       public:
+               Blip_Buffer* buf;
+               int last_amp;
+               int delta_factor;
+               
+               void volume_unit( double );
+               Blip_Synth_Fast_();
+               void treble_eq( blip_eq_t const& ) { }
+       };
+       
+       class Blip_Synth_ {
+       public:
+               Blip_Buffer* buf;
+               int last_amp;
+               int delta_factor;
+               
+               void volume_unit( double );
+               Blip_Synth_( short* impulses, int width );
+               void treble_eq( blip_eq_t const& );
+       private:
+               double volume_unit_;
+               short* const impulses;
+               int const width;
+               blip_long kernel_unit;
+               int impulses_size() const { return blip_res / 2 * width + 1; }
+               void adjust_impulse();
+       };
+
+// Quality level. Start with blip_good_quality.
+const int blip_med_quality  = 8;
+const int blip_good_quality = 12;
+const int blip_high_quality = 16;
+
+// Range specifies the greatest expected change in amplitude. Calculate it
+// by finding the difference between the maximum and minimum expected
+// amplitudes (max - min).
+template<int quality,int range>
+class Blip_Synth {
+public:
+       // Set overall volume of waveform
+       void volume( double v ) { impl.volume_unit( v * (1.0 / (range < 0 ? 
-range : range)) ); }
+       
+       // Configure low-pass filter (see blip_buffer.txt)
+       void treble_eq( blip_eq_t const& eq )       { impl.treble_eq( eq ); }
+       
+       // Get/set Blip_Buffer used for output
+       Blip_Buffer* output() const                 { return impl.buf; }
+       void output( Blip_Buffer* b )               { impl.buf = b; 
impl.last_amp = 0; }
+       
+       // Update amplitude of waveform at given time. Using this requires a 
separate
+       // Blip_Synth for each waveform.
+       void update( blip_time_t time, int amplitude );
+
+// Low-level interface
+
+       // Add an amplitude transition of specified delta, optionally into 
specified buffer
+       // rather than the one set with output(). Delta can be positive or 
negative.
+       // The actual change in amplitude is delta * (volume / range)
+       void offset( blip_time_t, int delta, Blip_Buffer* ) const;
+       void offset( blip_time_t t, int delta ) const { offset( t, delta, 
impl.buf ); }
+       
+       // Works directly in terms of fractional output samples. Contact author 
for more info.
+       void offset_resampled( blip_resampled_time_t, int delta, Blip_Buffer* ) 
const;
+       
+       // Same as offset(), except code is inlined for higher performance
+       void offset_inline( blip_time_t t, int delta, Blip_Buffer* buf ) const {
+               offset_resampled( t * buf->factor_ + buf->offset_, delta, buf );
+       }
+       void offset_inline( blip_time_t t, int delta ) const {
+               offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, 
delta, impl.buf );
+       }
+       
+private:
+       Blip_Synth_Fast_ impl;
+};
+
+// Low-pass equalization parameters
+class blip_eq_t {
+public:
+       // Logarithmic rolloff to treble dB at half sampling rate. Negative 
values reduce
+       // treble, small positive values (0 to 5.0) increase treble.
+       blip_eq_t( double treble_db = 0 );
+       
+       // See blip_buffer.txt
+       blip_eq_t( double treble, long rolloff_freq, long sample_rate, long 
cutoff_freq = 0 );
+       
+private:
+       double treble;
+       long rolloff_freq;
+       long sample_rate;
+       long cutoff_freq;
+       void generate( float* out, int count ) const;
+       friend class Blip_Synth_;
+};
+
+int const blip_sample_bits = 30;
+
+#define BLIP_RESTRICT
+
+// Optimized reading from Blip_Buffer, for use in custom sample output
+
+// Begin reading from buffer. Name should be unique to the current block.
+#define BLIP_READER_BEGIN( name, blip_buffer ) \
+       const Blip_Buffer::buf_t_* BLIP_RESTRICT name##_reader_buf = 
(blip_buffer).buffer_;\
+       blip_long name##_reader_accum = (blip_buffer).reader_accum_
+
+// Get value to pass to BLIP_READER_NEXT()
+#define BLIP_READER_BASS( blip_buffer ) ((blip_buffer).bass_shift_)
+
+// Constant value to use instead of BLIP_READER_BASS(), for slightly more 
optimal
+// code at the cost of having no bass control
+int const blip_reader_default_bass = 9;
+
+// Current sample
+#define BLIP_READER_READ( name )        (name##_reader_accum >> 
(blip_sample_bits - 16))
+
+// Current raw sample in full internal resolution
+#define BLIP_READER_READ_RAW( name )    (name##_reader_accum)
+
+// Advance to next sample
+#define BLIP_READER_NEXT( name, bass ) \
+       (void) (name##_reader_accum += *name##_reader_buf++ - 
(name##_reader_accum >> (bass)))
+
+// End reading samples from buffer. The number of samples read must now be 
removed
+// using Blip_Buffer::remove_samples().
+#define BLIP_READER_END( name, blip_buffer ) \
+       (void) ((blip_buffer).reader_accum_ = name##_reader_accum)
+
+
+// Compatibility with older version
+const long blip_unscaled = 65535;
+const int blip_low_quality  = blip_med_quality;
+const int blip_best_quality = blip_high_quality;
+
+// Deprecated; use BLIP_READER macros as follows:
+// Blip_Reader r; r.begin( buf ); -> BLIP_READER_BEGIN( r, buf );
+// int bass = r.begin( buf )      -> BLIP_READER_BEGIN( r, buf ); int bass = 
BLIP_READER_BASS( buf );
+// r.read()                       -> BLIP_READER_READ( r )
+// r.read_raw()                   -> BLIP_READER_READ_RAW( r )
+// r.next( bass )                 -> BLIP_READER_NEXT( r, bass )
+// r.next()                       -> BLIP_READER_NEXT( r, 
blip_reader_default_bass )
+// r.end( buf )                   -> BLIP_READER_END( r, buf )
+class Blip_Reader {
+public:
+       int begin( Blip_Buffer& );
+       blip_long read() const          { return accum >> (blip_sample_bits - 
16); }
+       blip_long read_raw() const      { return accum; }
+       void next( int bass_shift = 9 )         { accum += *buf++ - (accum >> 
bass_shift); }
+       void end( Blip_Buffer& b )              { b.reader_accum_ = accum; }
+       
+private:
+       const Blip_Buffer::buf_t_* buf;
+       blip_long accum;
+};
+
+// End of public interface
+
+#include <assert.h>
+
+template<int quality,int range>
+blip_inline void Blip_Synth<quality,range>::offset_resampled( 
blip_resampled_time_t time,
+               int delta, Blip_Buffer* blip_buf ) const
+{
+       // Fails if time is beyond end of Blip_Buffer, due to a bug in caller 
code or the
+       // need for a longer buffer as set by set_sample_rate().
+       assert( (blip_long) (time >> BLIP_BUFFER_ACCURACY) < 
blip_buf->buffer_size_ );
+       delta *= impl.delta_factor;
+       blip_long* BLIP_RESTRICT buf = blip_buf->buffer_ + (time >> 
BLIP_BUFFER_ACCURACY);
+       int phase = (int) (time >> (BLIP_BUFFER_ACCURACY - BLIP_PHASE_BITS) & 
(blip_res - 1));
+
+       blip_long left = buf [0] + delta;
+       
+       // Kind of crappy, but doing shift after multiply results in overflow.
+       // Alternate way of delaying multiply by delta_factor results in worse
+       // sub-sample resolution.
+       blip_long right = (delta >> BLIP_PHASE_BITS) * phase;
+       left  -= right;
+       right += buf [1];
+       
+       buf [0] = left;
+       buf [1] = right;
+}
+
+#undef BLIP_FWD
+#undef BLIP_REV
+
+template<int quality,int range>
+blip_inline void Blip_Synth<quality,range>::offset( blip_time_t t, int delta, 
Blip_Buffer* buf ) const
+{
+       offset_resampled( t * buf->factor_ + buf->offset_, delta, buf );
+}
+
+template<int quality,int range>
+blip_inline void Blip_Synth<quality,range>::update( blip_time_t t, int amp )
+{
+       int delta = amp - impl.last_amp;
+       impl.last_amp = amp;
+       offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, 
impl.buf );
+}
+
+blip_inline blip_eq_t::blip_eq_t( double t ) :
+               treble( t ), rolloff_freq( 0 ), sample_rate( 44100 ), 
cutoff_freq( 0 ) { }
+blip_inline blip_eq_t::blip_eq_t( double t, long rf, long sr, long cf ) :
+               treble( t ), rolloff_freq( rf ), sample_rate( sr ), 
cutoff_freq( cf ) { }
+
+blip_inline int  Blip_Buffer::length() const         { return length_; }
+blip_inline long Blip_Buffer::samples_avail() const  { return (long) (offset_ 
>> BLIP_BUFFER_ACCURACY); }
+blip_inline long Blip_Buffer::sample_rate() const    { return sample_rate_; }
+blip_inline int  Blip_Buffer::output_latency() const { return 
blip_widest_impulse_ / 2; }
+blip_inline long Blip_Buffer::clock_rate() const     { return clock_rate_; }
+blip_inline void Blip_Buffer::clock_rate( long cps ) { factor_ = 
clock_rate_factor( clock_rate_ = cps ); }
+
+blip_inline int Blip_Reader::begin( Blip_Buffer& blip_buf )
+{
+       buf = blip_buf.buffer_;
+       accum = blip_buf.reader_accum_;
+       return blip_buf.bass_shift_;
+}
+
+int const blip_max_length = 0;
+int const blip_default_length = 250;
+
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libretro-handy-0~git20200107/blip/Stereo_Buffer.cpp 
new/libretro-handy-0~git20200625/blip/Stereo_Buffer.cpp
--- old/libretro-handy-0~git20200107/blip/Stereo_Buffer.cpp     1970-01-01 
01:00:00.000000000 +0100
+++ new/libretro-handy-0~git20200625/blip/Stereo_Buffer.cpp     2020-06-25 
22:54:05.000000000 +0200
@@ -0,0 +1,191 @@
+// Blip_Buffer 0.3.0. http://www.slack.net/~ant/nes-emu/
+
+#include <blip/Stereo_Buffer.h>
+
+/* Library Copyright (C) 2004 Shay Green. Blip_Buffer 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 2 of the License, or (at your option) any later version.
+Stereo_Buffer 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 Stereo_Buffer; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+Stereo_Buffer::Stereo_Buffer() {
+}
+
+Stereo_Buffer::~Stereo_Buffer() {
+}
+
+bool Stereo_Buffer::set_sample_rate( long rate, int msec )
+{
+       for ( int i = 0; i < buf_count; i++ ) {
+               if ( bufs [i].set_sample_rate( rate, msec ) )
+               {
+                       return false;
+               }
+       }
+       
+       return true;
+}
+
+void Stereo_Buffer::clock_rate( long rate )
+{
+       for ( int i = 0; i < buf_count; i++ )
+               bufs [i].clock_rate( rate );
+}
+
+void Stereo_Buffer::bass_freq( int bass )
+{
+       for ( unsigned i = 0; i < buf_count; i++ )
+               bufs [i].bass_freq( bass );
+}
+
+void Stereo_Buffer::clear()
+{
+       stereo_added = false;
+       was_stereo = false;
+       for ( int i = 0; i < buf_count; i++ )
+               bufs [i].clear();
+}
+
+void Stereo_Buffer::end_frame( blip_time_t clock_count, bool stereo )
+{
+       for ( unsigned i = 0; i < buf_count; i++ )
+       {
+               bufs [i].end_frame( clock_count );
+       }
+       stereo_added = stereo;
+}
+
+
+
+long Stereo_Buffer::read_samples( blip_sample_t* out, long max_samples )
+{
+       long count = bufs [0].samples_avail();
+       if ( count > max_samples / 2 )
+               count = max_samples / 2;
+       if ( count )
+       {
+               if ( stereo_added || was_stereo )
+               {
+                       mix_stereo( out, count );
+                       
+                       bufs [0].remove_samples( count );
+                       bufs [1].remove_samples( count );
+                       bufs [2].remove_samples( count );
+               }
+#ifndef WANT_STEREO_SOUND
+               else
+               {
+                       mix_mono( out, count );
+                       
+                       bufs [0].remove_samples( count );
+                       
+                       bufs [1].remove_silence( count );
+                       bufs [2].remove_silence( count );
+               }
+#endif
+               
+               // to do: this might miss opportunities for optimization
+               if ( !bufs [0].samples_avail() ) {
+                       was_stereo = stereo_added;
+                       stereo_added = false;
+               }
+       }
+       
+       return count * 2;
+}
+
+void Stereo_Buffer::mix_stereo( blip_sample_t* out, long count )
+{
+       Blip_Reader left; 
+       Blip_Reader right; 
+       Blip_Reader center;
+       
+       left.begin( bufs [1] );
+       right.begin( bufs [2] );
+       int bass = center.begin( bufs [0] );
+       
+       while ( count-- )
+       {
+               int c = center.read();
+               out [0] = c + left.read();
+               out [1] = c + right.read();
+               out += 2;
+               
+               center.next( bass );
+               left.next( bass );
+               right.next( bass );
+       }
+       
+       center.end( bufs [0] );
+       right.end( bufs [2] );
+       left.end( bufs [1] );
+}
+
+void Stereo_Buffer::mix_stereo( float* out, long count )
+{
+        Blip_Reader left;
+        Blip_Reader right;
+        Blip_Reader center;
+
+        left.begin( bufs [1] );
+        right.begin( bufs [2] );
+        int bass = center.begin( bufs [0] );
+
+        while ( count-- )
+        {
+                int c = center.read();
+                out [0] = (float)(c + left.read()) / 32768;
+                out [1] = (float)(c + right.read()) / 32768;
+                out += 2;
+
+                center.next( bass );
+                left.next( bass );
+                right.next( bass );
+        }
+
+        center.end( bufs [0] );
+        right.end( bufs [2] );
+        left.end( bufs [1] );
+}
+
+#ifndef WANT_STEREO_SOUND
+void Stereo_Buffer::mix_mono( blip_sample_t* out, long count )
+{
+       Blip_Reader in;
+       int bass = in.begin( bufs [0] );
+       
+       while ( count-- )
+       {
+               int sample = in.read();
+               out [0] = sample;
+               out [1] = sample;
+               out += 2;
+               in.next( bass );
+       }
+       
+       in.end( bufs [0] );
+}
+
+void Stereo_Buffer::mix_mono( float* out, long count )
+{
+        Blip_Reader in;
+        int bass = in.begin( bufs [0] );
+
+        while ( count-- )
+        {
+                int sample = in.read();
+                out [0] = (float)(sample) / 32768;
+                out [1] = (float)(sample) / 32768;
+                out += 2;
+                in.next( bass );
+        }
+
+        in.end( bufs [0] );
+}
+#endif
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libretro-handy-0~git20200107/blip/Stereo_Buffer.h 
new/libretro-handy-0~git20200625/blip/Stereo_Buffer.h
--- old/libretro-handy-0~git20200107/blip/Stereo_Buffer.h       1970-01-01 
01:00:00.000000000 +0100
+++ new/libretro-handy-0~git20200625/blip/Stereo_Buffer.h       2020-06-25 
22:54:05.000000000 +0200
@@ -0,0 +1,71 @@
+
+// Simple stereo Blip_Buffer for sound emulators whose oscillators output
+// either on the left only, center, or right only.
+
+// Blip_Buffer 0.3.0. Copyright (C) 2003-2004 Shay Green. GNU GPL license.
+
+#ifndef STEREO_BUFFER_H
+#define STEREO_BUFFER_H
+
+#include "Blip_Buffer.h"
+
+class Stereo_Buffer {
+public:
+       Stereo_Buffer();
+       ~Stereo_Buffer();
+       
+       // Same as in Blip_Buffer (see Blip_Buffer.h)
+       bool set_sample_rate( long, int msec = 0 );
+       void clock_rate( long );
+       void bass_freq( int );
+       void clear();
+       
+       // Buffers to output synthesis to
+       Blip_Buffer* left();
+       Blip_Buffer* center();
+       Blip_Buffer* right();
+       
+       // Same as in Blip_Buffer. For more efficient operation, pass false
+       // for was_stereo if the left and right buffers had nothing added
+       // to them for this frame.
+       void end_frame( blip_time_t, bool was_stereo = true );
+       
+       // Output is stereo with channels interleved, left before right. Counts
+       // are in samples, *not* pairs.
+       long samples_avail() const;
+       long read_samples( blip_sample_t*, long );
+       
+private:
+       // noncopyable
+       Stereo_Buffer( const Stereo_Buffer& );
+       Stereo_Buffer& operator = ( const Stereo_Buffer& );
+       
+       enum { buf_count = 3 };
+       Blip_Buffer bufs [buf_count];
+       bool stereo_added;
+       bool was_stereo;
+       
+       void mix_stereo( blip_sample_t*, long );
+       void mix_mono( blip_sample_t*, long );
+        void mix_stereo( float*, long );
+        void mix_mono( float*, long );
+};
+
+       inline Blip_Buffer* Stereo_Buffer::left() {
+               return &bufs [1];
+       }
+       
+       inline Blip_Buffer* Stereo_Buffer::center() {
+               return &bufs [0];
+       }
+       
+       inline Blip_Buffer* Stereo_Buffer::right() {
+               return &bufs [2];
+       }
+       
+       inline long Stereo_Buffer::samples_avail() const {
+               return bufs [0].samples_avail();
+       }
+
+#endif
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libretro-handy-0~git20200107/libretro/libretro.cpp 
new/libretro-handy-0~git20200625/libretro/libretro.cpp
--- old/libretro-handy-0~git20200107/libretro/libretro.cpp      2020-01-07 
17:39:39.000000000 +0100
+++ new/libretro-handy-0~git20200625/libretro/libretro.cpp      2020-06-25 
22:54:05.000000000 +0200
@@ -20,7 +20,8 @@
 static uint8_t lynx_width = 160;
 static uint8_t lynx_height = 102;
 
-static int VIDEO_CORE_PIXELSIZE = 2;
+static int RETRO_PIX_BYTES = 2;
+static int RETRO_PIX_DEPTH = 15;
 
 
 static uint8_t framebuffer[160*160*4];
@@ -68,6 +69,47 @@
 
 static map* btn_map;
 
+static bool update_video = false;
+
+static void check_color_depth(void)
+{
+   if (RETRO_PIX_DEPTH == 24)
+   {
+      enum retro_pixel_format rgb888 = RETRO_PIXEL_FORMAT_XRGB8888;
+
+      if(!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &rgb888))
+      {
+         if(log_cb) log_cb(RETRO_LOG_ERROR, "Pixel format XRGB8888 not 
supported by platform.\n");
+
+         RETRO_PIX_BYTES = 2;
+         RETRO_PIX_DEPTH = 15;
+      }
+   }
+
+   if (RETRO_PIX_BYTES == 2)
+   {
+#if defined(FRONTEND_SUPPORTS_RGB565)
+      enum retro_pixel_format rgb565 = RETRO_PIXEL_FORMAT_RGB565;
+
+      if (environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &rgb565))
+      {
+         if(log_cb) log_cb(RETRO_LOG_INFO, "Frontend supports RGB565 - will 
use that instead of XRGB1555.\n");
+
+         RETRO_PIX_DEPTH = 16;
+      }
+#else
+      enum retro_pixel_format rgb555 = RETRO_PIXEL_FORMAT_0RGB1555;
+
+      if (environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &rgb555))
+      {
+         if(log_cb) log_cb(RETRO_LOG_INFO, "Using default 0RGB1555 pixel 
format.\n");
+
+         RETRO_PIX_DEPTH = 15;
+      }
+#endif
+   }
+}
+
 unsigned retro_api_version(void)
 {
    return RETRO_API_VERSION;
@@ -86,7 +128,7 @@
    if(!initialized)
       return (UBYTE*)framebuffer;
 
-   video_cb(framebuffer, lynx_width, lynx_height, 160*VIDEO_CORE_PIXELSIZE);
+   video_cb(framebuffer, lynx_width, lynx_height, 160*RETRO_PIX_BYTES);
 
 
    for(int total = 0; total < gAudioBufferPointer/4; )
@@ -125,11 +167,12 @@
       break;
    }
 
-   if(VIDEO_CORE_PIXELSIZE == 2) {
-      lynx->DisplaySetAttributes(lynx_rot, MIKIE_PIXEL_FORMAT_16BPP_565, 
160*2, lynx_display_callback, (ULONG)0);
-   }
-   else if(VIDEO_CORE_PIXELSIZE == 4) {
-      lynx->DisplaySetAttributes(lynx_rot, MIKIE_PIXEL_FORMAT_32BPP, 160*4, 
lynx_display_callback, (ULONG)0);
+   switch (RETRO_PIX_DEPTH)
+   {
+      case 15: lynx->DisplaySetAttributes(lynx_rot, 
MIKIE_PIXEL_FORMAT_16BPP_555, 160*2, lynx_display_callback, (ULONG)0); break;
+      case 16: lynx->DisplaySetAttributes(lynx_rot, 
MIKIE_PIXEL_FORMAT_16BPP_565, 160*2, lynx_display_callback, (ULONG)0); break;
+      case 24: lynx->DisplaySetAttributes(lynx_rot, MIKIE_PIXEL_FORMAT_32BPP,  
   160*4, lynx_display_callback, (ULONG)0); break;
+      default: lynx->DisplaySetAttributes(lynx_rot, MIKIE_PIXEL_FORMAT_32BPP,  
   160*4, lynx_display_callback, (ULONG)0); break;
    }
 
    update_geometry();
@@ -159,16 +202,23 @@
    var.key = "handy_gfx_colors";
    var.value = NULL;
 
-   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
-      static bool once = false;
+   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+   {
+      int old_value = RETRO_PIX_BYTES;
 
-      if (!once) {
-         if (strcmp(var.value, "16bit") == 0)
-            VIDEO_CORE_PIXELSIZE = 2;
-         else if (strcmp(var.value, "24bit") == 0)
-            VIDEO_CORE_PIXELSIZE = 4;
-         once = true;
+      if (strcmp(var.value, "16bit") == 0)
+      {
+         RETRO_PIX_BYTES = 2;
+         RETRO_PIX_DEPTH = 16;
       }
+      else if (strcmp(var.value, "24bit") == 0)
+      {
+         RETRO_PIX_BYTES = 4;
+         RETRO_PIX_DEPTH = 24;
+      }
+
+      if (old_value != RETRO_PIX_BYTES)
+         update_video = true;
    }
 }
 
@@ -179,28 +229,6 @@
    if (log.log)
       log_cb = log.log;
 
-   btn_map = btn_map_no_rot;
-
-
-   check_variables();
-
-   if(VIDEO_CORE_PIXELSIZE == 4) {
-      enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_XRGB8888;
-      if(!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt)) {
-         if(log_cb)
-            log_cb(RETRO_LOG_ERROR, "[could not set RGB8888]\n");
-         VIDEO_CORE_PIXELSIZE = 2;
-      }
-   }
-
-   if(VIDEO_CORE_PIXELSIZE == 2) {
-      enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_RGB565;
-      if(!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt) && log_cb) {
-         log_cb(RETRO_LOG_ERROR, "[could not set RGB565]\n");
-      }
-   }
-
-
    uint64_t serialization_quirks = RETRO_SERIALIZATION_QUIRK_SINGLE_SESSION;
    environ_cb(RETRO_ENVIRONMENT_SET_SERIALIZATION_QUIRKS, 
&serialization_quirks);
 }
@@ -228,7 +256,7 @@
 {
    static const struct retro_variable vars[] = {
       { "handy_rot", "Display rotation; None|90|270" },
-      { "handy_gfx_colors", "Color Depth (Restart); 16bit|24bit" },
+      { "handy_gfx_colors", "Color depth; 16bit|24bit" },
       { NULL, NULL },
    };
 
@@ -337,13 +365,6 @@
 
    lynx = new CSystem(gamepath, romfilename, true);
 
-   if(VIDEO_CORE_PIXELSIZE == 2) {
-      lynx->DisplaySetAttributes(lynx_rot, MIKIE_PIXEL_FORMAT_16BPP_565, 
160*2, lynx_display_callback, (ULONG)0);
-   }
-   else if(VIDEO_CORE_PIXELSIZE == 4) {
-      lynx->DisplaySetAttributes(lynx_rot, MIKIE_PIXEL_FORMAT_32BPP, 160*4, 
lynx_display_callback, (ULONG)0);
-   }
-
    return true;
 }
 
@@ -376,17 +397,38 @@
 
 void retro_run(void)
 {
+   bool updated = false;
+   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated)
+      check_variables();
+
    lynx_input();
 
+   if (update_video /*|| update_audio*/)
+   {
+      struct retro_system_av_info system_av_info;
+
+      if (update_video)
+      {
+         memset(&system_av_info, 0, sizeof(system_av_info));
+         environ_cb(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &system_av_info);
+
+         check_color_depth();
+         lynx_rotate();
+      }
+
+      retro_get_system_av_info(&system_av_info);
+      environ_cb(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &system_av_info);
+
+      update_video = false;
+      //update_audio = false;
+   }
+
+   gAudioLastUpdateCycle = gSystemCycleCount;
+
    while (!newFrame)
       lynx->Update();
 
    newFrame = false;
-
-
-   bool updated = false;
-   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated)
-      check_variables();
 }
 
 size_t retro_serialize_size(void)
@@ -445,15 +487,23 @@
 
    environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, desc);
 
+   check_variables();
+   check_color_depth();
+
    if (!lynx_initialize_system(info->path))
       return false;
 
    if (!lynx_initialize_sound())
       return false;
 
-   check_variables();
+   btn_map = btn_map_no_rot;
+   lynx_rotate();
+
+   update_video = false;
+   //update_audio = false;
 
    initialized = true;
+
    return true;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libretro-handy-0~git20200107/lynx/mikie.cpp 
new/libretro-handy-0~git20200625/lynx/mikie.cpp
--- old/libretro-handy-0~git20200107/lynx/mikie.cpp     2020-01-07 
17:39:39.000000000 +0100
+++ new/libretro-handy-0~git20200625/lynx/mikie.cpp     2020-06-25 
22:54:05.000000000 +0200
@@ -90,6 +90,12 @@
    for(loop=0;loop<16;loop++) mPalette[loop].Index=loop;
    for(loop=0;loop<4096;loop++) mColourMap[loop]=0;
 
+   mikbuf.set_sample_rate(HANDY_AUDIO_SAMPLE_FREQ, 60);
+   mikbuf.clock_rate(HANDY_SYSTEM_FREQ / 4);
+   mikbuf.bass_freq(60);
+   miksynth.volume(0.50);
+   miksynth.treble_eq(0);
+       
    Reset();
 }
 
@@ -1304,6 +1310,10 @@
          mpDisplayCurrent=mpDisplayBits;
          break;
    }
+
+   mikbuf.end_frame((gSystemCycleCount - gAudioLastUpdateCycle) / 4);
+   gAudioBufferPointer = mikbuf.read_samples((blip_sample_t*) gAudioBuffer, 
HANDY_AUDIO_BUFFER_SIZE / 2) * 2;
+
    return 0;
 }
 
@@ -2066,6 +2076,9 @@
          TRACE_MIKIE3("Poke(%04x,%02x) - Poke to illegal location at 
PC=%04x",addr,data,mSystem.mCpu->GetPC());
          break;
    }
+
+   if(addr >= AUD0VOL && addr <= MSTEREO)
+         UpdateSound();
 }
 
 
@@ -3336,8 +3349,6 @@
    // If sound is enabled then update the sound subsystem
    //
    if(gAudioEnabled) {
-      UpdateSound();
-
       //
       // Audio 0
       //
@@ -3665,11 +3676,18 @@
          //                                    TRACE_MIKIE1("Update() - 
mAUDIO_3_LASTCNT = %012d",mAUDIO_3_LAST_COUNT);
          //                                    TRACE_MIKIE1("Update() - 
mAUDIO_3_LINKING = %012d",mAUDIO_3_LINKING);
       }
+
+      UpdateSound();
    }
 
    //                  if(gSystemCycleCount==gNextTimerEvent) 
gError->Warning("CMikie::Update() - gSystemCycleCount==gNextTimerEvent, system 
lock likely");
    //                  TRACE_MIKIE1("Update() - NextTimerEvent = 
%012d",gNextTimerEvent);
 
+   // Update system IRQ status as a result of timer activity
+   gSystemIRQ=(mTimerStatusFlags)?true:false;
+   if(gSystemIRQ && gSystemCPUSleep) { ClearCPUSleep(); /*puts("ARLARM"); */ }
+   //else if(gSuzieDoneTime) SetCPUSleep();
+
    // Now all the timer updates are done we can increment the system
    // counter for any work done within the Update() function, 
gSystemCycleCounter
    // cannot be updated until this point otherwise it screws up the counters.
@@ -3705,26 +3723,16 @@
       }
    }
 
-   // Upsample to 16 bit signed
-   SWORD sample_l, sample_r;
-   sample_l= (cur_lsample<<5); // koennte auch 6 sein
-   sample_r= (cur_rsample<<5); // keep cool
-                                
-   
for(;gAudioLastUpdateCycle+HANDY_AUDIO_SAMPLE_PERIOD<gSystemCycleCount;gAudioLastUpdateCycle+=HANDY_AUDIO_SAMPLE_PERIOD)
 {
-      // Output audio sample
-      // Stereo 16 bit signed
-      *(SWORD *) &(gAudioBuffer[gAudioBufferPointer])=sample_l;
-      *(SWORD *) &(gAudioBuffer[gAudioBufferPointer+2])=sample_r;
-      gAudioBufferPointer+=4;
-
-      // Check buffer overflow condition, stick at the endpoint
-      // teh audio output system will reset the input pointer
-      // when it reads out the data.
-
-      // We should NEVER overflow, this buffer holds 0.25 seconds
-      // of data if this happens the the multimedia system above
-      // has failed so the corruption of the buffer contents wont matter
+   static int last_lsample = 0;
+   static int last_rsample = 0;
+
+   if(cur_lsample != last_lsample) {
+      miksynth.offset_inline((gSystemCycleCount - gAudioLastUpdateCycle) / 4, 
cur_lsample - last_lsample, mikbuf.left());
+      last_lsample = cur_lsample;
+   }
 
-      gAudioBufferPointer%=HANDY_AUDIO_BUFFER_SIZE;
+   if(cur_rsample != last_rsample) {
+      miksynth.offset_inline((gSystemCycleCount - gAudioLastUpdateCycle) / 4, 
cur_rsample - last_rsample, mikbuf.right());
+      last_rsample = cur_rsample;
    }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libretro-handy-0~git20200107/lynx/mikie.h 
new/libretro-handy-0~git20200625/lynx/mikie.h
--- old/libretro-handy-0~git20200107/lynx/mikie.h       2020-01-07 
17:39:39.000000000 +0100
+++ new/libretro-handy-0~git20200625/lynx/mikie.h       2020-06-25 
22:54:05.000000000 +0200
@@ -180,12 +180,19 @@
    MIKIE_PIXEL_FORMAT_32BPP,
 };
 
+#include <blip/Stereo_Buffer.h>
+
+typedef Blip_Synth<blip_good_quality, 256 * 4> Synth;
+
 class CMikie : public CLynxBase
 {
    public:
       CMikie(CSystem& parent);
       ~CMikie();
 
+      Synth miksynth;
+      Stereo_Buffer mikbuf;
+
       bool     ContextSave(LSS_FILE *fp);
       bool     ContextLoad(LSS_FILE *fp);
       void     Reset(void);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libretro-handy-0~git20200107/lynx/susie.cpp 
new/libretro-handy-0~git20200625/lynx/susie.cpp
--- old/libretro-handy-0~git20200107/lynx/susie.cpp     2020-01-07 
17:39:39.000000000 +0100
+++ new/libretro-handy-0~git20200625/lynx/susie.cpp     2020-06-25 
22:54:05.000000000 +0200
@@ -649,8 +649,8 @@
          int screen_v_start=(SWORD)mVOFF.Word;
          int screen_v_end=(SWORD)mVOFF.Word+SCREEN_HEIGHT;
 
-         int world_h_mid=screen_h_start+0x8000+(SCREEN_WIDTH/2);
-         int world_v_mid=screen_v_start+0x8000+(SCREEN_HEIGHT/2);
+         int world_h_mid=screen_h_start+(SCREEN_WIDTH/2);
+         int world_v_mid=screen_v_start+(SCREEN_HEIGHT/2);
 
          TRACE_SUSIE2("PaintSprites() screen_h_start $%04x screen_h_end 
$%04x",screen_h_start,screen_h_end);
          TRACE_SUSIE2("PaintSprites() screen_v_start $%04x screen_v_end 
$%04x",screen_v_start,screen_v_end);
@@ -672,7 +672,7 @@
          // Check ref is inside screen area
 
          if((SWORD)mHPOSSTRT.Word<screen_h_start || 
(SWORD)mHPOSSTRT.Word>=screen_h_end ||
-               (SWORD)mVPOSSTRT.Word<screen_v_start || 
(SWORD)mVPOSSTRT.Word>=screen_v_end) superclip=TRUE;
+            (SWORD)mVPOSSTRT.Word<screen_v_start || 
(SWORD)mVPOSSTRT.Word>=screen_v_end) superclip=TRUE;
 
          TRACE_SUSIE1("PaintSprites() Superclip=%d",superclip);
 
@@ -719,7 +719,7 @@
             // line, BUT on superclip we draw all the way to the end of any
             // given line checking each pixel is on screen.
 
-            if(superclip & 0) {
+            if(superclip) {
                // Check on the basis of each quad, we only render the quad
                // IF the screen is in the quad, relative to the centre of
                // the screen which is calculated below.
@@ -749,16 +749,16 @@
 
                switch(modquad) {
                   case 3:
-                     if((sprite_h>=screen_h_start || sprite_h<world_h_mid) && 
(sprite_v<screen_v_end   || sprite_v>world_v_mid)) render=TRUE;
+                     if((sprite_h>=screen_h_start || sprite_h<=world_h_mid) && 
(sprite_v<screen_v_end    || sprite_v>=world_v_mid)) render=TRUE;
                      break;
                   case 2:
-                     if((sprite_h>=screen_h_start || sprite_h<world_h_mid) && 
(sprite_v>=screen_v_start || sprite_v<world_v_mid)) render=TRUE;
+                     if((sprite_h>=screen_h_start || sprite_h<=world_h_mid) && 
(sprite_v>=screen_v_start || sprite_v<=world_v_mid)) render=TRUE;
                      break;
                   case 1:
-                     if((sprite_h<screen_h_end   || sprite_h>world_h_mid) && 
(sprite_v>=screen_v_start || sprite_v<world_v_mid)) render=TRUE;
+                     if((sprite_h<screen_h_end    || sprite_h>=world_h_mid) && 
(sprite_v>=screen_v_start || sprite_v<=world_v_mid)) render=TRUE;
                      break;
                   default:
-                     if((sprite_h<screen_h_end   || sprite_h>world_h_mid) && 
(sprite_v<screen_v_end   || sprite_v>world_v_mid)) render=TRUE;
+                     if((sprite_h<screen_h_end    || sprite_h>=world_h_mid) && 
(sprite_v<screen_v_end    || sprite_v>=world_v_mid)) render=TRUE;
                      break;
                }
             } else {


Reply via email to