Adds mixxing files.

This commit is contained in:
Chris Smith 2022-05-25 15:48:30 +01:00
parent c800f21f10
commit 858f49b723
7 changed files with 958 additions and 0 deletions

6
src/osdep/auto_crop.h Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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 );