mirror of
https://github.com/QB64-Phoenix-Edition/QB64pe.git
synced 2024-09-20 09:04:43 +00:00
481906977e
This is a single commit adding all of a740g's audio backend. Later commits will connect it together with QB64PE itself.
190 lines
3.3 KiB
C
190 lines
3.3 KiB
C
#ifndef LIBXMP_CALLBACKIO_H
|
|
#define LIBXMP_CALLBACKIO_H
|
|
|
|
#include <stddef.h>
|
|
#include "common.h"
|
|
|
|
typedef struct {
|
|
void *priv;
|
|
struct xmp_callbacks callbacks;
|
|
int eof;
|
|
} CBFILE;
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
static inline uint8 cbread8(CBFILE *f, int *err)
|
|
{
|
|
uint8 x = 0xff;
|
|
size_t r = f->callbacks.read_func(&x, 1, 1, f->priv);
|
|
f->eof = (r == 1) ? 0 : EOF;
|
|
|
|
if (err) *err = f->eof;
|
|
|
|
return x;
|
|
}
|
|
|
|
static inline int8 cbread8s(CBFILE *f, int *err)
|
|
{
|
|
return (int8)cbread8(f, err);
|
|
}
|
|
|
|
static inline uint16 cbread16l(CBFILE *f, int *err)
|
|
{
|
|
uint8 buf[2];
|
|
uint16 x = EOF;
|
|
size_t r = f->callbacks.read_func(buf, 2, 1, f->priv);
|
|
f->eof = (r == 1) ? 0 : EOF;
|
|
|
|
if (r) x = readmem16l(buf);
|
|
if (err) *err = f->eof;
|
|
|
|
return x;
|
|
}
|
|
|
|
static inline uint16 cbread16b(CBFILE *f, int *err)
|
|
{
|
|
uint8 buf[2];
|
|
uint16 x = EOF;
|
|
size_t r = f->callbacks.read_func(buf, 2, 1, f->priv);
|
|
f->eof = (r == 1) ? 0 : EOF;
|
|
|
|
if (r) x = readmem16b(buf);
|
|
if (err) *err = f->eof;
|
|
|
|
return x;
|
|
}
|
|
|
|
static inline uint32 cbread24l(CBFILE *f, int *err)
|
|
{
|
|
uint8 buf[3];
|
|
uint32 x = EOF;
|
|
size_t r = f->callbacks.read_func(buf, 3, 1, f->priv);
|
|
f->eof = (r == 1) ? 0 : EOF;
|
|
|
|
if (r) x = readmem24l(buf);
|
|
if (err) *err = f->eof;
|
|
|
|
return x;
|
|
}
|
|
|
|
static inline uint32 cbread24b(CBFILE *f, int *err)
|
|
{
|
|
uint8 buf[3];
|
|
uint32 x = EOF;
|
|
size_t r = f->callbacks.read_func(buf, 3, 1, f->priv);
|
|
f->eof = (r == 1) ? 0 : EOF;
|
|
|
|
if (r) x = readmem24b(buf);
|
|
if (err) *err = f->eof;
|
|
|
|
return x;
|
|
}
|
|
|
|
static inline uint32 cbread32l(CBFILE *f, int *err)
|
|
{
|
|
uint8 buf[4];
|
|
uint32 x = EOF;
|
|
size_t r = f->callbacks.read_func(buf, 4, 1, f->priv);
|
|
f->eof = (r == 1) ? 0 : EOF;
|
|
|
|
if (r) x = readmem32l(buf);
|
|
if (err) *err = f->eof;
|
|
|
|
return x;
|
|
}
|
|
|
|
static inline uint32 cbread32b(CBFILE *f, int *err)
|
|
{
|
|
uint8 buf[4];
|
|
uint32 x = EOF;
|
|
size_t r = f->callbacks.read_func(buf, 4, 1, f->priv);
|
|
f->eof = (r == 1) ? 0 : EOF;
|
|
|
|
if (r) x = readmem32b(buf);
|
|
if (err) *err = f->eof;
|
|
|
|
return x;
|
|
}
|
|
|
|
static inline size_t cbread(void *dest, size_t len, size_t nmemb, CBFILE *f)
|
|
{
|
|
size_t r = f->callbacks.read_func(dest, len, nmemb, f->priv);
|
|
f->eof = (r < nmemb) ? EOF : 0;
|
|
return r;
|
|
}
|
|
|
|
static inline int cbseek(CBFILE *f, long offset, int whence)
|
|
{
|
|
f->eof = 0;
|
|
return f->callbacks.seek_func(f->priv, offset, whence);
|
|
}
|
|
|
|
static inline long cbtell(CBFILE *f)
|
|
{
|
|
return f->callbacks.tell_func(f->priv);
|
|
}
|
|
|
|
static inline int cbeof(CBFILE *f)
|
|
{
|
|
return f->eof;
|
|
}
|
|
|
|
static inline long cbfilelength(CBFILE *f)
|
|
{
|
|
long pos = f->callbacks.tell_func(f->priv);
|
|
long length;
|
|
int r;
|
|
|
|
if (pos < 0)
|
|
return EOF;
|
|
|
|
r = f->callbacks.seek_func(f->priv, 0, SEEK_END);
|
|
if (r < 0)
|
|
return EOF;
|
|
|
|
length = f->callbacks.tell_func(f->priv);
|
|
r = f->callbacks.seek_func(f->priv, pos, SEEK_SET);
|
|
|
|
return length;
|
|
}
|
|
|
|
static inline CBFILE *cbopen(void *priv, struct xmp_callbacks callbacks)
|
|
{
|
|
CBFILE *f;
|
|
if (priv == NULL || callbacks.read_func == NULL ||
|
|
callbacks.seek_func == NULL || callbacks.tell_func == NULL)
|
|
goto err;
|
|
|
|
f = (CBFILE *)calloc(1, sizeof(CBFILE));
|
|
if (f == NULL)
|
|
goto err;
|
|
|
|
f->priv = priv;
|
|
f->callbacks = callbacks;
|
|
f->eof = 0;
|
|
return f;
|
|
|
|
err:
|
|
if (priv && callbacks.close_func)
|
|
callbacks.close_func(priv);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static inline int cbclose(CBFILE *f)
|
|
{
|
|
int r = 0;
|
|
if (f->callbacks.close_func != NULL)
|
|
r = f->callbacks.close_func(f->priv);
|
|
|
|
free(f);
|
|
return r;
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* LIBXMP_CALLBACKIO_H */
|