Adds mixxing files.
This commit is contained in:
parent
c800f21f10
commit
858f49b723
7 changed files with 958 additions and 0 deletions
6
src/osdep/auto_crop.h
Normal file
6
src/osdep/auto_crop.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef AUTO_CROP_H
|
||||
#define AUTO_CROP_H
|
||||
|
||||
void auto_crop_image(); // in amiberry_gfc.cpp
|
||||
|
||||
#endif
|
124
src/osdep/delta.cpp
Normal file
124
src/osdep/delta.cpp
Normal file
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
*
|
||||
* UAE - Redquark Delta values
|
||||
*
|
||||
* (c) 2021 Chris Smith
|
||||
*/
|
||||
#ifdef REDQUARK
|
||||
|
||||
#include "amiberry_filesys.hpp"
|
||||
#include "custom.h"
|
||||
|
||||
#include "math.h"
|
||||
#include "delta.h"
|
||||
|
||||
#define TIME_NOW_MS (read_processor_time()/1000)
|
||||
extern int get_host_hz(); // amiberry_gfx.cpp
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
delta_initialise( Delta *d, int target, int period, DeltaFlag flag )
|
||||
{
|
||||
d->flag = flag;
|
||||
d->period_ms = period;
|
||||
d->frame_period_ms = (get_host_hz() == 50) ? 20 : 17;
|
||||
|
||||
d->start = d->current = d->target = target * ((d->flag & DELTA_FLAG_PRECISION) ? 100 : 1);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
// Sets target value and sets up time period
|
||||
void
|
||||
delta_set( Delta *d, int target, DeltaFlag flag )
|
||||
{
|
||||
if( flag ) d->flag = (DeltaFlag)((d->flag & DELTA_FLAG_PRECISION) | flag);
|
||||
|
||||
d->start = d->current;
|
||||
d->target = target * ((d->flag & DELTA_FLAG_PRECISION) ? 100 : 1);
|
||||
d->target_t = TIME_NOW_MS + d->period_ms;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
//
|
||||
void
|
||||
delta_reset( Delta *d, int target )
|
||||
{
|
||||
d->start = d->current = d->target = target * ((d->flag & DELTA_FLAG_PRECISION) ? 100 : 1);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
// Returns the time difference in ms until delta process finishes.
|
||||
int
|
||||
delta_process( Delta *d )
|
||||
{
|
||||
if( d->target == d->current ) return 0;
|
||||
|
||||
int remaining = d->target_t - (TIME_NOW_MS + d->frame_period_ms);
|
||||
|
||||
if( remaining <= 0 ) {
|
||||
d->current = d->target;
|
||||
// If remaining was == 0, then 0 would be returned and the caller would
|
||||
// not be able to tell the difference between "nothing to do" and "delta has just done the last step".
|
||||
// Set remaining to 1 so the _next_ time delta_process is called, zero will be returned.
|
||||
remaining = 1;
|
||||
}
|
||||
else if( d->flag & DELTA_FLAG_LOG ) // PI/2 .. 0
|
||||
d->current = d->start + (float)(d->target - d->start) * sin( M_PI_2 - M_PI_2 * ((float)(d->target_t - TIME_NOW_MS) / (d->period_ms)) );
|
||||
else if( d->flag & DELTA_FLAG_LOG_INV )
|
||||
d->current = d->target - (float)(d->target - d->start) * sin( M_PI_2 * ((float)(d->target_t - TIME_NOW_MS) / (d->period_ms)) );
|
||||
else
|
||||
d->current += (d->frame_period_ms * (d->target - d->current)) / (d->target_t - TIME_NOW_MS ); // Linear
|
||||
|
||||
return remaining;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
//
|
||||
float
|
||||
delta_get( Delta *d )
|
||||
{
|
||||
float r = d->current / ((d->flag & DELTA_FLAG_PRECISION) ? 100 : 1);
|
||||
return d->flag & DELTA_FLAG_PRECISION ? r : rint(r);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
delay_period_set( DelayPeriod *d, int frame_units )
|
||||
{
|
||||
d->frame_period_ms = (get_host_hz() == 50) ? 20 : 17;
|
||||
|
||||
d->target_t = (int)(ceil( frame_units / d->frame_period_ms )) * d->frame_period_ms;
|
||||
|
||||
d->target_t += TIME_NOW_MS;
|
||||
d->cancelled = 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
// Returns the number of ms until timeout. If 0, timeout has past. If < 0, cancelled
|
||||
int
|
||||
delay_period_process( DelayPeriod *d )
|
||||
{
|
||||
if( d->cancelled ) return -1;
|
||||
if( d->target_t == 0 ) return 0;
|
||||
|
||||
int remaining = d->target_t - (TIME_NOW_MS + d->frame_period_ms);
|
||||
|
||||
if( remaining <= 0 ) {
|
||||
remaining = 0;
|
||||
d->target_t = 0;
|
||||
}
|
||||
|
||||
return remaining;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
//
|
||||
void
|
||||
delay_period_cancel( DelayPeriod *d )
|
||||
{
|
||||
d->cancelled = 1;
|
||||
}
|
||||
|
||||
#endif //REDQUARK
|
41
src/osdep/delta.h
Normal file
41
src/osdep/delta.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
*
|
||||
* UAE - Redquark Delta values
|
||||
*
|
||||
* (c) 2021 Chris Smith
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
typedef enum {
|
||||
DELTA_FLAG_NONE = 0,
|
||||
DELTA_FLAG_LOG = 1<<0,
|
||||
DELTA_FLAG_LOG_INV = 1<<1,
|
||||
DELTA_FLAG_LINEAR = 1<<2,
|
||||
DELTA_FLAG_PRECISION = 1<<3,
|
||||
} DeltaFlag;
|
||||
|
||||
typedef struct {
|
||||
int start;
|
||||
int target; // The value to hit
|
||||
float current; // The current fractional value
|
||||
unsigned long target_t; // The absolute time at which to hit the target value
|
||||
unsigned long period_ms; // The number of ms within which to hit the target value.
|
||||
unsigned long frame_period_ms; // The smallest duration between process calls
|
||||
DeltaFlag flag;
|
||||
} Delta;
|
||||
|
||||
typedef struct {
|
||||
unsigned long target_t;
|
||||
int cancelled;
|
||||
unsigned long frame_period_ms; // The smallest duration between process calls
|
||||
} DelayPeriod;
|
||||
|
||||
void delta_initialise( Delta *d, int target, int period, DeltaFlag flag );
|
||||
void delta_set( Delta *d, int target, DeltaFlag flag );
|
||||
void delta_reset( Delta *d, int target );
|
||||
int delta_process( Delta *d );
|
||||
float delta_get( Delta *d );
|
||||
|
||||
void delay_period_set( DelayPeriod *d, int frame_units );
|
||||
int delay_period_process( DelayPeriod *d );
|
||||
void delay_period_cancel( DelayPeriod *d );
|
489
src/osdep/disk_swap.cpp
Normal file
489
src/osdep/disk_swap.cpp
Normal file
|
@ -0,0 +1,489 @@
|
|||
/*
|
||||
* UAE - Redquark Disk Swap UI
|
||||
*
|
||||
* (c) 2021 Chris Smith
|
||||
*/
|
||||
#ifdef REDQUARK
|
||||
#include "virtual_keyboard.h"
|
||||
#include "disk_swap.h"
|
||||
#include "amiberry_filesys.hpp"
|
||||
#include "custom.h"
|
||||
#include "playlist.h"
|
||||
|
||||
#include "malifb.h"
|
||||
|
||||
//#define DISK_SWAP_DISABLED 1
|
||||
|
||||
#define TIME_NOW_MS (read_processor_time()/1000)
|
||||
|
||||
#define DF_W 290
|
||||
#define DF_H 46
|
||||
|
||||
typedef struct sprite {
|
||||
int x;
|
||||
int y;
|
||||
int w;
|
||||
int h;
|
||||
} Sprite;
|
||||
|
||||
typedef enum {
|
||||
Sprite_Floppy,
|
||||
Sprite_TopLeft,
|
||||
Sprite_BottomLeft,
|
||||
Sprite_TopRight,
|
||||
Sprite_BottomRight,
|
||||
Sprite_Left,
|
||||
Sprite_Top,
|
||||
Sprite_Right,
|
||||
Sprite_Bottom,
|
||||
Sprite_Center,
|
||||
Sprite_D0,
|
||||
Sprite_D1,
|
||||
Sprite_D2,
|
||||
Sprite_D3,
|
||||
Sprite_D4,
|
||||
Sprite_D5,
|
||||
Sprite_D6,
|
||||
Sprite_D7,
|
||||
Sprite_D8,
|
||||
Sprite_D9,
|
||||
Sprite_DS,
|
||||
Sprite_MAX,
|
||||
} SpriteID;
|
||||
|
||||
static Sprite Sprites[ Sprite_MAX ] = {
|
||||
{ 1, 1, 44, 44 }, // Floppy disk
|
||||
{ 49, 32, 6, 6 }, // Top Left
|
||||
{ 49, 39, 6, 6 }, // Bottom Left
|
||||
{ 57, 32, 6, 6 }, // Top Right
|
||||
{ 57, 39, 6, 6 }, // Bottom Right
|
||||
{ 64, 32, 6, 6 }, // Left
|
||||
{ 64, 39, 6, 6 }, // Top
|
||||
{ 72, 32, 6, 6 }, // Right
|
||||
{ 72, 39, 6, 6 }, // Bottom
|
||||
{ 79, 32, 6, 6 }, // Center
|
||||
{ 48, 2, 20, 28 }, // Digit 0
|
||||
{ 71, 2, 20, 28 }, // Digit 1
|
||||
{ 91, 2, 20, 28 }, // Digit 2
|
||||
{ 113, 2, 20, 28 }, // Digit 3
|
||||
{ 135, 2, 20, 28 }, // Digit 4
|
||||
{ 158, 2, 20, 28 }, // Digit 5
|
||||
{ 179, 2, 20, 28 }, // Digit 6
|
||||
{ 201, 2, 20, 28 }, // Digit 7
|
||||
{ 224, 2, 20, 28 }, // Digit 8
|
||||
{ 245, 2, 20, 28 }, // Digit 9
|
||||
{ 268, 2, 20, 28 }, // Digit /
|
||||
};
|
||||
|
||||
extern int get_host_hz(); // amiberry_gfx.cpp
|
||||
extern int savestate_then_quit;
|
||||
|
||||
static int is_enabled = 0;
|
||||
static int is_disabling = 0;
|
||||
|
||||
static Delta delta_fade;
|
||||
static DelayPeriod delay_show;
|
||||
|
||||
static MFB_Texture *disk_swap_texture = NULL;
|
||||
static int disk_count = 3;
|
||||
static int disk_current = 1;
|
||||
|
||||
typedef enum { // Must be in clockwise order from bottom left
|
||||
FSurface_BottomLeft,
|
||||
FSurface_Left,
|
||||
FSurface_TopLeft,
|
||||
FSurface_Top,
|
||||
FSurface_TopRight,
|
||||
FSurface_Right,
|
||||
FSurface_BottomRight,
|
||||
FSurface_Bottom,
|
||||
FSurface_Center,
|
||||
FSurface_MAX,
|
||||
} FrameSurface;
|
||||
|
||||
typedef struct {
|
||||
int w; // Sprite will be stretched to fit these bounds, if 0 then actual size used
|
||||
int h;
|
||||
int dx; // Position with repsect to last sprite. -1 = left/below, +1 = right/above
|
||||
int dy; //
|
||||
SpriteID id;
|
||||
} FrameSection;
|
||||
|
||||
static FrameSection FrameParts[FSurface_MAX] = {
|
||||
{ 0, 0, 0, 0, Sprite_BottomLeft },
|
||||
{ 0, 80, 0, 1, Sprite_Left },
|
||||
{ 0, 0, 0, 1, Sprite_TopLeft },
|
||||
{ 300, 0, 1, 0, Sprite_Top },
|
||||
{ 0, 0, 1, 0, Sprite_TopRight },
|
||||
{ 0, 80, 0, -1, Sprite_Right },
|
||||
{ 0, 0, 0, -1, Sprite_BottomRight },
|
||||
{ 300, 0, -1, 0, Sprite_Bottom },
|
||||
{ 300, 80, 0, 1, Sprite_Center },
|
||||
};
|
||||
|
||||
static MFB_Surface *frame_surfaces[FSurface_MAX ] = {NULL};
|
||||
|
||||
typedef enum {
|
||||
ISurface_Disk,
|
||||
ISurface_CountDigit1,
|
||||
ISurface_CountDigit2,
|
||||
ISurface_CountSep,
|
||||
ISurface_MaxDigit1,
|
||||
ISurface_MaxDigit2,
|
||||
ISurface_MAX,
|
||||
} IconSurface;
|
||||
|
||||
static MFB_Surface *icon_surfaces[ ISurface_MAX ] = {NULL};
|
||||
static int disk_swap_update_meta( int current, int max );
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
static int
|
||||
build_frame( MFB_Screen *screen )
|
||||
{
|
||||
FrameSection *fs;
|
||||
Sprite *sp;
|
||||
int x = 1280 / 2 - 312 / 2;
|
||||
int y = 720 / 2 - 92 / 2;
|
||||
int h = 0;
|
||||
int w = 0;
|
||||
int ah, aw;
|
||||
int i;
|
||||
for(i = FSurface_BottomLeft; i < FSurface_MAX; i++ ) {
|
||||
fs = &FrameParts[i];
|
||||
sp = &Sprites[ fs->id ];
|
||||
|
||||
aw = fs->w ? fs->w : sp->w;
|
||||
ah = fs->h ? fs->h : sp->h;
|
||||
|
||||
// h and w are here the last surface size
|
||||
|
||||
if( fs->dx ) {
|
||||
if( fs->dx > 0 ) // To the right of the last sprite
|
||||
x += w;
|
||||
if( fs->dx < 0 ) // tp the left of the last sprite
|
||||
x -= aw;
|
||||
}
|
||||
if( fs->dy ) {
|
||||
if( fs->dy > 0 ) // Above the last sprite
|
||||
y += h;
|
||||
if( fs->dy < 0 ) // Below the last sprite
|
||||
y -= ah;
|
||||
}
|
||||
|
||||
w = aw;
|
||||
h = ah;
|
||||
|
||||
//printf("%d, %d, %d, %d\n", x, y, w, h );
|
||||
|
||||
MFB_Surface *sf = MFB_SurfaceCreate( screen, x, y, w, h, 1, MFB_Surface_Opaque | MFB_Surface_Hidden );
|
||||
|
||||
//printf(" Update surface with texture coords %d %d %d %d\n", sp->x, sp->y, sp->w, sp->h );
|
||||
if( MFB_SurfaceUpdate( sf, sp->x, sp->y, sp->w, sp->h, disk_swap_texture ) != 0 ) {
|
||||
printf("ERROR\n");
|
||||
}
|
||||
|
||||
frame_surfaces[ i ] = sf;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
static unsigned char *
|
||||
load_image( const char *filename, int w, int h )
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
int fd = open( prefix_with_application_directory_path( filename ).c_str(), O_RDONLY );
|
||||
if( fd < 0 ) return NULL;
|
||||
|
||||
int size = w * h * 32;
|
||||
void *img = malloc( size );
|
||||
ret = read( fd, img, size );
|
||||
|
||||
if( ret < 0 ) free(img);
|
||||
|
||||
close(fd);
|
||||
|
||||
return ret < 0 ? NULL : (unsigned char *)img;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
int
|
||||
disk_swap_init( MFB_Screen *screen )
|
||||
{
|
||||
int ret = -1;
|
||||
unsigned char *vkimg = NULL;
|
||||
|
||||
int x,y;
|
||||
|
||||
#ifdef DISK_SWAP_DISABLED
|
||||
return 1; // Pretend init was okay
|
||||
#endif
|
||||
|
||||
disk_swap_finish( ); // Clean up
|
||||
|
||||
disk_current = currprefs.playlist_current_disk;
|
||||
disk_count = playlist_loaded_count();
|
||||
|
||||
if( disk_count == 0 ) return 0;
|
||||
|
||||
if( disk_current < 1 || disk_current > disk_count ) disk_current = 1;
|
||||
|
||||
|
||||
do {
|
||||
if( (vkimg = load_image( "data/disk_flip.rgba", DF_W, DF_H )) == NULL ) {
|
||||
break;
|
||||
}
|
||||
|
||||
disk_swap_texture = MFB_TextureCreate( DF_W, DF_H, MFB_RGBA );
|
||||
if( MFB_TextureRegister( screen, disk_swap_texture ) < 0 ) {
|
||||
break;
|
||||
}
|
||||
|
||||
if( MFB_TextureUpdate( disk_swap_texture, 0, 0, disk_swap_texture->width, disk_swap_texture->height, vkimg, MFB_Texture_Flag_None ) != 0 ) {
|
||||
break;
|
||||
}
|
||||
|
||||
build_frame( screen );
|
||||
|
||||
int i;
|
||||
for( i = ISurface_Disk; i < ISurface_MAX; i++ ) {
|
||||
icon_surfaces[ i ] = MFB_SurfaceCreate( screen, 0, 0, 0, 0, 2, MFB_Surface_Transparent | MFB_Surface_Hidden);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
} while( 0 );
|
||||
|
||||
// No need for image data any more, as it has been transfered to the GPU
|
||||
if( vkimg ) free( vkimg );
|
||||
vkimg = NULL;
|
||||
|
||||
if( ret != 0 ) {
|
||||
if( disk_swap_texture ) MFB_TextureDestroy( &disk_swap_texture );
|
||||
|
||||
// FIXME Clearn up all frame and icon surfaces
|
||||
//if( disk_surface ) MFB_SurfaceDestroy( &disk_surface );
|
||||
return ret;
|
||||
}
|
||||
|
||||
delta_initialise( &delta_fade, 0, 500/* fade ms */, DELTA_FLAG_LOG_INV );
|
||||
delay_period_cancel( &delay_show );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
static int
|
||||
disk_swap_set_meta_and_show( int current, int max )
|
||||
{
|
||||
if( current > 99 || max > 99 ) return -1;
|
||||
|
||||
int dc_ten = Sprite_D0 + current / 10;
|
||||
int dc_unit = Sprite_D0 + current % 10;
|
||||
int dm_ten = Sprite_D0 + max / 10;
|
||||
int dm_unit = Sprite_D0 + max % 10;
|
||||
|
||||
// Calculate total width of display
|
||||
//
|
||||
int total_w = Sprites[ Sprite_Floppy ].w + Sprites[ dc_unit ].w + Sprites[ Sprite_DS ].w + Sprites[ dm_unit ].w;
|
||||
total_w += dc_ten > Sprite_D0 ? Sprites[ dc_ten ].w : 0;
|
||||
total_w += dm_ten > Sprite_D0 ? Sprites[ dm_ten ].w : 0;
|
||||
total_w += 20; // Padding between disk and text
|
||||
|
||||
int x = 1280 / 2 - total_w / 2;
|
||||
int cy = 720 / 2;
|
||||
|
||||
int i;
|
||||
int pad;
|
||||
int target = ISurface_Disk;
|
||||
int sid;
|
||||
Sprite *s;
|
||||
for( i = ISurface_Disk; i < ISurface_MAX; i++ ) {
|
||||
pad = 0;
|
||||
switch(i) {
|
||||
case ISurface_Disk: sid = Sprite_Floppy; pad = 20; break;
|
||||
case ISurface_CountSep: sid = Sprite_DS; break;
|
||||
case ISurface_CountDigit1: sid = dc_ten; if( sid == Sprite_D0 ) continue; break;
|
||||
case ISurface_MaxDigit1: sid = dm_ten; if( sid == Sprite_D0 ) continue; break;
|
||||
case ISurface_CountDigit2: sid = dc_unit; break;
|
||||
case ISurface_MaxDigit2: sid = dm_unit; break;
|
||||
default: continue;
|
||||
}
|
||||
|
||||
Sprite *s = &Sprites[ sid ];
|
||||
MFB_SurfaceSize ( icon_surfaces[ target ], x, cy - s->h / 2, s->w, s->h );
|
||||
MFB_SurfaceUpdate( icon_surfaces[ target ], s->x, s->y, s->w, s->h, disk_swap_texture );
|
||||
MFB_SurfaceReveal( icon_surfaces[ target ] );
|
||||
x += s->w + pad;
|
||||
|
||||
target++;
|
||||
}
|
||||
|
||||
for( ; target < ISurface_MAX; target++ ) {
|
||||
MFB_SurfaceHide( icon_surfaces[ target ] );
|
||||
}
|
||||
|
||||
// Show the frame too
|
||||
for(i = FSurface_BottomLeft; i < FSurface_MAX; i++ ) {
|
||||
MFB_SurfaceReveal( frame_surfaces[ i ] );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
static void
|
||||
disk_swap_hide()
|
||||
{
|
||||
int i;
|
||||
for( i = ISurface_Disk; i < ISurface_MAX; i++ ) {
|
||||
MFB_SurfaceHide( icon_surfaces[ i ] );
|
||||
}
|
||||
|
||||
for(i = FSurface_BottomLeft; i < FSurface_MAX; i++ ) {
|
||||
MFB_SurfaceHide( frame_surfaces[ i ] );
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Will hide surfaces if alpha is zero
|
||||
static int
|
||||
disk_swap_set_alpha( int alpha )
|
||||
{
|
||||
if( alpha == 0 ) disk_swap_hide();
|
||||
else {
|
||||
int i;
|
||||
for( i = ISurface_Disk; i < ISurface_MAX; i++ ) {
|
||||
MFB_SurfaceAlpha( icon_surfaces[ i ], alpha );
|
||||
}
|
||||
for(i = FSurface_BottomLeft; i < FSurface_MAX; i++ ) {
|
||||
MFB_SurfaceAlpha( frame_surfaces[ i ], alpha );
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
int
|
||||
disk_swap_finish( )
|
||||
{
|
||||
if( disk_swap_texture ) MFB_TextureDestroy( &disk_swap_texture );
|
||||
// FIXME Clearn up all frame and icon surfaces
|
||||
//if( disk_surface ) MFB_SurfaceDestroy( &disk_surface );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
int
|
||||
disk_swap_enable()
|
||||
{
|
||||
int x,y;
|
||||
|
||||
#ifdef DISK_SWAP_DISABLED
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
if( is_disabling || savestate_then_quit ) return 0;
|
||||
|
||||
disk_swap_set_meta_and_show( disk_current, disk_count );
|
||||
|
||||
delta_reset( &delta_fade, 100 ); // Force fade to 100 (on)
|
||||
delay_period_set ( &delay_show, 500 );
|
||||
|
||||
is_enabled = 1;
|
||||
|
||||
disk_swap_process( );
|
||||
|
||||
MFB_SurfaceReveal( icon_surfaces[ ISurface_Disk ] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
void
|
||||
disk_swap_next()
|
||||
{
|
||||
#ifdef DISK_SWAP_DISABLED
|
||||
return;
|
||||
#endif
|
||||
if( disk_count == 0 ) return;
|
||||
|
||||
disk_current = 1 + disk_current % disk_count;
|
||||
disk_swap_enable();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
void
|
||||
disk_swap_previous()
|
||||
{
|
||||
#ifdef DISK_SWAP_DISABLED
|
||||
return;
|
||||
#endif
|
||||
if( disk_count == 0 ) return;
|
||||
|
||||
disk_current--;
|
||||
if( !disk_current ) disk_current = disk_count;
|
||||
|
||||
disk_swap_enable();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
int
|
||||
disk_swap_disable()
|
||||
{
|
||||
//if( is_disabling ) return 0;
|
||||
#ifdef DISK_SWAP_DISABLED
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
disk_swap_hide();
|
||||
|
||||
is_enabled = 0;
|
||||
|
||||
//is_disabling = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Returns true if move occurred
|
||||
int
|
||||
disk_swap_process( )
|
||||
{
|
||||
if( !is_enabled ) return 0;
|
||||
|
||||
int dr = delay_period_process( &delay_show );
|
||||
|
||||
if( dr < 0 && delta_get( &delta_fade ) == 0.0f ) {
|
||||
disk_swap_disable();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( dr == 0 ) {
|
||||
delay_period_cancel( &delay_show );
|
||||
delta_set( &delta_fade, 0, DELTA_FLAG_NONE );
|
||||
|
||||
playlist_insert_disk( disk_current );
|
||||
|
||||
} else if( dr < 0 ) {
|
||||
delta_process( &delta_fade );
|
||||
}
|
||||
|
||||
disk_swap_set_alpha( delta_get( &delta_fade ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
#endif //REDQUARK
|
12
src/osdep/disk_swap.h
Normal file
12
src/osdep/disk_swap.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "malifb.h"
|
||||
#include "sysdeps.h"
|
||||
#include "options.h"
|
||||
|
||||
int disk_swap_init( MFB_Screen *screen );
|
||||
int disk_swap_finish();
|
||||
int disk_swap_process( );
|
||||
int disk_swap_enable();
|
||||
void disk_swap_next();
|
||||
void disk_swap_previous();
|
255
src/osdep/playlist.cpp
Normal file
255
src/osdep/playlist.cpp
Normal file
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
* UAE - Redquark Playlist handling
|
||||
*
|
||||
* (c) 2022 Chris Smith
|
||||
*/
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "playlist.h"
|
||||
#include "disk.h"
|
||||
|
||||
static Playlist *main_playlist = NULL;
|
||||
|
||||
static unsigned char * find_entry( Playlist *pl, int item, int *len );
|
||||
static int count_tree_levels( const unsigned char *p, int len );
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
Playlist *
|
||||
playlist_open( const char *filename )
|
||||
{
|
||||
Playlist *pl = (Playlist *)malloc( sizeof(Playlist) );
|
||||
if( pl == NULL ) return NULL;
|
||||
|
||||
void * mem;
|
||||
struct stat sb;
|
||||
int fd = -1;
|
||||
int ret = 0;
|
||||
int len = 0;
|
||||
|
||||
if( (fd = open( (char*)filename, O_RDONLY ) ) < 0 ) ret = (-3);
|
||||
if( ret == 0 && fstat( fd, &sb ) < 0 ) ret = (-2);
|
||||
|
||||
if( ret == 0 ) {
|
||||
if( (mem = mmap( (caddr_t)0, (int)sb.st_size,
|
||||
PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0 )) != MAP_FAILED ) {
|
||||
len = (int)sb.st_size;
|
||||
} else ret = (-1);
|
||||
}
|
||||
|
||||
if( ret > (-3) ) close( fd );
|
||||
|
||||
if( ret < 0 ) return NULL;
|
||||
|
||||
pl->data = (unsigned char *)mem;
|
||||
pl->len = len;
|
||||
|
||||
int plen = strlen(filename);
|
||||
int i = plen - 1;
|
||||
while( i >= 0 && filename[i] != '/' ) i--;
|
||||
|
||||
i++; // Take into account tail '/'
|
||||
pl->playlist_dir = strndup( filename, i ); // Note strdup will also byte for \0 terminator
|
||||
pl->playlist_dir_len = i;
|
||||
|
||||
int count;
|
||||
find_entry( pl, -1, &count ); // Return count == 0 if no entries in file
|
||||
|
||||
if( count == 0 ) {
|
||||
playlist_close( &pl ); // This will release pl and set to NULL
|
||||
} else {
|
||||
pl->count = count;
|
||||
}
|
||||
|
||||
return pl;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
void
|
||||
playlist_close( Playlist ** pl )
|
||||
{
|
||||
if( pl == NULL || *pl == NULL ) return;
|
||||
if( (*pl)->data ) munmap( (void *)(*pl)->data, (*pl)->len );
|
||||
if( (*pl)->playlist_dir ) free( (*pl)->playlist_dir );
|
||||
free( *pl );
|
||||
*pl = NULL;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// If item is < 0, a special mode is entered where the number of filenames in the playlist
|
||||
// is returned in len, return WILL be NULL in this case
|
||||
//
|
||||
static unsigned char *
|
||||
find_entry( Playlist *pl, int item, int *len )
|
||||
{
|
||||
unsigned char *p = pl->data;
|
||||
|
||||
int count = 0;
|
||||
|
||||
unsigned char *s;
|
||||
unsigned char *e = p + pl->len;
|
||||
|
||||
while( p < e && (item < 0 || count <= item ) ) {
|
||||
|
||||
// Find end of line
|
||||
while( *p == ' ') p++; // skip leading spaces
|
||||
|
||||
if( *p == '#' ) while( *p >= ' ' ) p++; // Skip comment/extensino
|
||||
// Skip blank lines (or comment line ending)
|
||||
if( *p == '\r' ) p++;
|
||||
if( *p == '\n' ) {
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find end of line
|
||||
s = p;
|
||||
while( *p >= ' ') p++; // skip up to line ending
|
||||
*len = p - s;
|
||||
|
||||
while( *p < ' ' && *p > 0 ) p++; // Eat any line endings
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
if( item < 0 ) *len = count; // Special case -return number of entries
|
||||
else if( count <= item ) *len = 0; // Usual case, return string length
|
||||
else {
|
||||
// Discard trailing spaces
|
||||
while( (*len) && s[(*len) - 1] == ' ' ) (*len)--;
|
||||
}
|
||||
|
||||
return count > item ? s : NULL;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
int
|
||||
playlist_get_count( Playlist * pl )
|
||||
{
|
||||
if( pl == NULL ) return 0;
|
||||
return pl->count;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
unsigned char *
|
||||
playlist_get_entry( Playlist *pl, int item, int *len )
|
||||
{
|
||||
if( item < 0 || item >= pl->count ) return NULL;
|
||||
|
||||
int flen;
|
||||
unsigned char *f = find_entry( pl, item, &flen );
|
||||
|
||||
int tl = pl->playlist_dir_len + flen;
|
||||
unsigned char *b = (unsigned char *)malloc( tl + 1 );
|
||||
|
||||
memcpy( b, pl->playlist_dir, pl->playlist_dir_len );
|
||||
memcpy( b + pl->playlist_dir_len, f, flen );
|
||||
b[tl] = '\0';
|
||||
|
||||
if( len != NULL ) *len = tl;
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
int
|
||||
playlist_insert_disk( int disk_number )
|
||||
{
|
||||
if( main_playlist == NULL ) return -1;
|
||||
if( disk_number < 1 || disk_number > playlist_get_count( main_playlist ) ) return -1;
|
||||
|
||||
if( currprefs.playlist_current_disk == disk_number ) return 0;
|
||||
|
||||
unsigned char *df = playlist_get_entry( main_playlist, disk_number - 1, NULL );
|
||||
|
||||
#ifdef CPU_AMD64
|
||||
printf("Insert disk %d [%s]\n", disk_number, df );
|
||||
#endif
|
||||
|
||||
disk_insert(0, (char *)df );
|
||||
free( df );
|
||||
|
||||
currprefs.playlist_current_disk = disk_number;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
int
|
||||
playlist_loaded_count( )
|
||||
{
|
||||
if( main_playlist == NULL ) return 0;
|
||||
return playlist_get_count( main_playlist );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
int
|
||||
playlist_auto_open( struct uae_prefs* prefs, char *filepath )
|
||||
{
|
||||
#ifdef CPU_AMD64
|
||||
printf("Process playlist line [%s]\n", filepath );
|
||||
#endif
|
||||
|
||||
int i = strlen(filepath) - 1;
|
||||
while( i > 0 && filepath[i] >= '0' && filepath[i] <= '9' && filepath[i] != ':' ) i--;
|
||||
|
||||
int cd = ( filepath[i] == ':' ) ? atoi( filepath + i + 1) : 0; // Default of 0 means no-disk
|
||||
|
||||
if( filepath[i] == ':' ) filepath[i] = '\0';
|
||||
|
||||
#ifdef CPU_AMD64
|
||||
printf("Open playlist [%s]\n", filepath );
|
||||
#endif
|
||||
|
||||
if( main_playlist != NULL ) playlist_close( &main_playlist );
|
||||
|
||||
main_playlist = playlist_open( filepath );
|
||||
if( main_playlist == NULL ) return -1;
|
||||
|
||||
if( playlist_get_count( main_playlist ) < 1 ) {
|
||||
playlist_close( &main_playlist );
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef CPU_AMD64
|
||||
printf("Set current disk %d\n", cd );
|
||||
#endif
|
||||
|
||||
if( strcmp( prefs->playlist, filepath ) != 0 ) strcpy( prefs->playlist, filepath );
|
||||
prefs->playlist_current_disk = cd;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
void
|
||||
playlist_auto_prefs(struct uae_prefs* prefs, char* filepath)
|
||||
{
|
||||
if( playlist_auto_open( prefs, filepath ) < 0 ) return;
|
||||
|
||||
playlist_insert_disk( 1 );
|
||||
|
||||
prefs->start_gui = false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// end
|
31
src/osdep/playlist.h
Normal file
31
src/osdep/playlist.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* UAE - Redquark Virtual Keyboard
|
||||
*
|
||||
* (c) 2021 Chris Smith
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "sysconfig.h"
|
||||
#include "sysdeps.h"
|
||||
#include <ctype.h>
|
||||
#include "options.h"
|
||||
|
||||
typedef struct {
|
||||
unsigned char *data;
|
||||
int len;
|
||||
int count;
|
||||
char *playlist_dir;
|
||||
int playlist_dir_len;
|
||||
|
||||
} Playlist;
|
||||
|
||||
Playlist * playlist_open( const char *filename );
|
||||
void playlist_close( Playlist ** pl );
|
||||
int playlist_get_count( Playlist * pl );
|
||||
int playlist_insert_disk( int disk_number );
|
||||
int playlist_loaded_count( );
|
||||
|
||||
void playlist_auto_prefs(struct uae_prefs* prefs, char* filepath );
|
||||
int playlist_auto_open( struct uae_prefs* prefs, char *filepath );
|
||||
|
||||
unsigned char * playlist_get_entry( Playlist *pl, int item, int *len );
|
Loading…
Add table
Add a link
Reference in a new issue