diff --git a/GNUmakefile b/GNUmakefile
index b4f3202f7..f39cf1386 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -75,6 +75,7 @@ libxmplite_objs := \
s3m_load.c \
sample.c \
xm_load.c \
+ win32.c \
libxmplite_root := $(source)/$(libxmplite)
libxmplite_src := $(libxmplite_root)/src
diff --git a/platform/Windows/libxmp-lite.vcxproj b/platform/Windows/libxmp-lite.vcxproj
index 8983938e0..68f2bb018 100644
--- a/platform/Windows/libxmp-lite.vcxproj
+++ b/platform/Windows/libxmp-lite.vcxproj
@@ -66,6 +66,7 @@
+
diff --git a/platform/Windows/libxmp-lite.vcxproj.filters b/platform/Windows/libxmp-lite.vcxproj.filters
index 59bcb767a..24ba72930 100644
--- a/platform/Windows/libxmp-lite.vcxproj.filters
+++ b/platform/Windows/libxmp-lite.vcxproj.filters
@@ -149,5 +149,6 @@
Source Files
+
\ No newline at end of file
diff --git a/source/libxmp-lite/include/libxmp-lite/xmp.h b/source/libxmp-lite/include/libxmp-lite/xmp.h
index 799deb28d..33076f650 100644
--- a/source/libxmp-lite/include/libxmp-lite/xmp.h
+++ b/source/libxmp-lite/include/libxmp-lite/xmp.h
@@ -5,30 +5,30 @@
extern "C" {
#endif
-#define XMP_VERSION "4.4.2"
-#define XMP_VERCODE 0x040402
+#define XMP_VERSION "4.5.0"
+#define XMP_VERCODE 0x040500
#define XMP_VER_MAJOR 4
-#define XMP_VER_MINOR 4
-#define XMP_VER_RELEASE 2
+#define XMP_VER_MINOR 5
+#define XMP_VER_RELEASE 0
#if defined(_WIN32) && !defined(__CYGWIN__)
# if defined(BUILDING_STATIC)
-# define EXPORT
+# define LIBXMP_EXPORT
# elif defined(BUILDING_DLL)
-# define EXPORT __declspec(dllexport)
+# define LIBXMP_EXPORT __declspec(dllexport)
# else
-# define EXPORT __declspec(dllimport)
+# define LIBXMP_EXPORT __declspec(dllimport)
# endif
#elif defined(__OS2__) && defined(__WATCOMC__) && defined(__SW_BD)
-# define EXPORT __declspec(dllexport)
+# define LIBXMP_EXPORT __declspec(dllexport)
#elif (defined(__GNUC__) || defined(__clang__) || defined(__HP_cc)) && defined(XMP_SYM_VISIBILITY)
-# define EXPORT __attribute__((visibility ("default")))
+# define LIBXMP_EXPORT __attribute__((visibility ("default")))
#elif defined(__SUNPRO_C) && defined(XMP_LDSCOPE_GLOBAL)
-# define EXPORT __global
+# define LIBXMP_EXPORT __global
#elif defined(EMSCRIPTEN)
-# define EXPORT EMSCRIPTEN_KEEPALIVE
+# define LIBXMP_EXPORT EMSCRIPTEN_KEEPALIVE
#else
-# define EXPORT
+# define LIBXMP_EXPORT
#endif
#define XMP_NAME_SIZE 64 /* Size of module name and type */
@@ -172,35 +172,36 @@ struct xmp_envelope {
};
struct xmp_subinstrument {
- int vol; /* Default volume */
- int gvl; /* Global volume */
- int pan; /* Pan */
- int xpo; /* Transpose */
- int fin; /* Finetune */
- int vwf; /* Vibrato waveform */
- int vde; /* Vibrato depth */
- int vra; /* Vibrato rate */
- int vsw; /* Vibrato sweep */
- int rvv; /* Random volume/pan variation (IT) */
- int sid; /* Sample number */
+ int vol; /* Default volume */
+ int gvl; /* Global volume */
+ int pan; /* Pan */
+ int xpo; /* Transpose */
+ int fin; /* Finetune */
+ int vwf; /* Vibrato waveform */
+ int vde; /* Vibrato depth */
+ int vra; /* Vibrato rate */
+ int vsw; /* Vibrato sweep */
+ int rvv; /* Random volume/pan variation (IT) */
+ int sid; /* Sample number */
#define XMP_INST_NNA_CUT 0x00
#define XMP_INST_NNA_CONT 0x01
#define XMP_INST_NNA_OFF 0x02
#define XMP_INST_NNA_FADE 0x03
- int nna; /* New note action */
+ int nna; /* New note action */
#define XMP_INST_DCT_OFF 0x00
#define XMP_INST_DCT_NOTE 0x01
#define XMP_INST_DCT_SMP 0x02
#define XMP_INST_DCT_INST 0x03
- int dct; /* Duplicate check type */
+ int dct; /* Duplicate check type */
#define XMP_INST_DCA_CUT XMP_INST_NNA_CUT
#define XMP_INST_DCA_OFF XMP_INST_NNA_OFF
#define XMP_INST_DCA_FADE XMP_INST_NNA_FADE
- int dca; /* Duplicate check action */
- int ifc; /* Initial filter cutoff */
- int ifr; /* Initial filter resonance */
+ int dca; /* Duplicate check action */
+ int ifc; /* Initial filter cutoff */
+ int ifr; /* Initial filter resonance */
};
+
struct xmp_instrument {
char name[32]; /* Instrument name */
int vol; /* Instrument volume */
@@ -215,7 +216,7 @@ struct xmp_instrument {
signed char xpo; /* Instrument transpose for each key */
} map[XMP_MAX_KEYS];
- struct xmp_subinstrument *sub;
+ struct xmp_subinstrument *sub;
void *extra; /* Extra fields */
};
@@ -279,18 +280,19 @@ struct xmp_module_info {
};
struct xmp_channel_info { /* Current channel information */
- unsigned int period; /* Sample period (* 4096) */
- unsigned int position; /* Sample position */
- short pitchbend; /* Linear bend from base note*/
- unsigned char note; /* Current base note number */
- unsigned char instrument; /* Current instrument number */
- unsigned char sample; /* Current sample number */
- unsigned char volume; /* Current volume */
- unsigned char pan; /* Current stereo pan */
- unsigned char reserved; /* Reserved */
- struct xmp_event event; /* Current track event */
+ unsigned int period; /* Sample period (* 4096) */
+ unsigned int position; /* Sample position */
+ short pitchbend; /* Linear bend from base note*/
+ unsigned char note; /* Current base note number */
+ unsigned char instrument; /* Current instrument number */
+ unsigned char sample; /* Current sample number */
+ unsigned char volume; /* Current volume */
+ unsigned char pan; /* Current stereo pan */
+ unsigned char reserved; /* Reserved */
+ struct xmp_event event; /* Current track event */
};
+
struct xmp_frame_info { /* Current frame information */
int pos; /* Current position */
int pattern; /* Current pattern */
@@ -317,51 +319,52 @@ struct xmp_frame_info { /* Current frame information */
typedef char *xmp_context;
-EXPORT extern const char *xmp_version;
-EXPORT extern const unsigned int xmp_vercode;
+LIBXMP_EXPORT extern const char *xmp_version;
+LIBXMP_EXPORT extern const unsigned int xmp_vercode;
-EXPORT xmp_context xmp_create_context (void);
-EXPORT void xmp_free_context (xmp_context);
+LIBXMP_EXPORT xmp_context xmp_create_context (void);
+LIBXMP_EXPORT void xmp_free_context (xmp_context);
#ifdef EDUKE32_DISABLED
-EXPORT int xmp_test_module (char *, struct xmp_test_info *);
-EXPORT int xmp_load_module (xmp_context, char *);
+LIBXMP_EXPORT int xmp_test_module (char *, struct xmp_test_info *);
+LIBXMP_EXPORT int xmp_load_module (xmp_context, char *);
#endif
-EXPORT void xmp_scan_module (xmp_context);
-EXPORT void xmp_release_module (xmp_context);
-EXPORT int xmp_start_player (xmp_context, int, int);
-EXPORT int xmp_play_frame (xmp_context);
-EXPORT int xmp_play_buffer (xmp_context, void *, int, int);
-EXPORT void xmp_get_frame_info (xmp_context, struct xmp_frame_info *);
-EXPORT void xmp_end_player (xmp_context);
-EXPORT void xmp_inject_event (xmp_context, int, struct xmp_event *);
-EXPORT void xmp_get_module_info (xmp_context, struct xmp_module_info *);
-EXPORT const char**xmp_get_format_list (void);
-EXPORT int xmp_next_position (xmp_context);
-EXPORT int xmp_prev_position (xmp_context);
-EXPORT int xmp_set_position (xmp_context, int);
-EXPORT void xmp_stop_module (xmp_context);
-EXPORT void xmp_restart_module (xmp_context);
-EXPORT int xmp_seek_time (xmp_context, int);
-EXPORT int xmp_channel_mute (xmp_context, int, int);
-EXPORT int xmp_channel_vol (xmp_context, int, int);
-EXPORT int xmp_set_player (xmp_context, int, int);
-EXPORT int xmp_get_player (xmp_context, int);
-EXPORT int xmp_set_instrument_path (xmp_context, char *);
-EXPORT int xmp_load_module_from_memory (xmp_context, void *, long);
+LIBXMP_EXPORT void xmp_scan_module (xmp_context);
+LIBXMP_EXPORT void xmp_release_module (xmp_context);
+LIBXMP_EXPORT int xmp_start_player (xmp_context, int, int);
+LIBXMP_EXPORT int xmp_play_frame (xmp_context);
+LIBXMP_EXPORT int xmp_play_buffer (xmp_context, void *, int, int);
+LIBXMP_EXPORT void xmp_get_frame_info (xmp_context, struct xmp_frame_info *);
+LIBXMP_EXPORT void xmp_end_player (xmp_context);
+LIBXMP_EXPORT void xmp_inject_event (xmp_context, int, struct xmp_event *);
+LIBXMP_EXPORT void xmp_get_module_info (xmp_context, struct xmp_module_info *);
+LIBXMP_EXPORT const char **xmp_get_format_list (void);
+LIBXMP_EXPORT int xmp_next_position (xmp_context);
+LIBXMP_EXPORT int xmp_prev_position (xmp_context);
+LIBXMP_EXPORT int xmp_set_position (xmp_context, int);
+LIBXMP_EXPORT int xmp_set_row (xmp_context, int);
+LIBXMP_EXPORT int xmp_set_tempo_factor(xmp_context, double);
+LIBXMP_EXPORT void xmp_stop_module (xmp_context);
+LIBXMP_EXPORT void xmp_restart_module (xmp_context);
+LIBXMP_EXPORT int xmp_seek_time (xmp_context, int);
+LIBXMP_EXPORT int xmp_channel_mute (xmp_context, int, int);
+LIBXMP_EXPORT int xmp_channel_vol (xmp_context, int, int);
+LIBXMP_EXPORT int xmp_set_player (xmp_context, int, int);
+LIBXMP_EXPORT int xmp_get_player (xmp_context, int);
+LIBXMP_EXPORT int xmp_set_instrument_path (xmp_context, char *);
+LIBXMP_EXPORT int xmp_load_module_from_memory (xmp_context, void *, long);
#ifdef EDUKE32_DISABLED
-EXPORT int xmp_load_module_from_file (xmp_context, void *, long);
+LIBXMP_EXPORT int xmp_load_module_from_file (xmp_context, void *, long);
#endif
-
/* External sample mixer API */
-EXPORT int xmp_start_smix (xmp_context, int, int);
-EXPORT void xmp_end_smix (xmp_context);
-EXPORT int xmp_smix_play_instrument(xmp_context, int, int, int, int);
-EXPORT int xmp_smix_play_sample (xmp_context, int, int, int, int);
-EXPORT int xmp_smix_channel_pan (xmp_context, int, int);
+LIBXMP_EXPORT int xmp_start_smix (xmp_context, int, int);
+LIBXMP_EXPORT void xmp_end_smix (xmp_context);
+LIBXMP_EXPORT int xmp_smix_play_instrument(xmp_context, int, int, int, int);
+LIBXMP_EXPORT int xmp_smix_play_sample (xmp_context, int, int, int, int);
+LIBXMP_EXPORT int xmp_smix_channel_pan (xmp_context, int, int);
#ifdef EDUKE32_DISABLED
-EXPORT int xmp_smix_load_sample (xmp_context, int, char *);
+LIBXMP_EXPORT int xmp_smix_load_sample (xmp_context, int, char *);
#endif
-EXPORT int xmp_smix_release_sample (xmp_context, int);
+LIBXMP_EXPORT int xmp_smix_release_sample (xmp_context, int);
#ifdef __cplusplus
}
diff --git a/source/libxmp-lite/src/common.c b/source/libxmp-lite/src/common.c
index 4ca28e90b..ed38442c1 100644
--- a/source/libxmp-lite/src/common.c
+++ b/source/libxmp-lite/src/common.c
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/source/libxmp-lite/src/common.h b/source/libxmp-lite/src/common.h
index 2290606d1..44634251d 100644
--- a/source/libxmp-lite/src/common.h
+++ b/source/libxmp-lite/src/common.h
@@ -145,10 +145,7 @@ void __inline CLIB_DECL D_(const char *text, ...) { do {} while (0); }
#define close _close
#define unlink _unlink
#endif
-#if defined(_MSC_VER)
-#define snprintf _snprintf
-#define vsnprintf _vsnprintf
-#elif defined(__WATCOMC__) /* in win32.c */
+#if defined(_WIN32) || defined(__WATCOMC__) /* in win32.c */
int libxmp_vsnprintf(char *, size_t, const char *, va_list);
int libxmp_snprintf (char *, size_t, const char *, ...);
#define snprintf libxmp_snprintf
@@ -296,28 +293,40 @@ struct module_data {
};
struct pattern_loop {
- int start;
- int count;
+ int start;
+ int count;
};
+
struct flow_control {
- int pbreak;
- int jump;
- int delay;
- int jumpline;
- int loop_chn;
-
- struct pattern_loop *loop;
-
- int num_rows;
- int end_point;
- int rowdelay; /* For IT pattern row delay */
- int rowdelay_set;
+ int pbreak;
+ int jump;
+ int delay;
+ int jumpline;
+ int loop_chn;
+
+ struct pattern_loop *loop;
+
+ int num_rows;
+ int end_point;
+ int rowdelay; /* For IT pattern row delay */
+ int rowdelay_set;
};
struct virt_channel {
- int count;
- int map;
+ int count;
+ int map;
+};
+
+struct virt_control {
+ int num_tracks; /* Number of tracks */
+ int virt_channels; /* Number of virtual channels */
+ int virt_used; /* Number of voices currently in use */
+ int maxvoc; /* Number of sound card voices */
+
+ struct virt_channel *virt_channel;
+
+ struct mixer_voice *voice_array;
};
struct player_data {
@@ -342,7 +351,7 @@ struct player_data {
int master_vol; /* Music volume */
int gvol;
- struct flow_control flow;
+ struct flow_control flow;
struct {
int time; /* replay time in ms */
@@ -356,16 +365,7 @@ struct player_data {
int channel_vol[XMP_MAX_CHANNELS];
char channel_mute[XMP_MAX_CHANNELS];
- struct virt_control {
- int num_tracks; /* Number of tracks */
- int virt_channels; /* Number of virtual channels */
- int virt_used; /* Number of voices currently in use */
- int maxvoc; /* Number of sound card voices */
-
- struct virt_channel *virt_channel;
-
- struct mixer_voice *voice_array;
- } virt;
+ struct virt_control virt;
struct xmp_event inject_event[XMP_MAX_CHANNELS];
diff --git a/source/libxmp-lite/src/control.c b/source/libxmp-lite/src/control.c
index 342fee819..8102c9f4c 100644
--- a/source/libxmp-lite/src/control.c
+++ b/source/libxmp-lite/src/control.c
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -174,6 +174,37 @@ int xmp_set_position(xmp_context opaque, int pos)
return p->pos;
}
+int xmp_set_row(xmp_context opaque, int row)
+{
+ struct context_data *ctx = (struct context_data *)opaque;
+ struct player_data *p = &ctx->p;
+ struct module_data *m = &ctx->m;
+ struct xmp_module *mod = &m->mod;
+ struct flow_control *f = &p->flow;
+ int pos = p->pos;
+ int pattern = mod->xxo[pos];
+
+ if (pos < 0 || pos >= mod->len) {
+ pos = 0;
+ }
+
+ if (ctx->state < XMP_STATE_PLAYING)
+ return -XMP_ERROR_STATE;
+
+ if (row >= mod->xxp[pattern]->rows)
+ return -XMP_ERROR_INVALID;
+
+ /* See set_position. */
+ if (p->pos < 0)
+ p->pos = 0;
+ p->ord = p->pos;
+ p->row = row;
+ p->frame = -1;
+ f->num_rows = mod->xxp[mod->xxo[p->ord]]->rows;
+
+ return row;
+}
+
void xmp_stop_module(xmp_context opaque)
{
struct context_data *ctx = (struct context_data *)opaque;
@@ -275,12 +306,12 @@ int xmp_channel_vol(xmp_context opaque, int chn, int vol)
}
#ifdef USE_VERSIONED_SYMBOLS
-EXPORT extern int xmp_set_player_v40__(xmp_context, int, int);
-EXPORT extern int xmp_set_player_v41__(xmp_context, int, int)
+LIBXMP_EXPORT extern int xmp_set_player_v40__(xmp_context, int, int);
+LIBXMP_EXPORT extern int xmp_set_player_v41__(xmp_context, int, int)
__attribute__((alias("xmp_set_player_v40__")));
-EXPORT extern int xmp_set_player_v43__(xmp_context, int, int)
+LIBXMP_EXPORT extern int xmp_set_player_v43__(xmp_context, int, int)
__attribute__((alias("xmp_set_player_v40__")));
-EXPORT extern int xmp_set_player_v44__(xmp_context, int, int)
+LIBXMP_EXPORT extern int xmp_set_player_v44__(xmp_context, int, int)
__attribute__((alias("xmp_set_player_v40__")));
asm(".symver xmp_set_player_v40__, xmp_set_player@XMP_4.0");
@@ -393,14 +424,14 @@ int xmp_set_player__(xmp_context opaque, int parm, int val)
}
#ifdef USE_VERSIONED_SYMBOLS
-EXPORT extern int xmp_get_player_v40__(xmp_context, int);
-EXPORT extern int xmp_get_player_v41__(xmp_context, int)
+LIBXMP_EXPORT extern int xmp_get_player_v40__(xmp_context, int);
+LIBXMP_EXPORT extern int xmp_get_player_v41__(xmp_context, int)
__attribute__((alias("xmp_get_player_v40__")));
-EXPORT extern int xmp_get_player_v42__(xmp_context, int)
+LIBXMP_EXPORT extern int xmp_get_player_v42__(xmp_context, int)
__attribute__((alias("xmp_get_player_v40__")));
-EXPORT extern int xmp_get_player_v43__(xmp_context, int)
+LIBXMP_EXPORT extern int xmp_get_player_v43__(xmp_context, int)
__attribute__((alias("xmp_get_player_v40__")));
-EXPORT extern int xmp_get_player_v44__(xmp_context, int)
+LIBXMP_EXPORT extern int xmp_get_player_v44__(xmp_context, int)
__attribute__((alias("xmp_get_player_v40__")));
asm(".symver xmp_get_player_v40__, xmp_get_player@XMP_4.0");
@@ -527,3 +558,25 @@ int xmp_set_instrument_path(xmp_context opaque, char *path)
return 0;
}
+
+int xmp_set_tempo_factor(xmp_context opaque, double val)
+{
+ struct context_data *ctx = (struct context_data *)opaque;
+ struct player_data *p = &ctx->p;
+ struct module_data *m = &ctx->m;
+ struct mixer_data *s = &ctx->s;
+ int ticksize;
+
+ if (val <= 0.0) {
+ return -1;
+ }
+
+ val *= 10;
+ ticksize = s->freq * m->time_factor * m->rrate / p->bpm / 1000 * sizeof(int);
+ if (ticksize > XMP_MAX_FRAMESIZE) {
+ return -1;
+ }
+ m->time_factor = val;
+
+ return 0;
+}
diff --git a/source/libxmp-lite/src/dataio.c b/source/libxmp-lite/src/dataio.c
index c4c2253e9..002c0a4a7 100644
--- a/source/libxmp-lite/src/dataio.c
+++ b/source/libxmp-lite/src/dataio.c
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/source/libxmp-lite/src/effects.c b/source/libxmp-lite/src/effects.c
index 5d128020f..79a898fa3 100644
--- a/source/libxmp-lite/src/effects.c
+++ b/source/libxmp-lite/src/effects.c
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -540,9 +540,11 @@ void libxmp_process_fx(struct context_data *ctx, struct channel_data *xc, int ch
#ifndef LIBXMP_CORE_DISABLE_IT
case FX_IT_BPM: /* Set IT BPM */
- if (MSN(fxp) == 0) { /* T0x - Tempo slide down by x */
+ if (MSN(fxp) == 0) {
SET(TEMPO_SLIDE);
+ if (LSN(fxp)) /* T0x - Tempo slide down by x */
xc->tempo.slide = -LSN(fxp);
+ /* T00 - Repeat previous slide */
} else if (MSN(fxp) == 1) { /* T1x - Tempo slide up by x */
SET(TEMPO_SLIDE);
xc->tempo.slide = LSN(fxp);
@@ -586,8 +588,11 @@ void libxmp_process_fx(struct context_data *ctx, struct channel_data *xc, int ch
xc->vol.fslide2 = -fxp;
break;
case FX_IT_BREAK: /* Pattern break with hex parameter */
+ if (!f->loop_chn)
+ {
p->flow.pbreak = 1;
p->flow.jumpline = fxp;
+ }
break;
#endif
@@ -684,10 +689,10 @@ void libxmp_process_fx(struct context_data *ctx, struct channel_data *xc, int ch
EFFECT_MEMORY_S3M(fxp);
if (fxp) {
xc->retrig.val = fxp;
+ xc->retrig.type = MSN(xc->retrig.val);
}
if (note) {
xc->retrig.count = LSN(xc->retrig.val) + 1;
- xc->retrig.type = MSN(xc->retrig.val);
}
SET(RETRIG);
break;
diff --git a/source/libxmp-lite/src/hio.c b/source/libxmp-lite/src/hio.c
index e2356421d..91328ad89 100644
--- a/source/libxmp-lite/src/hio.c
+++ b/source/libxmp-lite/src/hio.c
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/source/libxmp-lite/src/it.h b/source/libxmp-lite/src/it.h
index b574c67e8..5c6fc63ef 100644
--- a/source/libxmp-lite/src/it.h
+++ b/source/libxmp-lite/src/it.h
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/source/libxmp-lite/src/it_load.c b/source/libxmp-lite/src/it_load.c
index e41e6dc1a..ea7858ce2 100644
--- a/source/libxmp-lite/src/it_load.c
+++ b/source/libxmp-lite/src/it_load.c
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -42,19 +42,22 @@ const struct format_loader libxmp_loader_it = {
it_load
};
+#ifndef LIBXMP_CORE_PLAYER /* */
#if defined(__WATCOMC__)
#undef localtime_r
#define localtime_r _localtime
#elif !defined(HAVE_LOCALTIME_R) || defined(_WIN32)
#undef localtime_r
-struct tm *localtime_r(const time_t * timep, struct tm *result)
+#define localtime_r libxmp_localtime_r
+static struct tm *libxmp_localtime_r(const time_t * timep, struct tm *result)
{
/* Note: Win32 localtime() is thread-safe */
memcpy(result, localtime(timep), sizeof(struct tm));
return result;
}
#endif
+#endif /* ! LIBXMP_CORE_PLAYER */
static int it_test(HIO_HANDLE * f, char *t, const int start)
{
@@ -280,14 +283,7 @@ static int read_envelope(struct xmp_envelope *ei, struct it_envelope *env,
}
env->flg = buf[0];
- env->num = buf[1];
-
- /* Sanity check */
- if (env->num >= XMP_MAX_ENV_POINTS) {
- env->flg = 0;
- env->num = 0;
- return -1;
- }
+ env->num = MIN(buf[1], 25); /* Clamp to IT max */
env->lpb = buf[2];
env->lpe = buf[3];
@@ -1140,7 +1136,6 @@ static int it_load(struct module_data *m, HIO_HANDLE *f, const int start)
}
if (ifh.chpan[i] & 0x80) { /* Channel mute */
- ifh.chvol[i] = 0;
xxc->flg |= XMP_CHANNEL_MUTE;
}
@@ -1348,7 +1343,7 @@ static int it_load(struct module_data *m, HIO_HANDLE *f, const int start)
D_(D_INFO "Message length : %d", ifh.msglen);
- for (j = 0; j < ifh.msglen - 1; j++) {
+ for (j = 0; j + 1 < ifh.msglen; j++) {
int b = hio_read8(f);
if (b == '\r') {
b = '\n';
@@ -1360,7 +1355,7 @@ static int it_load(struct module_data *m, HIO_HANDLE *f, const int start)
}
if (ifh.msglen > 0) {
- m->comment[j-1] = 0;
+ m->comment[j] = 0;
}
}
}
diff --git a/source/libxmp-lite/src/lfo.c b/source/libxmp-lite/src/lfo.c
index 5cdf4fb25..72911c1cd 100644
--- a/source/libxmp-lite/src/lfo.c
+++ b/source/libxmp-lite/src/lfo.c
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/source/libxmp-lite/src/load.c b/source/libxmp-lite/src/load.c
index ee873d933..fa1002d4b 100644
--- a/source/libxmp-lite/src/load.c
+++ b/source/libxmp-lite/src/load.c
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -34,9 +34,6 @@
#include "format.h"
#include "list.h"
#include "hio.h"
-#ifndef LIBXMP_CORE_PLAYER
-#include "tempfile.h"
-#endif
#ifndef LIBXMP_CORE_PLAYER
#if !defined(HAVE_POPEN) && defined(WIN32)
diff --git a/source/libxmp-lite/src/load_helpers.c b/source/libxmp-lite/src/load_helpers.c
index 37738121b..40cafe5db 100644
--- a/source/libxmp-lite/src/load_helpers.c
+++ b/source/libxmp-lite/src/load_helpers.c
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/source/libxmp-lite/src/memio.c b/source/libxmp-lite/src/memio.c
index 7646f5540..5112d12c8 100644
--- a/source/libxmp-lite/src/memio.c
+++ b/source/libxmp-lite/src/memio.c
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/source/libxmp-lite/src/mix_all.c b/source/libxmp-lite/src/mix_all.c
index cd5cda520..11ae8f691 100644
--- a/source/libxmp-lite/src/mix_all.c
+++ b/source/libxmp-lite/src/mix_all.c
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/source/libxmp-lite/src/mixer.c b/source/libxmp-lite/src/mixer.c
index d4a3e6644..22020f47b 100644
--- a/source/libxmp-lite/src/mixer.c
+++ b/source/libxmp-lite/src/mixer.c
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/source/libxmp-lite/src/mod.h b/source/libxmp-lite/src/mod.h
index 707d47cf2..8208c58e2 100644
--- a/source/libxmp-lite/src/mod.h
+++ b/source/libxmp-lite/src/mod.h
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/source/libxmp-lite/src/mtm_load.c b/source/libxmp-lite/src/mtm_load.c
index d48401973..d4bc76068 100644
--- a/source/libxmp-lite/src/mtm_load.c
+++ b/source/libxmp-lite/src/mtm_load.c
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/source/libxmp-lite/src/period.c b/source/libxmp-lite/src/period.c
index 7728902a0..582eba0df 100644
--- a/source/libxmp-lite/src/period.c
+++ b/source/libxmp-lite/src/period.c
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -138,10 +138,12 @@ static uint16 pt_period_table[16][36] = {
#define M_LN2 0.69314718055994530942
#endif
#if !defined(HAVE_ROUND) || defined(_MSC_VER) || defined(__WATCOMC__)
-static inline double round(double val)
+static inline double libxmp_round(double val)
{
return (val >= 0.0)? floor(val + 0.5) : ceil(val - 0.5);
}
+#else
+#define libxmp_round round
#endif
#ifdef LIBXMP_PAULA_SIMULATOR
@@ -219,7 +221,7 @@ int libxmp_period_to_note(int p)
return 0;
}
- return (int)round(12.0 * log(PERIOD_BASE / p) / M_LN2) + 1;
+ return libxmp_round(12.0 * log(PERIOD_BASE / p) / M_LN2) + 1;
}
/* Get pitchbend from base note and amiga period */
@@ -237,11 +239,11 @@ int libxmp_period_to_bend(struct context_data *ctx, double p, int n, double adj)
return (int) (100 * (8 * (((240 - n) << 4) - p)));
case PERIOD_CSPD:
d = libxmp_note_to_period(ctx, n, 0, adj);
- return (int) round(100.0 * (1536.0 / M_LN2) * log(p / d));
+ return libxmp_round(100.0 * (1536.0 / M_LN2) * log(p / d));
default:
/* Amiga */
d = libxmp_note_to_period(ctx, n, 0, adj);
- return (int) round(100.0 * (1536.0 / M_LN2) * log(d / p));
+ return libxmp_round(100.0 * (1536.0 / M_LN2) * log(d / p));
}
}
diff --git a/source/libxmp-lite/src/player.c b/source/libxmp-lite/src/player.c
index a75b6d368..834c03095 100644
--- a/source/libxmp-lite/src/player.c
+++ b/source/libxmp-lite/src/player.c
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -1502,8 +1502,13 @@ int xmp_start_player(xmp_context opaque, int rate, int format)
p->loop_count = 0;
p->sequence = 0;
- /* Unmute all channels and set default volume */
- for (i = 0; i < XMP_MAX_CHANNELS; i++) {
+ /* Set default volume and mute status */
+ for (i = 0; i < mod->chn; i++) {
+ if (mod->xxc[i].flg & XMP_CHANNEL_MUTE)
+ p->channel_mute[i] = 1;
+ p->channel_vol[i] = 100;
+ }
+ for (i = mod->chn; i < XMP_MAX_CHANNELS; i++) {
p->channel_mute[i] = 0;
p->channel_vol[i] = 100;
}
@@ -1553,6 +1558,9 @@ int xmp_start_player(xmp_context opaque, int rate, int format)
goto err1;
}
+ /* Reset our buffer pointers */
+ xmp_play_buffer(opaque, NULL, 0, 0);
+
#ifndef LIBXMP_CORE_PLAYER
for (i = 0; i < p->virt.virt_channels; i++) {
struct channel_data *xc = &p->xc_data[i];
diff --git a/source/libxmp-lite/src/read_event.c b/source/libxmp-lite/src/read_event.c
index 168f95d44..55a7f9bf3 100644
--- a/source/libxmp-lite/src/read_event.c
+++ b/source/libxmp-lite/src/read_event.c
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/source/libxmp-lite/src/s3m.h b/source/libxmp-lite/src/s3m.h
index 122e2d711..56717c57a 100644
--- a/source/libxmp-lite/src/s3m.h
+++ b/source/libxmp-lite/src/s3m.h
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/source/libxmp-lite/src/s3m_load.c b/source/libxmp-lite/src/s3m_load.c
index 66a580dbd..611fb0bd6 100644
--- a/source/libxmp-lite/src/s3m_load.c
+++ b/source/libxmp-lite/src/s3m_load.c
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/source/libxmp-lite/src/sample.c b/source/libxmp-lite/src/sample.c
index 3eb31dc98..a81939e57 100644
--- a/source/libxmp-lite/src/sample.c
+++ b/source/libxmp-lite/src/sample.c
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/source/libxmp-lite/src/scan.c b/source/libxmp-lite/src/scan.c
index 42b310659..f3358c3fc 100644
--- a/source/libxmp-lite/src/scan.c
+++ b/source/libxmp-lite/src/scan.c
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/source/libxmp-lite/src/smix.c b/source/libxmp-lite/src/smix.c
index bf501d7c3..878d35970 100644
--- a/source/libxmp-lite/src/smix.c
+++ b/source/libxmp-lite/src/smix.c
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -251,7 +251,7 @@ int xmp_smix_load_sample(xmp_context opaque, int num, char *path)
retval = -XMP_ERROR_SYSTEM;
goto err2;
}
- size = hio_read32l(h) / (bits / 8);
+ size = hio_read32l(h);
if (size == 0) {
retval = -XMP_ERROR_FORMAT;
goto err2;
@@ -264,11 +264,17 @@ int xmp_smix_load_sample(xmp_context opaque, int num, char *path)
xxs->lpe = 0;
xxs->flg = bits == 16 ? XMP_SAMPLE_16BIT : 0;
- xxs->data = (unsigned char *)malloc(size);
+ xxs->data = malloc(size + 8);
if (xxs->data == NULL) {
retval = -XMP_ERROR_SYSTEM;
goto err2;
}
+
+ /* ugly hack to make the interpolator happy */
+ memset(xxs->data, 0, 4);
+ memset(xxs->data + 4 + size, 0, 4);
+ xxs->data += 4;
+
if (hio_seek(h, 44, SEEK_SET) < 0) {
retval = -XMP_ERROR_SYSTEM;
goto err2;
@@ -300,7 +306,9 @@ int xmp_smix_release_sample(xmp_context opaque, int num)
return -XMP_ERROR_INVALID;
}
- free(smix->xxs[num].data);
+ if (smix->xxs[num].data != NULL) {
+ free(smix->xxs[num].data - 4);
+ }
free(smix->xxi[num].sub);
smix->xxs[num].data = NULL;
@@ -322,3 +330,4 @@ void xmp_end_smix(xmp_context opaque)
free(smix->xxs);
free(smix->xxi);
}
+
diff --git a/source/libxmp-lite/src/virtual.c b/source/libxmp-lite/src/virtual.c
index 4fa5cb1b1..77bcb6014 100644
--- a/source/libxmp-lite/src/virtual.c
+++ b/source/libxmp-lite/src/virtual.c
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
diff --git a/source/libxmp-lite/src/xm_load.c b/source/libxmp-lite/src/xm_load.c
index 7ccbc6ac8..e310f5d17 100644
--- a/source/libxmp-lite/src/xm_load.c
+++ b/source/libxmp-lite/src/xm_load.c
@@ -1,5 +1,5 @@
/* Extended Module Player
- * Copyright (C) 1996-2016 Claudio Matsuoka and Hipolito Carraro Jr
+ * Copyright (C) 1996-2018 Claudio Matsuoka and Hipolito Carraro Jr
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -351,6 +351,7 @@ static int load_instruments(struct module_data *m, int version, HIO_HANDLE * f)
struct xm_instrument xi;
struct xm_sample_header xsh[16];
int sample_num = 0;
+ long total_sample_size;
int i, j;
uint8 buf[208];
@@ -363,6 +364,7 @@ static int load_instruments(struct module_data *m, int version, HIO_HANDLE * f)
return -1;
for (i = 0; i < mod->ins; i++) {
+ long instr_pos = hio_tell(f);
struct xmp_instrument *xxi = &mod->xxi[i];
/* Modules converted with MOD2XM 1.0 always say we have 31
@@ -571,6 +573,7 @@ static int load_instruments(struct module_data *m, int version, HIO_HANDLE * f)
xxs->flg |= xsh[j].type & XM_LOOP_PINGPONG ? XMP_SAMPLE_LOOP | XMP_SAMPLE_LOOP_BIDIR : 0;
}
+ total_sample_size = 0;
for (j = 0; j < xxi->nsm; j++) {
struct xmp_subinstrument *sub = &xxi->sub[j];
int flags;
@@ -595,7 +598,19 @@ static int load_instruments(struct module_data *m, int version, HIO_HANDLE * f)
if (libxmp_load_sample(m, f, flags, &mod->xxs[sub->sid], NULL) < 0) {
return -1;
}
+ if (flags & SAMPLE_FLAG_ADPCM) {
+ total_sample_size += 16 + ((xsh[j].length + 1) >> 1);
+ } else {
+ total_sample_size += xsh[j].length;
+ }
}
+ }
+
+ /* Reposition correctly in case of 16-bit sample having odd in-file length.
+ * See "Lead Lined for '99", reported by Dennis Mulleneers.
+ */
+ if (hio_seek(f, instr_pos + xih.size + 40 * xih.samples + total_sample_size, SEEK_SET) < 0) {
+ return -1;
}
}