reformatted original source to my editor settings

This commit is contained in:
Ilu
2023-04-28 15:08:06 +02:00
parent 60a2f78b46
commit e781aa5a1a
36 changed files with 744 additions and 1021 deletions

View File

@@ -1,10 +1,9 @@
#include "lib/cmixer/cmixer.h" #include "lib/cmixer/cmixer.h"
#include "soundblaster.h" #include "soundblaster.h"
static short audio_buffer[SOUNDBLASTER_SAMPLES_PER_BUFFER * 2]; static short audio_buffer[SOUNDBLASTER_SAMPLES_PER_BUFFER * 2];
static const short* audio_callback(void) { static const short *audio_callback(void) {
/* For the moment the soundblaster code expects mono audio while the cmixer /* For the moment the soundblaster code expects mono audio while the cmixer
** library outputs stereo -- we process to a stereo buffer, then copy the left ** library outputs stereo -- we process to a stereo buffer, then copy the left
** channel to the start of the buffer */ ** channel to the start of the buffer */
@@ -17,13 +16,9 @@ static const short* audio_callback(void) {
return audio_buffer; return audio_buffer;
} }
void audio_init(void) { void audio_init(void) {
cm_init(soundblaster_getSampleRate()); cm_init(soundblaster_getSampleRate());
soundblaster_init(audio_callback); soundblaster_init(audio_callback);
} }
void audio_deinit(void) { soundblaster_deinit(); }
void audio_deinit(void) {
soundblaster_deinit();
}

View File

@@ -19,32 +19,35 @@ static struct {
unsigned writei, readi; unsigned writei, readi;
} events; } events;
const char *event_typestr(int type) {
const char* event_typestr(int type) {
switch (type) { switch (type) {
case EVENT_QUIT : return "quit"; case EVENT_QUIT:
case EVENT_KEYBOARD_PRESSED : return "keypressed"; return "quit";
case EVENT_KEYBOARD_RELEASED : return "keyreleased"; case EVENT_KEYBOARD_PRESSED:
case EVENT_KEYBOARD_TEXTINPUT : return "textinput"; return "keypressed";
case EVENT_MOUSE_MOVED : return "mousemoved"; case EVENT_KEYBOARD_RELEASED:
case EVENT_MOUSE_PRESSED : return "mousepressed"; return "keyreleased";
case EVENT_MOUSE_RELEASED : return "mousereleased"; case EVENT_KEYBOARD_TEXTINPUT:
return "textinput";
case EVENT_MOUSE_MOVED:
return "mousemoved";
case EVENT_MOUSE_PRESSED:
return "mousepressed";
case EVENT_MOUSE_RELEASED:
return "mousereleased";
} }
return "?"; return "?";
} }
void event_push(event_t *e) { void event_push(event_t *e) {
events.buffer[events.writei++ & BUFFER_MASK] = *e; events.buffer[events.writei++ & BUFFER_MASK] = *e;
} }
void event_pump(void) { void event_pump(void) {
keyboard_update(); keyboard_update();
mouse_update(); mouse_update();
} }
int event_poll(event_t *e) { int event_poll(event_t *e) {
if (events.readi != events.writei) { if (events.readi != events.writei) {
*e = events.buffer[events.readi++ & BUFFER_MASK]; *e = events.buffer[events.readi++ & BUFFER_MASK];

View File

@@ -43,8 +43,7 @@ typedef union {
} event_t; } event_t;
const char *event_typestr(int type);
const char* event_typestr(int type);
void event_push(event_t *e); void event_push(event_t *e);
void event_pump(void); void event_pump(void);
int event_poll(event_t *e); int event_poll(event_t *e);

View File

@@ -17,8 +17,8 @@
#include "filesystem.h" #include "filesystem.h"
#define MAX_MOUNTS 8 #define MAX_MOUNTS 8
#define MAX_PATH 256 #define MAX_PATH 256
enum { enum {
FILESYSTEM_TNONE, FILESYSTEM_TNONE,
@@ -42,11 +42,9 @@ int filesystem_mountIdx;
mount_t filesystem_mounts[MAX_MOUNTS]; mount_t filesystem_mounts[MAX_MOUNTS];
char filesystem_writeDir[MAX_PATH]; char filesystem_writeDir[MAX_PATH];
#define FOREACH_MOUNT(var)\ #define FOREACH_MOUNT(var) \
for (mount_t *var = &filesystem_mounts[filesystem_mountIdx - 1];\ for (mount_t *var = &filesystem_mounts[filesystem_mountIdx - 1]; \
var >= filesystem_mounts;\ var >= filesystem_mounts; var--)
var--)
static int get_file_type(const char *filename) { static int get_file_type(const char *filename) {
/* The use of `stat` is intentionally avoided here, a stat call seems to /* The use of `stat` is intentionally avoided here, a stat call seems to
@@ -64,7 +62,6 @@ static int get_file_type(const char *filename) {
return FILESYSTEM_TNONE; return FILESYSTEM_TNONE;
} }
static int concat_path(char *dst, const char *dir, const char *filename) { static int concat_path(char *dst, const char *dir, const char *filename) {
int dirlen = strlen(dir); int dirlen = strlen(dir);
int filenamelen = strlen(filename); int filenamelen = strlen(filename);
@@ -75,7 +72,7 @@ static int concat_path(char *dst, const char *dir, const char *filename) {
} }
/* Write full name to buffer and return ok */ /* Write full name to buffer and return ok */
if ( dir[dirlen - 1] == '/' ) { if (dir[dirlen - 1] == '/') {
sprintf(dst, "%s%s", dir, filename); sprintf(dst, "%s%s", dir, filename);
} else { } else {
sprintf(dst, "%s/%s", dir, filename); sprintf(dst, "%s/%s", dir, filename);
@@ -83,7 +80,6 @@ static int concat_path(char *dst, const char *dir, const char *filename) {
return FILESYSTEM_ESUCCESS; return FILESYSTEM_ESUCCESS;
} }
static int concat_and_get_file_type(const char *dir, const char *filename) { static int concat_and_get_file_type(const char *dir, const char *filename) {
char buf[MAX_PATH]; char buf[MAX_PATH];
/* Make fullpath */ /* Make fullpath */
@@ -95,7 +91,6 @@ static int concat_and_get_file_type(const char *dir, const char *filename) {
return get_file_type(buf); return get_file_type(buf);
} }
static unsigned hash_string_ignore_case(const char *str) { static unsigned hash_string_ignore_case(const char *str) {
unsigned hash = 5381; unsigned hash = 5381;
while (*str) { while (*str) {
@@ -104,7 +99,6 @@ static unsigned hash_string_ignore_case(const char *str) {
return hash; return hash;
} }
static int strings_equal_ignore_case(const char *a, const char *b) { static int strings_equal_ignore_case(const char *a, const char *b) {
while (*a) { while (*a) {
if (tolower(*a++) != tolower(*b++)) { if (tolower(*a++) != tolower(*b++)) {
@@ -114,7 +108,6 @@ static int strings_equal_ignore_case(const char *a, const char *b) {
return !*b; return !*b;
} }
static void strip_trailing_slash(char *str) { static void strip_trailing_slash(char *str) {
int len = strlen(str); int len = strlen(str);
if (len > 0 && str[len - 1] == '/') { if (len > 0 && str[len - 1] == '/') {
@@ -122,11 +115,7 @@ static void strip_trailing_slash(char *str) {
} }
} }
static int is_separator(int chr) { return (chr == '/' || chr == '\\'); }
static int is_separator(int chr) {
return (chr == '/' || chr == '\\');
}
static int make_dirs(const char *path) { static int make_dirs(const char *path) {
char str[MAX_PATH]; char str[MAX_PATH];
@@ -135,8 +124,10 @@ static int make_dirs(const char *path) {
if (err) { if (err) {
return err; return err;
} }
if (p[0] == '/') p++; if (p[0] == '/')
if (p[0] && p[1] == ':' && p[2] == '\\') p += 3; p++;
if (p[0] && p[1] == ':' && p[2] == '\\')
p += 3;
while (*p) { while (*p) {
if (is_separator(*p)) { if (is_separator(*p)) {
*p = '\0'; *p = '\0';
@@ -152,32 +143,25 @@ static int make_dirs(const char *path) {
return FILESYSTEM_ESUCCESS; return FILESYSTEM_ESUCCESS;
} }
/*==================*/ /*==================*/
/* Directory mount */ /* Directory mount */
/*==================*/ /*==================*/
static void dir_unmount(mount_t *mnt) { static void dir_unmount(mount_t *mnt) { /* Intentionally empty */ }
/* Intentionally empty */
}
static int dir_exists(mount_t *mnt, const char *filename) { static int dir_exists(mount_t *mnt, const char *filename) {
return concat_and_get_file_type(mnt->path, filename) != FILESYSTEM_TNONE; return concat_and_get_file_type(mnt->path, filename) != FILESYSTEM_TNONE;
} }
static int dir_isFile(mount_t *mnt, const char *filename) { static int dir_isFile(mount_t *mnt, const char *filename) {
return concat_and_get_file_type(mnt->path, filename) == FILESYSTEM_TREG; return concat_and_get_file_type(mnt->path, filename) == FILESYSTEM_TREG;
} }
static int dir_isDirectory(mount_t *mnt, const char *filename) { static int dir_isDirectory(mount_t *mnt, const char *filename) {
return concat_and_get_file_type(mnt->path, filename) == FILESYSTEM_TDIR; return concat_and_get_file_type(mnt->path, filename) == FILESYSTEM_TDIR;
} }
static void *dir_read(mount_t *mnt, const char *filename, int *size) {
static void* dir_read(mount_t *mnt, const char *filename, int *size) {
char buf[MAX_PATH]; char buf[MAX_PATH];
/* Make fullpath */ /* Make fullpath */
int err = concat_path(buf, mnt->path, filename); int err = concat_path(buf, mnt->path, filename);
@@ -204,10 +188,9 @@ static void* dir_read(mount_t *mnt, const char *filename, int *size) {
return p; return p;
} }
static int dir_mount(mount_t *mnt, const char *path) { static int dir_mount(mount_t *mnt, const char *path) {
/* Check the path is actually a directory */ /* Check the path is actually a directory */
if ( get_file_type(path) != FILESYSTEM_TDIR ) { if (get_file_type(path) != FILESYSTEM_TDIR) {
return FILESYSTEM_EFAILURE; return FILESYSTEM_EFAILURE;
} }
@@ -223,12 +206,13 @@ static int dir_mount(mount_t *mnt, const char *path) {
return FILESYSTEM_ESUCCESS; return FILESYSTEM_ESUCCESS;
} }
/*==================*/ /*==================*/
/* Tar mount */ /* Tar mount */
/*==================*/ /*==================*/
typedef struct { unsigned hash, pos; } tar_file_ref_t; typedef struct {
unsigned hash, pos;
} tar_file_ref_t;
typedef struct { typedef struct {
mtar_t tar; mtar_t tar;
@@ -238,7 +222,6 @@ typedef struct {
int nfiles; int nfiles;
} tar_mount_t; } tar_mount_t;
static int tar_find(mount_t *mnt, const char *filename, mtar_header_t *h) { static int tar_find(mount_t *mnt, const char *filename, mtar_header_t *h) {
/* Hash filename and linear search map for matching hash, read header and /* Hash filename and linear search map for matching hash, read header and
* check against filename if the hashes match */ * check against filename if the hashes match */
@@ -257,12 +240,10 @@ static int tar_find(mount_t *mnt, const char *filename, mtar_header_t *h) {
return FILESYSTEM_ESUCCESS; return FILESYSTEM_ESUCCESS;
} }
} }
} }
return FILESYSTEM_EFAILURE; return FILESYSTEM_EFAILURE;
} }
static void tar_unmount(mount_t *mnt) { static void tar_unmount(mount_t *mnt) {
tar_mount_t *tm = mnt->udata; tar_mount_t *tm = mnt->udata;
mtar_close(&tm->tar); mtar_close(&tm->tar);
@@ -270,13 +251,11 @@ static void tar_unmount(mount_t *mnt) {
dmt_free(tm); dmt_free(tm);
} }
static int tar_exists(mount_t *mnt, const char *filename) { static int tar_exists(mount_t *mnt, const char *filename) {
mtar_header_t h; mtar_header_t h;
return tar_find(mnt, filename, &h) == FILESYSTEM_ESUCCESS; return tar_find(mnt, filename, &h) == FILESYSTEM_ESUCCESS;
} }
static int tar_isFile(mount_t *mnt, const char *filename) { static int tar_isFile(mount_t *mnt, const char *filename) {
mtar_header_t h; mtar_header_t h;
int err = tar_find(mnt, filename, &h); int err = tar_find(mnt, filename, &h);
@@ -286,7 +265,6 @@ static int tar_isFile(mount_t *mnt, const char *filename) {
return h.type == MTAR_TREG; return h.type == MTAR_TREG;
} }
static int tar_isDirectory(mount_t *mnt, const char *filename) { static int tar_isDirectory(mount_t *mnt, const char *filename) {
mtar_header_t h; mtar_header_t h;
int err = tar_find(mnt, filename, &h); int err = tar_find(mnt, filename, &h);
@@ -296,8 +274,7 @@ static int tar_isDirectory(mount_t *mnt, const char *filename) {
return h.type == MTAR_TDIR; return h.type == MTAR_TDIR;
} }
static void *tar_read(mount_t *mnt, const char *filename, int *size) {
static void* tar_read(mount_t *mnt, const char *filename, int *size) {
mtar_t *tar = mnt->udata; mtar_t *tar = mnt->udata;
int err; int err;
mtar_header_t h; mtar_header_t h;
@@ -319,28 +296,24 @@ static void* tar_read(mount_t *mnt, const char *filename, int *size) {
return p; return p;
} }
static int tar_stream_read(mtar_t *tar, void *data, unsigned size) { static int tar_stream_read(mtar_t *tar, void *data, unsigned size) {
tar_mount_t *tm = tar->stream; tar_mount_t *tm = tar->stream;
unsigned res = fread(data, 1, size, tm->fp); unsigned res = fread(data, 1, size, tm->fp);
return (res == size) ? MTAR_ESUCCESS : MTAR_EREADFAIL; return (res == size) ? MTAR_ESUCCESS : MTAR_EREADFAIL;
} }
static int tar_stream_seek(mtar_t *tar, unsigned offset) { static int tar_stream_seek(mtar_t *tar, unsigned offset) {
tar_mount_t *tm = tar->stream; tar_mount_t *tm = tar->stream;
int res = fseek(tm->fp, tm->offset + offset, SEEK_SET); int res = fseek(tm->fp, tm->offset + offset, SEEK_SET);
return (res == 0) ? MTAR_ESUCCESS : MTAR_ESEEKFAIL; return (res == 0) ? MTAR_ESUCCESS : MTAR_ESEEKFAIL;
} }
static int tar_stream_close(mtar_t *tar) { static int tar_stream_close(mtar_t *tar) {
tar_mount_t *tm = tar->stream; tar_mount_t *tm = tar->stream;
fclose(tm->fp); fclose(tm->fp);
return MTAR_ESUCCESS; return MTAR_ESUCCESS;
} }
static int tar_mount(mount_t *mnt, const char *path) { static int tar_mount(mount_t *mnt, const char *path) {
tar_mount_t *tm = NULL; tar_mount_t *tm = NULL;
FILE *fp = NULL; FILE *fp = NULL;
@@ -376,7 +349,7 @@ static int tar_mount(mount_t *mnt, const char *path) {
fseek(fp, -8, SEEK_END); fseek(fp, -8, SEEK_END);
fread(buf, 1, 4, fp); fread(buf, 1, 4, fp);
fread(&offset, 1, 4, fp); fread(&offset, 1, 4, fp);
if ( !memcmp(buf, "TAR\0", 4) ) { if (!memcmp(buf, "TAR\0", 4)) {
fseek(fp, -offset, SEEK_END); fseek(fp, -offset, SEEK_END);
tm->offset = ftell(fp); tm->offset = ftell(fp);
} }
@@ -392,7 +365,7 @@ static int tar_mount(mount_t *mnt, const char *path) {
mtar_rewind(tar); mtar_rewind(tar);
int n = 0; int n = 0;
int cap = 0; int cap = 0;
while ( (mtar_read_header(tar, &h)) == MTAR_ESUCCESS ) { while ((mtar_read_header(tar, &h)) == MTAR_ESUCCESS) {
/* Realloc if map capacity was reached */ /* Realloc if map capacity was reached */
if (n >= cap) { if (n >= cap) {
cap = cap ? (cap << 1) : 16; cap = cap ? (cap << 1) : 16;
@@ -420,7 +393,8 @@ static int tar_mount(mount_t *mnt, const char *path) {
return FILESYSTEM_ESUCCESS; return FILESYSTEM_ESUCCESS;
fail: fail:
if (fp) fclose(fp); if (fp)
fclose(fp);
if (tm) { if (tm) {
dmt_free(tm->map); dmt_free(tm->map);
dmt_free(tm); dmt_free(tm);
@@ -428,43 +402,47 @@ fail:
return FILESYSTEM_EFAILURE; return FILESYSTEM_EFAILURE;
} }
/*==================*/ /*==================*/
/* Filesystem */ /* Filesystem */
/*==================*/ /*==================*/
const char* filesystem_strerror(int err) { const char *filesystem_strerror(int err) {
switch (err) { switch (err) {
case FILESYSTEM_ESUCCESS : return "success"; case FILESYSTEM_ESUCCESS:
case FILESYSTEM_EFAILURE : return "failure"; return "success";
case FILESYSTEM_ETOOLONG : return "path too long"; case FILESYSTEM_EFAILURE:
case FILESYSTEM_EMOUNTED : return "path already mounted"; return "failure";
case FILESYSTEM_ENOMOUNT : return "path is not mounted"; case FILESYSTEM_ETOOLONG:
case FILESYSTEM_EMOUNTFAIL : return "could not mount path"; return "path too long";
case FILESYSTEM_ENOWRITEDIR : return "no write directory set"; case FILESYSTEM_EMOUNTED:
case FILESYSTEM_EWRITEFAIL : return "could not write file"; return "path already mounted";
case FILESYSTEM_EMKDIRFAIL : return "could not make directory"; case FILESYSTEM_ENOMOUNT:
return "path is not mounted";
case FILESYSTEM_EMOUNTFAIL:
return "could not mount path";
case FILESYSTEM_ENOWRITEDIR:
return "no write directory set";
case FILESYSTEM_EWRITEFAIL:
return "could not write file";
case FILESYSTEM_EMKDIRFAIL:
return "could not make directory";
} }
return "unknown error"; return "unknown error";
} }
void filesystem_deinit(void) { void filesystem_deinit(void) {
FOREACH_MOUNT(mnt) { FOREACH_MOUNT(mnt) { mnt->unmount(mnt); }
mnt->unmount(mnt);
}
filesystem_mountIdx = 0; filesystem_mountIdx = 0;
} }
int filesystem_mount(const char *path) { int filesystem_mount(const char *path) {
/* Check path length is ok */ /* Check path length is ok */
if ( strlen(path) >= MAX_PATH ) { if (strlen(path) >= MAX_PATH) {
return FILESYSTEM_ETOOLONG; return FILESYSTEM_ETOOLONG;
} }
/* Check path isn't already mounted */ /* Check path isn't already mounted */
FOREACH_MOUNT(m) { FOREACH_MOUNT(m) {
if ( !strcmp(m->path, path) ) { if (!strcmp(m->path, path)) {
return FILESYSTEM_EMOUNTED; return FILESYSTEM_EMOUNTED;
} }
} }
@@ -479,8 +457,10 @@ int filesystem_mount(const char *path) {
strcpy(mnt->path, path); strcpy(mnt->path, path);
/* Try to mount path */ /* Try to mount path */
if ( tar_mount(mnt, path) == FILESYSTEM_ESUCCESS ) goto success; if (tar_mount(mnt, path) == FILESYSTEM_ESUCCESS)
if ( dir_mount(mnt, path) == FILESYSTEM_ESUCCESS ) goto success; goto success;
if (dir_mount(mnt, path) == FILESYSTEM_ESUCCESS)
goto success;
/* Fail */ /* Fail */
filesystem_mountIdx--; filesystem_mountIdx--;
@@ -490,10 +470,9 @@ success:
return FILESYSTEM_ESUCCESS; return FILESYSTEM_ESUCCESS;
} }
int filesystem_unmount(const char *path) { int filesystem_unmount(const char *path) {
FOREACH_MOUNT(mnt) { FOREACH_MOUNT(mnt) {
if ( !strcmp(mnt->path, path) ) { if (!strcmp(mnt->path, path)) {
/* Unmount */ /* Unmount */
mnt->unmount(mnt); mnt->unmount(mnt);
/* Shift remaining mounts to fill gap and decrement idx */ /* Shift remaining mounts to fill gap and decrement idx */
@@ -506,51 +485,43 @@ int filesystem_unmount(const char *path) {
return FILESYSTEM_ENOMOUNT; return FILESYSTEM_ENOMOUNT;
} }
int filesystem_exists(const char *filename) { int filesystem_exists(const char *filename) {
FOREACH_MOUNT(mnt) { FOREACH_MOUNT(mnt) {
if ( mnt->exists(mnt, filename) ) { if (mnt->exists(mnt, filename)) {
return 1; return 1;
} }
} }
return 0; return 0;
} }
int filesystem_isFile(const char *filename) { int filesystem_isFile(const char *filename) {
FOREACH_MOUNT(mnt) { FOREACH_MOUNT(mnt) {
if ( mnt->exists(mnt, filename) ) { if (mnt->exists(mnt, filename)) {
return mnt->isFile(mnt, filename); return mnt->isFile(mnt, filename);
} }
} }
return 0; return 0;
} }
int filesystem_isDirectory(const char *filename) { int filesystem_isDirectory(const char *filename) {
FOREACH_MOUNT(mnt) { FOREACH_MOUNT(mnt) {
if ( mnt->exists(mnt, filename) ) { if (mnt->exists(mnt, filename)) {
return mnt->isDirectory(mnt, filename); return mnt->isDirectory(mnt, filename);
} }
} }
return 0; return 0;
} }
void *filesystem_read(const char *filename, int *size) {
void* filesystem_read(const char *filename, int *size) {
FOREACH_MOUNT(mnt) { FOREACH_MOUNT(mnt) {
if ( mnt->exists(mnt, filename) && mnt->isFile(mnt, filename) ) { if (mnt->exists(mnt, filename) && mnt->isFile(mnt, filename)) {
return mnt->read(mnt, filename, size); return mnt->read(mnt, filename, size);
} }
} }
return NULL; return NULL;
} }
void filesystem_free(void *ptr) { dmt_free(ptr); }
void filesystem_free(void *ptr) {
dmt_free(ptr);
}
int filesystem_setWriteDir(const char *path) { int filesystem_setWriteDir(const char *path) {
if (strlen(path) >= MAX_PATH) { if (strlen(path) >= MAX_PATH) {
@@ -564,7 +535,6 @@ int filesystem_setWriteDir(const char *path) {
return FILESYSTEM_ESUCCESS; return FILESYSTEM_ESUCCESS;
} }
int filesystem_write(const char *filename, const void *data, int size) { int filesystem_write(const char *filename, const void *data, int size) {
int err, n; int err, n;
char buf[MAX_PATH]; char buf[MAX_PATH];

View File

@@ -13,25 +13,25 @@
#include <stddef.h> #include <stddef.h>
enum { enum {
FILESYSTEM_ESUCCESS = 0, FILESYSTEM_ESUCCESS = 0,
FILESYSTEM_EFAILURE = -1, FILESYSTEM_EFAILURE = -1,
FILESYSTEM_ETOOLONG = -2, FILESYSTEM_ETOOLONG = -2,
FILESYSTEM_EMOUNTED = -3, FILESYSTEM_EMOUNTED = -3,
FILESYSTEM_ENOMOUNT = -4, FILESYSTEM_ENOMOUNT = -4,
FILESYSTEM_EMOUNTFAIL = -5, FILESYSTEM_EMOUNTFAIL = -5,
FILESYSTEM_ENOWRITEDIR = -6, FILESYSTEM_ENOWRITEDIR = -6,
FILESYSTEM_EWRITEFAIL = -7, FILESYSTEM_EWRITEFAIL = -7,
FILESYSTEM_EMKDIRFAIL = -8 FILESYSTEM_EMKDIRFAIL = -8
}; };
const char* filesystem_strerror(int err); const char *filesystem_strerror(int err);
void filesystem_deinit(void); void filesystem_deinit(void);
int filesystem_mount(const char *path); int filesystem_mount(const char *path);
int filesystem_unmount(const char *path); int filesystem_unmount(const char *path);
int filesystem_exists(const char *filename); int filesystem_exists(const char *filename);
int filesystem_isFile(const char *filename); int filesystem_isFile(const char *filename);
int filesystem_isDirectory(const char *filename); int filesystem_isDirectory(const char *filename);
void* filesystem_read(const char *filename, int *size); void *filesystem_read(const char *filename, int *size);
void filesystem_free(void *ptr); void filesystem_free(void *ptr);
int filesystem_setWriteDir(const char *path); int filesystem_setWriteDir(const char *path);
int filesystem_write(const char *filename, const void *data, int size); int filesystem_write(const char *filename, const void *data, int size);

View File

@@ -14,13 +14,12 @@
#include "filesystem.h" #include "filesystem.h"
#include "font.h" #include "font.h"
static const char *initFont(font_t *self, const void *data, int ptsize) { static const char *initFont(font_t *self, const void *data, int ptsize) {
int i; int i;
/* Init font */ /* Init font */
stbtt_fontinfo font; stbtt_fontinfo font;
if ( !stbtt_InitFont(&font, data, 0) ) { if (!stbtt_InitFont(&font, data, 0)) {
return "could not load font"; return "could not load font";
} }
@@ -38,8 +37,8 @@ retry:
/* Load glyphs */ /* Load glyphs */
float s = stbtt_ScaleForMappingEmToPixels(&font, 1) / float s = stbtt_ScaleForMappingEmToPixels(&font, 1) /
stbtt_ScaleForPixelHeight(&font, 1); stbtt_ScaleForPixelHeight(&font, 1);
int res = stbtt_BakeFontBitmap( int res = stbtt_BakeFontBitmap(data, 0, ptsize * s, self->image.data, w, h, 0,
data, 0, ptsize * s, self->image.data, w, h, 0, 128, self->glyphs); 128, self->glyphs);
/* Retry with a larger image buffer if the buffer wasn't large enough */ /* Retry with a larger image buffer if the buffer wasn't large enough */
if (res < 0) { if (res < 0) {
@@ -65,7 +64,6 @@ retry:
return NULL; return NULL;
} }
const char *font_init(font_t *self, const char *filename, int ptsize) { const char *font_init(font_t *self, const char *filename, int ptsize) {
const char *errmsg = NULL; const char *errmsg = NULL;
void *data = NULL; void *data = NULL;
@@ -93,29 +91,24 @@ const char *font_init(font_t *self, const char *filename, int ptsize) {
return NULL; return NULL;
fail: fail:
if (fp) fclose(fp); if (fp)
fclose(fp);
filesystem_free(data); filesystem_free(data);
return errmsg; return errmsg;
} }
const char *font_initEmbedded(font_t *self, int ptsize) { const char *font_initEmbedded(font_t *self, int ptsize) {
#include "font_ttf.h" #include "font_ttf.h"
return initFont(self, font_ttf, ptsize); return initFont(self, font_ttf, ptsize);
} }
void font_deinit(font_t *self) { image_deinit(&self->image); }
void font_deinit(font_t *self) {
image_deinit(&self->image);
}
extern int image_blendMode; extern int image_blendMode;
extern int image_flip; extern int image_flip;
void font_blit(font_t *self, pixel_t *buf, int bufw, int bufh, void font_blit(font_t *self, pixel_t *buf, int bufw, int bufh, const char *str,
const char *str, int dx, int dy int dx, int dy) {
) {
const char *p = str; const char *p = str;
int x = dx; int x = dx;
int y = dy; int y = dy;
@@ -130,11 +123,11 @@ void font_blit(font_t *self, pixel_t *buf, int bufw, int bufh,
x = dx; x = dx;
y += self->height; y += self->height;
} else { } else {
stbtt_bakedchar *g = &self->glyphs[(int) (*p & 127)]; stbtt_bakedchar *g = &self->glyphs[(int)(*p & 127)];
int w = g->x1 - g->x0; int w = g->x1 - g->x0;
int h = g->y1 - g->y0; int h = g->y1 - g->y0;
image_blit(&self->image, buf, bufw, bufh, image_blit(&self->image, buf, bufw, bufh, x + g->xoff, y + g->yoff, g->x0,
x + g->xoff, y + g->yoff, g->x0, g->y0, w, h); g->y0, w, h);
x += g->xadvance; x += g->xadvance;
} }
p++; p++;

View File

@@ -20,8 +20,7 @@ typedef struct {
const char *font_init(font_t *self, const char *filename, int ptsize); const char *font_init(font_t *self, const char *filename, int ptsize);
const char *font_initEmbedded(font_t *self, int ptsize); const char *font_initEmbedded(font_t *self, int ptsize);
void font_deinit(font_t *self); void font_deinit(font_t *self);
void font_blit(font_t *self, pixel_t *buf, int bufw, int bufh, void font_blit(font_t *self, pixel_t *buf, int bufw, int bufh, const char *str,
const char *str, int dx, int dy); int dx, int dy);
#endif #endif

View File

@@ -19,20 +19,13 @@ int image_blendMode = IMAGE_NORMAL;
int image_flip = 0; int image_flip = 0;
unsigned int image_color = 0x0f0f0f0f; unsigned int image_color = 0x0f0f0f0f;
void image_setBlendMode(int mode) { image_blendMode = mode; }
void image_setBlendMode(int mode) {
image_blendMode = mode;
}
void image_setColor(pixel_t color) { void image_setColor(pixel_t color) {
image_color = color | (color << 8) | (color << 16) | (color << 24); image_color = color | (color << 8) | (color << 16) | (color << 24);
} }
void image_setFlip(int mode) { void image_setFlip(int mode) { image_flip = !!mode; }
image_flip = !!mode;
}
const char *image_init(image_t *self, const char *filename) { const char *image_init(image_t *self, const char *filename) {
/* Loads an image file into the struct and inits the mask */ /* Loads an image file into the struct and inits the mask */
@@ -101,7 +94,6 @@ fail:
return errmsg; return errmsg;
} }
void image_initBlank(image_t *self, int width, int height) { void image_initBlank(image_t *self, int width, int height) {
/* Creates a blank zeroset image with a zeroset mask. This function can be /* Creates a blank zeroset image with a zeroset mask. This function can be
* used to init the image instead of image_init() */ * used to init the image instead of image_init() */
@@ -113,99 +105,124 @@ void image_initBlank(image_t *self, int width, int height) {
self->mask = dmt_calloc(1, width * height); self->mask = dmt_calloc(1, width * height);
} }
void image_blit(image_t *self, pixel_t *buf, int bufw, int bufh, int dx, int dy,
void image_blit(image_t *self, pixel_t *buf, int bufw, int bufh, int sx, int sy, int sw, int sh) {
int dx, int dy, int sx, int sy, int sw, int sh
) {
int diff; int diff;
/* Clip to source buffer */ /* Clip to source buffer */
if (sx < 0) { sw -= sx; sx = 0; } if (sx < 0) {
if (sy < 0) { sy -= sy; sy = 0; } sw -= sx;
if ((diff = (sx + sw) - self->width) > 0) { sw -= diff; } sx = 0;
if ((diff = (sy + sh) - self->height) > 0) { sh -= diff; } }
if (sy < 0) {
sy -= sy;
sy = 0;
}
if ((diff = (sx + sw) - self->width) > 0) {
sw -= diff;
}
if ((diff = (sy + sh) - self->height) > 0) {
sh -= diff;
}
/* Clip to destination buffer */ /* Clip to destination buffer */
if (!image_flip) { if (!image_flip) {
if ((diff = -dx) > 0) { sw -= diff; sx += diff; dx += diff; } if ((diff = -dx) > 0) {
if ((diff = dx + sw - bufw) >= 0) { sw -= diff; } sw -= diff;
sx += diff;
dx += diff;
}
if ((diff = dx + sw - bufw) >= 0) {
sw -= diff;
}
} else { } else {
if ((diff = -dx) > 0) { sw -= diff; dx += diff; } if ((diff = -dx) > 0) {
if ((diff = dx + sw - bufw) >= 0) { sx += diff; sw -= diff; } sw -= diff;
dx += diff;
}
if ((diff = dx + sw - bufw) >= 0) {
sx += diff;
sw -= diff;
}
}
if ((diff = dy + sh - bufh) >= 0) {
sh -= diff;
}
if ((diff = -dy) > 0) {
sh -= diff;
sy += diff;
dy += diff;
} }
if ((diff = dy + sh - bufh) >= 0) { sh -= diff; }
if ((diff = -dy) > 0) { sh -= diff; sy += diff; dy += diff; }
/* Return early if we're clipped entirely off the dest / source */ /* Return early if we're clipped entirely off the dest / source */
if (sw <= 0 || sh <= 0) return; if (sw <= 0 || sh <= 0)
return;
/* Blit */ /* Blit */
#define BLIT_LOOP_NORMAL(func)\ #define BLIT_LOOP_NORMAL(func) \
{\ { \
int x, y;\ int x, y; \
int srci = sx + sy * self->width;\ int srci = sx + sy * self->width; \
int dsti = dx + dy * bufw;\ int dsti = dx + dy * bufw; \
int srcrowdiff = self->width - sw;\ int srcrowdiff = self->width - sw; \
int dstrowdiff = bufw - sw;\ int dstrowdiff = bufw - sw; \
int sw32 = sw - (sw & 3);\ int sw32 = sw - (sw & 3); \
for (y = 0; y < sh; y++) {\ for (y = 0; y < sh; y++) { \
for (x = 0; x < sw32; x += 4) {\ for (x = 0; x < sw32; x += 4) { \
func(*(unsigned int*)&buf[dsti],\ func(*(unsigned int *)&buf[dsti], *(unsigned int *)&self->data[srci], \
*(unsigned int*)&self->data[srci],\ *(unsigned int *)&self->mask[srci]) srci += 4; \
*(unsigned int*)&self->mask[srci])\ dsti += 4; \
srci += 4;\ } \
dsti += 4;\ for (; x < sw; x++) { \
}\ func(buf[dsti], self->data[srci], self->mask[srci]) srci++; \
for (; x < sw; x++) {\ dsti++; \
func(buf[dsti], self->data[srci], self->mask[srci])\ } \
srci++;\ srci += srcrowdiff; \
dsti++;\ dsti += dstrowdiff; \
}\ } \
srci += srcrowdiff;\ }
dsti += dstrowdiff;\
}\
}
#define BLIT_LOOP_FLIPPED(func)\ #define BLIT_LOOP_FLIPPED(func) \
{\ { \
int x, y;\ int x, y; \
int srci = sx + sy * self->width + sw - 1;\ int srci = sx + sy * self->width + sw - 1; \
int dsti = dx + dy * bufw;\ int dsti = dx + dy * bufw; \
int srcrowdiff = self->width + sw;\ int srcrowdiff = self->width + sw; \
int dstrowdiff = bufw - sw;\ int dstrowdiff = bufw - sw; \
for (y = 0; y < sh; y++) {\ for (y = 0; y < sh; y++) { \
for (x = 0; x < sw; x++) {\ for (x = 0; x < sw; x++) { \
func(buf[dsti], self->data[srci], self->mask[srci])\ func(buf[dsti], self->data[srci], self->mask[srci]) srci--; \
srci--;\ dsti++; \
dsti++;\ } \
}\ srci += srcrowdiff; \
srci += srcrowdiff;\ dsti += dstrowdiff; \
dsti += dstrowdiff;\ } \
}\ }
}
#define BLIT_NORMAL(dst, src, msk)\ #define BLIT_NORMAL(dst, src, msk) \
(dst) &= (msk);\ (dst) &= (msk); \
(dst) |= (src); (dst) |= (src);
#define BLIT_AND(dst, src, msk)\ #define BLIT_AND(dst, src, msk) (dst) &= (src);
(dst) &= (src);
#define BLIT_OR(dst, src, msk)\ #define BLIT_OR(dst, src, msk) (dst) |= (src);
(dst) |= (src);
#define BLIT_COLOR(dst, src, msk)\ #define BLIT_COLOR(dst, src, msk) \
(dst) &= (msk);\ (dst) &= (msk); \
(dst) |= ~(msk) & image_color; (dst) |= ~(msk)&image_color;
#define BLIT(blit_loop)\ #define BLIT(blit_loop) \
switch (image_blendMode) {\ switch (image_blendMode) { \
default:\ default: \
case IMAGE_NORMAL : blit_loop(BLIT_NORMAL) break;\ case IMAGE_NORMAL: \
case IMAGE_AND : blit_loop(BLIT_AND) break;\ blit_loop(BLIT_NORMAL) break; \
case IMAGE_OR : blit_loop(BLIT_OR) break;\ case IMAGE_AND: \
case IMAGE_COLOR : blit_loop(BLIT_COLOR) break;\ blit_loop(BLIT_AND) break; \
}\ case IMAGE_OR: \
blit_loop(BLIT_OR) break; \
case IMAGE_COLOR: \
blit_loop(BLIT_COLOR) break; \
}
if (!image_flip) { if (!image_flip) {
if (image_blendMode == IMAGE_FAST) { if (image_blendMode == IMAGE_FAST) {
@@ -223,10 +240,8 @@ void image_blit(image_t *self, pixel_t *buf, int bufw, int bufh,
} else { } else {
BLIT(BLIT_LOOP_FLIPPED); BLIT(BLIT_LOOP_FLIPPED);
} }
} }
void image_deinit(image_t *self) { void image_deinit(image_t *self) {
dmt_free(self->data); dmt_free(self->data);
dmt_free(self->mask); dmt_free(self->mask);

View File

@@ -11,8 +11,7 @@
#include "vga.h" #include "vga.h"
#include "luaobj.h" #include "luaobj.h"
typedef enum {
enum {
IMAGE_NORMAL, IMAGE_NORMAL,
IMAGE_FAST, IMAGE_FAST,
IMAGE_AND, IMAGE_AND,
@@ -20,23 +19,20 @@ enum {
IMAGE_COLOR, IMAGE_COLOR,
} IMAGE_BLEND_MODE; } IMAGE_BLEND_MODE;
typedef struct { typedef struct {
pixel_t *data; pixel_t *data;
pixel_t *mask; pixel_t *mask;
int width, height; int width, height;
} image_t; } image_t;
static inline void image_setPixel(image_t *self, int x, int y, pixel_t val) {
static inline
void image_setPixel(image_t* self, int x, int y, pixel_t val) {
if (x >= 0 && x < self->width && y >= 0 && y < self->height) { if (x >= 0 && x < self->width && y >= 0 && y < self->height) {
self->data[x + y * self->width] = val; self->data[x + y * self->width] = val;
} }
} }
static inline static inline void image_setMaskPixel(image_t *self, int x, int y,
void image_setMaskPixel(image_t* self, int x, int y, pixel_t val) { pixel_t val) {
if (x >= 0 && x < self->width && y >= 0 && y < self->height) { if (x >= 0 && x < self->width && y >= 0 && y < self->height) {
self->mask[x + y * self->width] = val; self->mask[x + y * self->width] = val;
} }
@@ -47,9 +43,9 @@ void image_setBlendMode(int mode);
void image_setFlip(int mode); void image_setFlip(int mode);
const char *image_init(image_t *self, const char *filename); const char *image_init(image_t *self, const char *filename);
void image_initBlank(image_t*, int, int); void image_initBlank(image_t *, int, int);
void image_blit(image_t *self, pixel_t *buf, int bufw, int bufh, void image_blit(image_t *self, pixel_t *buf, int bufw, int bufh, int dx, int dy,
int dx, int dy, int sx, int sy, int sw, int sh); int sx, int sy, int sw, int sh);
void image_deinit(image_t*); void image_deinit(image_t *);
#endif #endif

View File

@@ -19,143 +19,48 @@
#define BUFFER_MASK (BUFFER_SIZE - 1) #define BUFFER_MASK (BUFFER_SIZE - 1)
static const char *scancodeMap[] = { static const char *scancodeMap[] = {
[ 0] = "?", [0] = "?", [1] = "escape", [2] = "1", [3] = "2",
[ 1] = "escape", [4] = "3", [5] = "4", [6] = "5", [7] = "6",
[ 2] = "1", [8] = "7", [9] = "8", [10] = "9", [11] = "0",
[ 3] = "2", [12] = "-", [13] = "=", [14] = "backspace", [15] = "tab",
[ 4] = "3", [16] = "q", [17] = "w", [18] = "e", [19] = "r",
[ 5] = "4", [20] = "t", [21] = "y", [22] = "u", [23] = "i",
[ 6] = "5", [24] = "o", [25] = "p", [26] = "[", [27] = "]",
[ 7] = "6", [28] = "return", [29] = "lctrl", [30] = "a", [31] = "s",
[ 8] = "7", [32] = "d", [33] = "f", [34] = "g", [35] = "h",
[ 9] = "8", [36] = "j", [37] = "k", [38] = "l", [39] = ";",
[ 10] = "9", [40] = "\"", [41] = "`", [42] = "lshift", [43] = "\\",
[ 11] = "0", [44] = "z", [45] = "x", [46] = "c", [47] = "v",
[ 12] = "-", [48] = "b", [49] = "n", [50] = "m", [51] = ",",
[ 13] = "=", [52] = ".", [53] = "/", [54] = "rshift", [55] = "*",
[ 14] = "backspace", [56] = "lalt", [57] = "space", [58] = "capslock", [59] = "f1",
[ 15] = "tab", [60] = "f2", [61] = "f3", [62] = "f4", [63] = "f5",
[ 16] = "q", [64] = "f6", [65] = "f7", [66] = "f8", [67] = "f9",
[ 17] = "w", [68] = "f10", [69] = "numlock", [70] = "scrolllock", [71] = "home",
[ 18] = "e", [72] = "up", [73] = "pageup", [74] = "-", [75] = "left",
[ 19] = "r", [76] = "5", [77] = "right", [78] = "+", [79] = "end",
[ 20] = "t", [80] = "down", [81] = "pagedown", [82] = "insert", [83] = "delete",
[ 21] = "y", [84] = "?", [85] = "?", [86] = "?", [87] = "?",
[ 22] = "u", [88] = "f12", [89] = "?", [90] = "?", [91] = "?",
[ 23] = "i", [92] = "?", [93] = "?", [94] = "?", [95] = "?",
[ 24] = "o", [96] = "enter", [97] = "lctrl", [98] = "/", [99] = "f12",
[ 25] = "p", [100] = "rctrl", [101] = "pause", [102] = "home", [103] = "up",
[ 26] = "[", [104] = "pageup", [105] = "left", [106] = "right", [107] = "end",
[ 27] = "]", [108] = "down", [109] = "pagedown", [110] = "insert", [111] = "?",
[ 28] = "return", [112] = "?", [113] = "?", [114] = "?", [115] = "?",
[ 29] = "lctrl", [116] = "?", [117] = "?", [118] = "?", [119] = "pause",
[ 30] = "a", [120] = "?", [121] = "?", [122] = "?", [123] = "?",
[ 31] = "s", [124] = "?", [125] = "?", [126] = "?", [127] = "?",
[ 32] = "d", [128] = NULL,
[ 33] = "f",
[ 34] = "g",
[ 35] = "h",
[ 36] = "j",
[ 37] = "k",
[ 38] = "l",
[ 39] = ";",
[ 40] = "\"",
[ 41] = "`",
[ 42] = "lshift",
[ 43] = "\\",
[ 44] = "z",
[ 45] = "x",
[ 46] = "c",
[ 47] = "v",
[ 48] = "b",
[ 49] = "n",
[ 50] = "m",
[ 51] = ",",
[ 52] = ".",
[ 53] = "/",
[ 54] = "rshift",
[ 55] = "*",
[ 56] = "lalt",
[ 57] = "space",
[ 58] = "capslock",
[ 59] = "f1",
[ 60] = "f2",
[ 61] = "f3",
[ 62] = "f4",
[ 63] = "f5",
[ 64] = "f6",
[ 65] = "f7",
[ 66] = "f8",
[ 67] = "f9",
[ 68] = "f10",
[ 69] = "numlock",
[ 70] = "scrolllock",
[ 71] = "home",
[ 72] = "up",
[ 73] = "pageup",
[ 74] = "-",
[ 75] = "left",
[ 76] = "5",
[ 77] = "right",
[ 78] = "+",
[ 79] = "end",
[ 80] = "down",
[ 81] = "pagedown",
[ 82] = "insert",
[ 83] = "delete",
[ 84] = "?",
[ 85] = "?",
[ 86] = "?",
[ 87] = "?",
[ 88] = "f12",
[ 89] = "?",
[ 90] = "?",
[ 91] = "?",
[ 92] = "?",
[ 93] = "?",
[ 94] = "?",
[ 95] = "?",
[ 96] = "enter",
[ 97] = "lctrl",
[ 98] = "/",
[ 99] = "f12",
[100] = "rctrl",
[101] = "pause",
[102] = "home",
[103] = "up",
[104] = "pageup",
[105] = "left",
[106] = "right",
[107] = "end",
[108] = "down",
[109] = "pagedown",
[110] = "insert",
[111] = "?",
[112] = "?",
[113] = "?",
[114] = "?",
[115] = "?",
[116] = "?",
[117] = "?",
[118] = "?",
[119] = "pause",
[120] = "?",
[121] = "?",
[122] = "?",
[123] = "?",
[124] = "?",
[125] = "?",
[126] = "?",
[127] = "?",
[128] = NULL,
}; };
volatile int keyboard_allowKeyRepeat = 0; volatile int keyboard_allowKeyRepeat = 0;
volatile char keyboard_keyStates[KEY_MAX]; volatile char keyboard_keyStates[KEY_MAX];
enum { KEYPRESSED, KEYRELEASED }; enum { KEYPRESSED, KEYRELEASED };
typedef struct { unsigned char type, code, isrepeat; } key_event_t; typedef struct {
unsigned char type, code, isrepeat;
} key_event_t;
volatile struct { volatile struct {
key_event_t data[32]; key_event_t data[32];
@@ -164,7 +69,6 @@ volatile struct {
_go32_dpmi_seginfo old_keyb_handler_seginfo, new_keyb_handler_seginfo; _go32_dpmi_seginfo old_keyb_handler_seginfo, new_keyb_handler_seginfo;
void keyboard_handler() { void keyboard_handler() {
static unsigned char code; static unsigned char code;
code = inportb(0x60); code = inportb(0x60);
@@ -199,31 +103,25 @@ void keyboard_handler() {
outportb(0x20, 0x20); outportb(0x20, 0x20);
} }
void keyboard_handler_end() {} void keyboard_handler_end() {}
int keyboard_init(void) { int keyboard_init(void) {
_go32_dpmi_lock_data((char*)&keyboard_keyStates, KEY_MAX); _go32_dpmi_lock_data((char *)&keyboard_keyStates, KEY_MAX);
_go32_dpmi_lock_data((char*)&keyboard_events, sizeof(keyboard_events)); _go32_dpmi_lock_data((char *)&keyboard_events, sizeof(keyboard_events));
_go32_dpmi_lock_code(keyboard_handler,(unsigned long)keyboard_handler_end - _go32_dpmi_lock_code(keyboard_handler, (unsigned long)keyboard_handler_end -
(unsigned long)keyboard_handler); (unsigned long)keyboard_handler);
_go32_dpmi_get_protected_mode_interrupt_vector(9, &old_keyb_handler_seginfo); _go32_dpmi_get_protected_mode_interrupt_vector(9, &old_keyb_handler_seginfo);
new_keyb_handler_seginfo.pm_offset = (int)keyboard_handler; new_keyb_handler_seginfo.pm_offset = (int)keyboard_handler;
_go32_dpmi_chain_protected_mode_interrupt_vector(9, &new_keyb_handler_seginfo); _go32_dpmi_chain_protected_mode_interrupt_vector(9,
&new_keyb_handler_seginfo);
return 0; return 0;
} }
void keyboard_deinit(void) { void keyboard_deinit(void) {
_go32_dpmi_set_protected_mode_interrupt_vector(9, &old_keyb_handler_seginfo); _go32_dpmi_set_protected_mode_interrupt_vector(9, &old_keyb_handler_seginfo);
} }
void keyboard_setKeyRepeat(int allow) { keyboard_allowKeyRepeat = allow; }
void keyboard_setKeyRepeat(int allow) {
keyboard_allowKeyRepeat = allow;
}
int keyboard_isDown(const char *key) { int keyboard_isDown(const char *key) {
int i; int i;
@@ -235,11 +133,11 @@ int keyboard_isDown(const char *key) {
return 0; return 0;
} }
void keyboard_update(void) { void keyboard_update(void) {
/* Handle key press / release */ /* Handle key press / release */
while (keyboard_events.readi != keyboard_events.writei) { while (keyboard_events.readi != keyboard_events.writei) {
key_event_t ke = keyboard_events.data[keyboard_events.readi++ & BUFFER_MASK]; key_event_t ke =
keyboard_events.data[keyboard_events.readi++ & BUFFER_MASK];
event_t e; event_t e;
if (ke.type == KEYPRESSED) { if (ke.type == KEYPRESSED) {
e.type = EVENT_KEYBOARD_PRESSED; e.type = EVENT_KEYBOARD_PRESSED;
@@ -254,7 +152,7 @@ void keyboard_update(void) {
/* Handle text input */ /* Handle text input */
char buf[64]; char buf[64];
int i = 0; int i = 0;
while ( kbhit() ) { while (kbhit()) {
int chr = getch(); int chr = getch();
if (chr == 0) { /* Discard "special" keys */ if (chr == 0) { /* Discard "special" keys */
getch(); getch();

View File

@@ -11,10 +11,8 @@
#include "luaobj.h" #include "luaobj.h"
int luaobj_newclass(lua_State *L, const char *name, const char *extends, int luaobj_newclass(lua_State *L, const char *name, const char *extends,
int (*constructor)(lua_State*), luaL_Reg* reg int (*constructor)(lua_State *), luaL_Reg *reg) {
) {
/* Creates and pushes a new metatable which represents a class containing the /* Creates and pushes a new metatable which represents a class containing the
* functions in the `reg` argument. If the `extends` argument is not NULL * functions in the `reg` argument. If the `extends` argument is not NULL
* this class will use the specified class as a super class */ * this class will use the specified class as a super class */
@@ -35,7 +33,7 @@ int luaobj_newclass(lua_State *L, const char *name, const char *extends,
if (extends) { if (extends) {
luaL_getmetatable(L, extends); luaL_getmetatable(L, extends);
/* Pull metatable functions from base class */ /* Pull metatable functions from base class */
char *mtfields[] = { "__gc", "__tostring", NULL }; char *mtfields[] = {"__gc", "__tostring", NULL};
int i; int i;
for (i = 0; mtfields[i]; i++) { for (i = 0; mtfields[i]; i++) {
lua_getfield(L, -1, mtfields[i]); lua_getfield(L, -1, mtfields[i]);
@@ -43,9 +41,9 @@ int luaobj_newclass(lua_State *L, const char *name, const char *extends,
} }
lua_setmetatable(L, -2); lua_setmetatable(L, -2);
} }
lua_pop(L, 1); /* Pop func table */ lua_pop(L, 1); /* Pop func table */
luaL_setfuncs(L, reg, 0); /* Set metatable's funcs */ luaL_setfuncs(L, reg, 0); /* Set metatable's funcs */
lua_pop(L, 1); /* Pop metatable */ lua_pop(L, 1); /* Pop metatable */
/* Return constructor */ /* Return constructor */
lua_pushcfunction(L, constructor); lua_pushcfunction(L, constructor);
@@ -53,7 +51,6 @@ int luaobj_newclass(lua_State *L, const char *name, const char *extends,
return 1; return 1;
} }
void luaobj_setclass(lua_State *L, uint32_t type, char *name) { void luaobj_setclass(lua_State *L, uint32_t type, char *name) {
/* Sets the the metatable of the member at the top of the stack to the /* Sets the the metatable of the member at the top of the stack to the
* class-metatable of the given `name` */ * class-metatable of the given `name` */
@@ -61,13 +58,12 @@ void luaobj_setclass(lua_State *L, uint32_t type, char *name) {
udata->type = type; udata->type = type;
luaL_getmetatable(L, name); luaL_getmetatable(L, name);
if (lua_isnil(L, -1)) { if (lua_isnil(L, -1)) {
luaL_error( luaL_error(L, "missing metatable: assure class '%s' is inited in love.c\n",
L, "missing metatable: assure class '%s' is inited in love.c\n", name); name);
} }
lua_setmetatable(L, -2); lua_setmetatable(L, -2);
} }
void *luaobj_newudata(lua_State *L, int size) { void *luaobj_newudata(lua_State *L, int size) {
/* Creates a udata of the requested size, plus space for the luaobj_head_t /* Creates a udata of the requested size, plus space for the luaobj_head_t
* header. Returns the pointer to the udata's body */ * header. Returns the pointer to the udata's body */
@@ -77,7 +73,6 @@ void *luaobj_newudata(lua_State *L, int size) {
return udata + 1; return udata + 1;
} }
void *luaobj_checkudata(lua_State *L, int index, uint32_t type) { void *luaobj_checkudata(lua_State *L, int index, uint32_t type) {
/* Checks the header of a luaobj udata at the given index, taking into /* Checks the header of a luaobj udata at the given index, taking into
* account super-classes it may have extended. Returns the udata's body if * account super-classes it may have extended. Returns the udata's body if
@@ -89,4 +84,3 @@ void *luaobj_checkudata(lua_State *L, int index, uint32_t type) {
} }
return udata + 1; return udata + 1;
} }

View File

@@ -14,25 +14,21 @@
#include "lib/lua/lualib.h" #include "lib/lua/lualib.h"
#include "lib/lua/lauxlib.h" #include "lib/lua/lauxlib.h"
typedef struct { typedef struct {
uint32_t type; uint32_t type;
} luaobj_head_t; } luaobj_head_t;
/* Each mask should consist of its unique bit and the unique bit of all its /* Each mask should consist of its unique bit and the unique bit of all its
* super classes */ * super classes */
#define LUAOBJ_TYPE_IMAGE (1 << 0) #define LUAOBJ_TYPE_IMAGE (1 << 0)
#define LUAOBJ_TYPE_QUAD (1 << 1) #define LUAOBJ_TYPE_QUAD (1 << 1)
#define LUAOBJ_TYPE_FONT (1 << 2) #define LUAOBJ_TYPE_FONT (1 << 2)
#define LUAOBJ_TYPE_SOURCE (1 << 3) #define LUAOBJ_TYPE_SOURCE (1 << 3)
int luaobj_newclass(lua_State *L, const char *name, const char *extends, int luaobj_newclass(lua_State *L, const char *name, const char *extends,
int (*constructor)(lua_State*), luaL_Reg* reg); int (*constructor)(lua_State *), luaL_Reg *reg);
void luaobj_setclass(lua_State *L, uint32_t type, char *name); void luaobj_setclass(lua_State *L, uint32_t type, char *name);
void *luaobj_newudata(lua_State *L, int size); void *luaobj_newudata(lua_State *L, int size);
void *luaobj_checkudata(lua_State *L, int index, uint32_t type); void *luaobj_checkudata(lua_State *L, int index, uint32_t type);
#endif #endif

View File

@@ -23,7 +23,6 @@
#include "palette.h" #include "palette.h"
#include "package.h" #include "package.h"
static lua_State *L; static lua_State *L;
static void deinit(void) { static void deinit(void) {
@@ -33,12 +32,11 @@ static void deinit(void) {
keyboard_deinit(); keyboard_deinit();
lua_close(L); lua_close(L);
filesystem_deinit(); filesystem_deinit();
if ( dmt_usage() > 0 ) { if (dmt_usage() > 0) {
dmt_dump(stdout); dmt_dump(stdout);
} }
} }
static int onLuaPanic(lua_State *L) { static int onLuaPanic(lua_State *L) {
vga_deinit(); vga_deinit();
const char *err = lua_tostring(L, -1); const char *err = lua_tostring(L, -1);
@@ -46,13 +44,12 @@ static int onLuaPanic(lua_State *L) {
return 0; return 0;
} }
int luaopen_love(lua_State *L); int luaopen_love(lua_State *L);
int main(int argc, char **argv) { int main(int argc, char **argv) {
/* Handle package command */ /* Handle package command */
if ( package_run(argc, argv) == PACKAGE_ESUCCESS ) { if (package_run(argc, argv) == PACKAGE_ESUCCESS) {
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
@@ -83,16 +80,15 @@ int main(int argc, char **argv) {
} }
lua_pop(L, 1); lua_pop(L, 1);
/* Init embedded scripts */ /* Init embedded scripts */
#include "nogame_lua.h" #include "nogame_lua.h"
#include "boot_lua.h" #include "boot_lua.h"
struct { struct {
const char *name, *data; int size; const char *name, *data;
} items[] = { int size;
{ "nogame.lua", nogame_lua, sizeof(nogame_lua) }, } items[] = {{"nogame.lua", nogame_lua, sizeof(nogame_lua)},
{ "boot.lua", boot_lua, sizeof(boot_lua) }, {"boot.lua", boot_lua, sizeof(boot_lua)},
{ NULL, NULL, 0 } {NULL, NULL, 0}};
};
int i; int i;
for (i = 0; items[i].name; i++) { for (i = 0; items[i].name; i++) {
int err = luaL_loadbuffer(L, items[i].data, items[i].size, items[i].name); int err = luaL_loadbuffer(L, items[i].data, items[i].size, items[i].name);

View File

@@ -5,9 +5,8 @@
* under the terms of the MIT license. See LICENSE for details. * under the terms of the MIT license. See LICENSE for details.
*/ */
#include "lib/cmixer/cmixer.h" #include "lib/cmixer/cmixer.h"
#include "luaobj.h" #include "luaobj.h"
int l_audio_setVolume(lua_State *L) { int l_audio_setVolume(lua_State *L) {
double n = luaL_checknumber(L, 1); double n = luaL_checknumber(L, 1);
@@ -15,14 +14,13 @@ int l_audio_setVolume(lua_State *L) {
return 0; return 0;
} }
int l_source_new(lua_State *L); int l_source_new(lua_State *L);
int luaopen_audio(lua_State *L) { int luaopen_audio(lua_State *L) {
luaL_Reg reg[] = { luaL_Reg reg[] = {
{ "newSource", l_source_new }, {"newSource", l_source_new},
{ "setVolume", l_audio_setVolume }, {"setVolume", l_audio_setVolume},
{ 0, 0 }, {0, 0},
}; };
luaL_newlib(L, reg); luaL_newlib(L, reg);
return 1; return 1;

View File

@@ -8,47 +8,45 @@
#include "luaobj.h" #include "luaobj.h"
#include "event.h" #include "event.h"
int l_event_pump(lua_State *L) { int l_event_pump(lua_State *L) {
event_pump(); event_pump();
return 0; return 0;
} }
int l_event_poll(lua_State *L) { int l_event_poll(lua_State *L) {
event_t e; event_t e;
if (event_poll(&e)) { if (event_poll(&e)) {
lua_pushstring(L, event_typestr(e.type)); lua_pushstring(L, event_typestr(e.type));
switch(e.type) { switch (e.type) {
case EVENT_QUIT: case EVENT_QUIT:
lua_pushnumber(L, e.quit.status); lua_pushnumber(L, e.quit.status);
return 2; return 2;
case EVENT_KEYBOARD_PRESSED: case EVENT_KEYBOARD_PRESSED:
case EVENT_KEYBOARD_RELEASED: case EVENT_KEYBOARD_RELEASED:
lua_pushstring(L, e.keyboard.key); lua_pushstring(L, e.keyboard.key);
lua_pushstring(L, e.keyboard.key); lua_pushstring(L, e.keyboard.key);
lua_pushboolean(L, e.keyboard.isrepeat); lua_pushboolean(L, e.keyboard.isrepeat);
return 4; return 4;
case EVENT_KEYBOARD_TEXTINPUT: case EVENT_KEYBOARD_TEXTINPUT:
lua_pushstring(L, e.keyboard.text); lua_pushstring(L, e.keyboard.text);
return 2; return 2;
case EVENT_MOUSE_MOVED: case EVENT_MOUSE_MOVED:
lua_pushnumber(L, e.mouse.x); lua_pushnumber(L, e.mouse.x);
lua_pushnumber(L, e.mouse.y); lua_pushnumber(L, e.mouse.y);
lua_pushnumber(L, e.mouse.dx); lua_pushnumber(L, e.mouse.dx);
lua_pushnumber(L, e.mouse.dy); lua_pushnumber(L, e.mouse.dy);
return 5; return 5;
case EVENT_MOUSE_PRESSED: case EVENT_MOUSE_PRESSED:
case EVENT_MOUSE_RELEASED: case EVENT_MOUSE_RELEASED:
lua_pushnumber(L, e.mouse.x); lua_pushnumber(L, e.mouse.x);
lua_pushnumber(L, e.mouse.y); lua_pushnumber(L, e.mouse.y);
lua_pushnumber(L, e.mouse.button); lua_pushnumber(L, e.mouse.button);
return 4; return 4;
} }
return 1; return 1;
@@ -57,7 +55,6 @@ int l_event_poll(lua_State *L) {
return 0; return 0;
} }
int l_event_quit(lua_State *L) { int l_event_quit(lua_State *L) {
int status = luaL_optnumber(L, 1, 0); int status = luaL_optnumber(L, 1, 0);
event_t e; event_t e;
@@ -67,14 +64,12 @@ int l_event_quit(lua_State *L) {
return 0; return 0;
} }
int luaopen_event(lua_State *L) { int luaopen_event(lua_State *L) {
luaL_Reg reg[] = { luaL_Reg reg[] = {
{ "pump", l_event_pump }, {"pump", l_event_pump},
{ "poll", l_event_poll }, {"poll", l_event_poll},
{ "quit", l_event_quit }, {"quit", l_event_quit},
{ 0, 0 }, {0, 0},
}; };
luaL_newlib(L, reg); luaL_newlib(L, reg);
return 1; return 1;

View File

@@ -8,7 +8,6 @@
#include "filesystem.h" #include "filesystem.h"
#include "luaobj.h" #include "luaobj.h"
int l_filesystem_mount(lua_State *L) { int l_filesystem_mount(lua_State *L) {
const char *path = luaL_checkstring(L, 1); const char *path = luaL_checkstring(L, 1);
int err = filesystem_mount(path); int err = filesystem_mount(path);
@@ -21,7 +20,6 @@ int l_filesystem_mount(lua_State *L) {
return 1; return 1;
} }
int l_filesystem_unmount(lua_State *L) { int l_filesystem_unmount(lua_State *L) {
const char *path = luaL_checkstring(L, 1); const char *path = luaL_checkstring(L, 1);
int err = filesystem_unmount(path); int err = filesystem_unmount(path);
@@ -34,28 +32,24 @@ int l_filesystem_unmount(lua_State *L) {
return 1; return 1;
} }
int l_filesystem_exists(lua_State *L) { int l_filesystem_exists(lua_State *L) {
const char *filename = luaL_checkstring(L, 1); const char *filename = luaL_checkstring(L, 1);
lua_pushboolean( L, filesystem_exists(filename) ); lua_pushboolean(L, filesystem_exists(filename));
return 1; return 1;
} }
int l_filesystem_isFile(lua_State *L) { int l_filesystem_isFile(lua_State *L) {
const char *filename = luaL_checkstring(L, 1); const char *filename = luaL_checkstring(L, 1);
lua_pushboolean( L, filesystem_isFile(filename) ); lua_pushboolean(L, filesystem_isFile(filename));
return 1; return 1;
} }
int l_filesystem_isDirectory(lua_State *L) { int l_filesystem_isDirectory(lua_State *L) {
const char *filename = luaL_checkstring(L, 1); const char *filename = luaL_checkstring(L, 1);
lua_pushboolean( L, filesystem_isDirectory(filename) ); lua_pushboolean(L, filesystem_isDirectory(filename));
return 1; return 1;
} }
int l_filesystem_read(lua_State *L) { int l_filesystem_read(lua_State *L) {
const char *filename = luaL_checkstring(L, 1); const char *filename = luaL_checkstring(L, 1);
int size; int size;
@@ -68,7 +62,6 @@ int l_filesystem_read(lua_State *L) {
return 1; return 1;
} }
int l_filesystem_setWriteDir(lua_State *L) { int l_filesystem_setWriteDir(lua_State *L) {
const char *path = luaL_checkstring(L, 1); const char *path = luaL_checkstring(L, 1);
int err = filesystem_setWriteDir(path); int err = filesystem_setWriteDir(path);
@@ -81,7 +74,6 @@ int l_filesystem_setWriteDir(lua_State *L) {
return 1; return 1;
} }
int l_filesystem_write(lua_State *L) { int l_filesystem_write(lua_State *L) {
size_t sz; size_t sz;
const char *filename = luaL_checkstring(L, 1); const char *filename = luaL_checkstring(L, 1);
@@ -94,18 +86,17 @@ int l_filesystem_write(lua_State *L) {
return 1; return 1;
} }
int luaopen_filesystem(lua_State *L) { int luaopen_filesystem(lua_State *L) {
luaL_Reg reg[] = { luaL_Reg reg[] = {
{ "mount", l_filesystem_mount }, {"mount", l_filesystem_mount},
{ "unmount", l_filesystem_unmount }, {"unmount", l_filesystem_unmount},
{ "exists", l_filesystem_exists }, {"exists", l_filesystem_exists},
{ "isFile", l_filesystem_isFile }, {"isFile", l_filesystem_isFile},
{ "isDirectory", l_filesystem_isDirectory }, {"isDirectory", l_filesystem_isDirectory},
{ "read", l_filesystem_read }, {"read", l_filesystem_read},
{ "setWriteDir", l_filesystem_setWriteDir }, {"setWriteDir", l_filesystem_setWriteDir},
{ "write", l_filesystem_write }, {"write", l_filesystem_write},
{ 0, 0 }, {0, 0},
}; };
luaL_newlib(L, reg); luaL_newlib(L, reg);
return 1; return 1;

View File

@@ -8,14 +8,13 @@
#include "font.h" #include "font.h"
#include "luaobj.h" #include "luaobj.h"
#define CLASS_TYPE LUAOBJ_TYPE_FONT #define CLASS_TYPE LUAOBJ_TYPE_FONT
#define CLASS_NAME "Font" #define CLASS_NAME "Font"
int l_font_new(lua_State *L) { int l_font_new(lua_State *L) {
const char *filename; const char *filename;
int ptsize = 8; int ptsize = 8;
if ( lua_isnoneornil(L, 2) ) { if (lua_isnoneornil(L, 2)) {
filename = NULL; filename = NULL;
ptsize = luaL_optnumber(L, 1, ptsize); ptsize = luaL_optnumber(L, 1, ptsize);
} else { } else {
@@ -26,48 +25,44 @@ int l_font_new(lua_State *L) {
luaobj_setclass(L, CLASS_TYPE, CLASS_NAME); luaobj_setclass(L, CLASS_TYPE, CLASS_NAME);
if (filename) { if (filename) {
const char *err = font_init(self, filename, ptsize); const char *err = font_init(self, filename, ptsize);
if (err) luaL_error(L, err); if (err)
luaL_error(L, err);
} else { } else {
font_initEmbedded(self, ptsize); font_initEmbedded(self, ptsize);
} }
return 1; return 1;
} }
int l_font_gc(lua_State *L) { int l_font_gc(lua_State *L) {
font_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); font_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
font_deinit(self); font_deinit(self);
return 0; return 0;
} }
int l_font_getWidth(lua_State *L) { int l_font_getWidth(lua_State *L) {
font_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); font_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
const char *p = luaL_checkstring(L, 2); const char *p = luaL_checkstring(L, 2);
int width = 0; int width = 0;
while (*p) { while (*p) {
width += self->glyphs[(int) (*p++ & 127)].xadvance; width += self->glyphs[(int)(*p++ & 127)].xadvance;
} }
lua_pushinteger(L, width); lua_pushinteger(L, width);
return 1; return 1;
} }
int l_font_getHeight(lua_State *L) { int l_font_getHeight(lua_State *L) {
font_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); font_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
lua_pushinteger(L, self->height); lua_pushinteger(L, self->height);
return 1; return 1;
} }
int luaopen_font(lua_State *L) { int luaopen_font(lua_State *L) {
luaL_Reg reg[] = { luaL_Reg reg[] = {
{ "new", l_font_new }, {"new", l_font_new},
{ "__gc", l_font_gc }, {"__gc", l_font_gc},
{ "getWidth", l_font_getWidth }, {"getWidth", l_font_getWidth},
{ "getHeight", l_font_getHeight }, {"getHeight", l_font_getHeight},
{ 0, 0 }, {0, 0},
}; };
luaobj_newclass(L, CLASS_NAME, NULL, l_font_new, reg); luaobj_newclass(L, CLASS_NAME, NULL, l_font_new, reg);
return 1; return 1;

View File

@@ -15,21 +15,20 @@
#include "vga.h" #include "vga.h"
#include "luaobj.h" #include "luaobj.h"
image_t *graphics_screen; image_t *graphics_screen;
font_t *graphics_defaultFont; font_t *graphics_defaultFont;
image_t *graphics_canvas;
font_t *graphics_font;
pixel_t graphics_backgroundColor;
int graphics_backgroundColor_rgb[3];
pixel_t graphics_color;
int graphics_color_rgb[3];
int graphics_blendMode;
image_t *graphics_canvas;
font_t *graphics_font;
pixel_t graphics_backgroundColor;
int graphics_backgroundColor_rgb[3];
pixel_t graphics_color;
int graphics_color_rgb[3];
int graphics_blendMode;
static int getColorFromArgs(lua_State *L, int *rgb, const int *def) { static int getColorFromArgs(lua_State *L, int *rgb, const int *def) {
int r, g, b; int r, g, b;
if ( lua_isnoneornil(L, 1) ) { if (lua_isnoneornil(L, 1)) {
r = def[0]; r = def[0];
g = def[1]; g = def[1];
b = def[2]; b = def[2];
@@ -50,7 +49,6 @@ static int getColorFromArgs(lua_State *L, int *rgb, const int *def) {
return idx; return idx;
} }
static int pushColor(lua_State *L, int *rgb) { static int pushColor(lua_State *L, int *rgb) {
lua_pushinteger(L, rgb[0]); lua_pushinteger(L, rgb[0]);
lua_pushinteger(L, rgb[1]); lua_pushinteger(L, rgb[1]);
@@ -58,96 +56,105 @@ static int pushColor(lua_State *L, int *rgb) {
return 3; return 3;
} }
int l_graphics_getDimensions(lua_State *L) { int l_graphics_getDimensions(lua_State *L) {
lua_pushinteger(L, graphics_screen->width); lua_pushinteger(L, graphics_screen->width);
lua_pushinteger(L, graphics_screen->height); lua_pushinteger(L, graphics_screen->height);
return 2; return 2;
} }
int l_graphics_getWidth(lua_State *L) { int l_graphics_getWidth(lua_State *L) {
lua_pushinteger(L, graphics_screen->width); lua_pushinteger(L, graphics_screen->width);
return 1; return 1;
} }
int l_graphics_getHeight(lua_State *L) { int l_graphics_getHeight(lua_State *L) {
lua_pushinteger(L, graphics_screen->height); lua_pushinteger(L, graphics_screen->height);
return 1; return 1;
} }
int l_graphics_getBackgroundColor(lua_State *L) { int l_graphics_getBackgroundColor(lua_State *L) {
return pushColor(L, graphics_backgroundColor_rgb); return pushColor(L, graphics_backgroundColor_rgb);
} }
int l_graphics_setBackgroundColor(lua_State *L) { int l_graphics_setBackgroundColor(lua_State *L) {
static const int def[] = { 0, 0, 0 }; static const int def[] = {0, 0, 0};
int idx = getColorFromArgs(L, graphics_backgroundColor_rgb, def); int idx = getColorFromArgs(L, graphics_backgroundColor_rgb, def);
graphics_backgroundColor = idx; graphics_backgroundColor = idx;
return 0; return 0;
} }
int l_graphics_getColor(lua_State *L) { int l_graphics_getColor(lua_State *L) {
return pushColor(L, graphics_color_rgb); return pushColor(L, graphics_color_rgb);
} }
int l_graphics_setColor(lua_State *L) { int l_graphics_setColor(lua_State *L) {
static const int def[] = { 0xff, 0xff, 0xff }; static const int def[] = {0xff, 0xff, 0xff};
graphics_color = getColorFromArgs(L, graphics_color_rgb, def); graphics_color = getColorFromArgs(L, graphics_color_rgb, def);
image_setColor(graphics_color); image_setColor(graphics_color);
return 0; return 0;
} }
int l_graphics_getBlendMode(lua_State *L) { int l_graphics_getBlendMode(lua_State *L) {
switch (graphics_blendMode) { switch (graphics_blendMode) {
default: default:
case IMAGE_NORMAL : lua_pushstring(L, "normal"); break; case IMAGE_NORMAL:
case IMAGE_FAST : lua_pushstring(L, "fast"); break; lua_pushstring(L, "normal");
case IMAGE_AND : lua_pushstring(L, "and"); break; break;
case IMAGE_OR : lua_pushstring(L, "or"); break; case IMAGE_FAST:
case IMAGE_COLOR : lua_pushstring(L, "color"); break; lua_pushstring(L, "fast");
break;
case IMAGE_AND:
lua_pushstring(L, "and");
break;
case IMAGE_OR:
lua_pushstring(L, "or");
break;
case IMAGE_COLOR:
lua_pushstring(L, "color");
break;
} }
return 1; return 1;
} }
int l_graphics_setBlendMode(lua_State *L) { int l_graphics_setBlendMode(lua_State *L) {
const char *str = lua_isnoneornil(L, 1) ? "normal" : luaL_checkstring(L, 1); const char *str = lua_isnoneornil(L, 1) ? "normal" : luaL_checkstring(L, 1);
#define SET_BLEND_MODE(str, e)\ #define SET_BLEND_MODE(str, e) \
do {\ do { \
if (!strcmp(str, str)) {\ if (!strcmp(str, str)) { \
graphics_blendMode = e;\ graphics_blendMode = e; \
image_setBlendMode(graphics_blendMode);\ image_setBlendMode(graphics_blendMode); \
return 0;\ return 0; \
}\ } \
} while (0) } while (0)
switch (*str) { switch (*str) {
case 'n' : SET_BLEND_MODE("normal", IMAGE_NORMAL); break; case 'n':
case 'f' : SET_BLEND_MODE("fast", IMAGE_FAST); break; SET_BLEND_MODE("normal", IMAGE_NORMAL);
case 'a' : SET_BLEND_MODE("and", IMAGE_AND); break; break;
case 'o' : SET_BLEND_MODE("or", IMAGE_OR); break; case 'f':
case 'c' : SET_BLEND_MODE("color", IMAGE_COLOR); break; SET_BLEND_MODE("fast", IMAGE_FAST);
break;
case 'a':
SET_BLEND_MODE("and", IMAGE_AND);
break;
case 'o':
SET_BLEND_MODE("or", IMAGE_OR);
break;
case 'c':
SET_BLEND_MODE("color", IMAGE_COLOR);
break;
} }
#undef SET_BLEND_MODE #undef SET_BLEND_MODE
luaL_argerror(L, 1, "bad blend mode"); luaL_argerror(L, 1, "bad blend mode");
return 0; return 0;
} }
int l_graphics_getFont(lua_State *L) { int l_graphics_getFont(lua_State *L) {
lua_pushlightuserdata(L, graphics_font); lua_pushlightuserdata(L, graphics_font);
lua_gettable(L, LUA_REGISTRYINDEX); lua_gettable(L, LUA_REGISTRYINDEX);
return 1; return 1;
} }
int l_graphics_setFont(lua_State *L) { int l_graphics_setFont(lua_State *L) {
font_t *oldFont = graphics_font; font_t *oldFont = graphics_font;
if (lua_isnoneornil(L, 1)) { if (lua_isnoneornil(L, 1)) {
@@ -172,14 +179,12 @@ int l_graphics_setFont(lua_State *L) {
return 0; return 0;
} }
int l_graphics_getCanvas(lua_State *L) { int l_graphics_getCanvas(lua_State *L) {
lua_pushlightuserdata(L, graphics_canvas); lua_pushlightuserdata(L, graphics_canvas);
lua_gettable(L, LUA_REGISTRYINDEX); lua_gettable(L, LUA_REGISTRYINDEX);
return 1; return 1;
} }
int l_graphics_setCanvas(lua_State *L) { int l_graphics_setCanvas(lua_State *L) {
image_t *oldCanvas = graphics_canvas; image_t *oldCanvas = graphics_canvas;
if (lua_isnoneornil(L, 1)) { if (lua_isnoneornil(L, 1)) {
@@ -204,15 +209,11 @@ int l_graphics_setCanvas(lua_State *L) {
return 0; return 0;
} }
int l_graphics_reset(lua_State *L) { int l_graphics_reset(lua_State *L) {
int (*funcs[])(lua_State*) = { int (*funcs[])(lua_State *) = {
l_graphics_setBackgroundColor, l_graphics_setBackgroundColor, l_graphics_setColor,
l_graphics_setColor, l_graphics_setBlendMode, l_graphics_setFont,
l_graphics_setBlendMode, l_graphics_setCanvas, NULL,
l_graphics_setFont,
l_graphics_setCanvas,
NULL,
}; };
int i; int i;
for (i = 0; funcs[i]; i++) { for (i = 0; funcs[i]; i++) {
@@ -222,7 +223,6 @@ int l_graphics_reset(lua_State *L) {
return 0; return 0;
} }
int l_graphics_clear(lua_State *L) { int l_graphics_clear(lua_State *L) {
int idx = getColorFromArgs(L, NULL, graphics_backgroundColor_rgb); int idx = getColorFromArgs(L, NULL, graphics_backgroundColor_rgb);
int sz = graphics_canvas->width * graphics_canvas->height; int sz = graphics_canvas->width * graphics_canvas->height;
@@ -230,13 +230,11 @@ int l_graphics_clear(lua_State *L) {
return 0; return 0;
} }
int l_graphics_present(lua_State *L) { int l_graphics_present(lua_State *L) {
vga_update(graphics_screen->data); vga_update(graphics_screen->data);
return 0; return 0;
} }
int l_graphics_draw(lua_State *L) { int l_graphics_draw(lua_State *L) {
image_t *img = luaobj_checkudata(L, 1, LUAOBJ_TYPE_IMAGE); image_t *img = luaobj_checkudata(L, 1, LUAOBJ_TYPE_IMAGE);
quad_t *quad = NULL; quad_t *quad = NULL;
@@ -256,16 +254,14 @@ int l_graphics_draw(lua_State *L) {
int bufh = graphics_canvas->height; int bufh = graphics_canvas->height;
image_setFlip(flip); image_setFlip(flip);
if (quad) { if (quad) {
image_blit(img, buf, bufw, bufh, x, y, image_blit(img, buf, bufw, bufh, x, y, quad->x, quad->y, quad->width,
quad->x, quad->y, quad->width, quad->height); quad->height);
} else { } else {
image_blit(img, buf, bufw, bufh, x, y, image_blit(img, buf, bufw, bufh, x, y, 0, 0, img->width, img->height);
0, 0, img->width, img->height);
} }
return 0; return 0;
} }
int l_graphics_point(lua_State *L) { int l_graphics_point(lua_State *L) {
int x = luaL_checknumber(L, 1); int x = luaL_checknumber(L, 1);
int y = luaL_checknumber(L, 2); int y = luaL_checknumber(L, 2);
@@ -273,7 +269,6 @@ int l_graphics_point(lua_State *L) {
return 0; return 0;
} }
int l_graphics_line(lua_State *L) { int l_graphics_line(lua_State *L) {
int argc = lua_gettop(L); int argc = lua_gettop(L);
int lastx = luaL_checknumber(L, 1); int lastx = luaL_checknumber(L, 1);
@@ -286,8 +281,8 @@ int l_graphics_line(lua_State *L) {
int y1 = luaL_checknumber(L, idx + 1); int y1 = luaL_checknumber(L, idx + 1);
lastx = x1; lastx = x1;
lasty = y1; lasty = y1;
/* Draw line */ /* Draw line */
#define SWAP_INT(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b))) #define SWAP_INT(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b)))
int steep = abs(y1 - y0) > abs(x1 - x0); int steep = abs(y1 - y0) > abs(x1 - x0);
if (steep) { if (steep) {
SWAP_INT(x0, y0); SWAP_INT(x0, y0);
@@ -297,7 +292,7 @@ int l_graphics_line(lua_State *L) {
SWAP_INT(x0, x1); SWAP_INT(x0, x1);
SWAP_INT(y0, y1); SWAP_INT(y0, y1);
} }
#undef SWAP_INT #undef SWAP_INT
int deltax = x1 - x0; int deltax = x1 - x0;
int deltay = abs(y1 - y0); int deltay = abs(y1 - y0);
int error = deltax / 2; int error = deltax / 2;
@@ -320,7 +315,6 @@ int l_graphics_line(lua_State *L) {
return 0; return 0;
} }
int l_graphics_rectangle(lua_State *L) { int l_graphics_rectangle(lua_State *L) {
const char *mode = luaL_checkstring(L, 1); const char *mode = luaL_checkstring(L, 1);
int x = luaL_checknumber(L, 2); int x = luaL_checknumber(L, 2);
@@ -336,14 +330,25 @@ int l_graphics_rectangle(lua_State *L) {
luaL_error(L, "bad mode"); luaL_error(L, "bad mode");
} }
/* Clip to screen */ /* Clip to screen */
if (x < 0) { x2 += x; x = 0; } if (x < 0) {
if (y < 0) { y2 += y; y = 0; } x2 += x;
if (x2 > graphics_canvas->width) { x2 = graphics_canvas->width; } x = 0;
if (y2 > graphics_canvas->height) { y2 = graphics_canvas->height; } }
if (y < 0) {
y2 += y;
y = 0;
}
if (x2 > graphics_canvas->width) {
x2 = graphics_canvas->width;
}
if (y2 > graphics_canvas->height) {
y2 = graphics_canvas->height;
}
/* Get width/height and Abort early if we're off screen */ /* Get width/height and Abort early if we're off screen */
int width = x2 - x; int width = x2 - x;
int height = y2 - y; int height = y2 - y;
if (width <= 0 || height <= 0) return 0; if (width <= 0 || height <= 0)
return 0;
/* Draw */ /* Draw */
if (fill) { if (fill) {
int i; int i;
@@ -352,21 +357,20 @@ int l_graphics_rectangle(lua_State *L) {
graphics_color, width); graphics_color, width);
} }
} else { } else {
memset(graphics_canvas->data + x + y * graphics_canvas->width, memset(graphics_canvas->data + x + y * graphics_canvas->width,
graphics_color, width); graphics_color, width);
memset(graphics_canvas->data + x + (y2 - 1) * graphics_canvas->width, memset(graphics_canvas->data + x + (y2 - 1) * graphics_canvas->width,
graphics_color, width); graphics_color, width);
int i; int i;
for (i = y; i < y2; i++) { for (i = y; i < y2; i++) {
graphics_canvas->data[x + i * graphics_canvas->width] = graphics_canvas->data[x + i * graphics_canvas->width] =
graphics_canvas->data[x2 - 1 + i * graphics_canvas->width] = graphics_canvas->data[x2 - 1 + i * graphics_canvas->width] =
graphics_color; graphics_color;
} }
} }
return 0; return 0;
} }
int l_graphics_circle(lua_State *L) { int l_graphics_circle(lua_State *L) {
const char *mode = luaL_checkstring(L, 1); const char *mode = luaL_checkstring(L, 1);
int x = luaL_checknumber(L, 2); int x = luaL_checknumber(L, 2);
@@ -383,62 +387,67 @@ int l_graphics_circle(lua_State *L) {
/* Draw */ /* Draw */
if (fill) { if (fill) {
int dx = radius, dy = 0; int dx = radius, dy = 0;
int radiusError = 1-dx; int radiusError = 1 - dx;
while(dx >= dy) { while (dx >= dy) {
#define FILL_ROW(startx, endx, starty)\ #define FILL_ROW(startx, endx, starty) \
do {\ do { \
int sx = (startx);\ int sx = (startx); \
int ex = (endx);\ int ex = (endx); \
int sy = (starty);\ int sy = (starty); \
if (sy < 0 || sy >= graphics_canvas->height) break;\ if (sy < 0 || sy >= graphics_canvas->height) \
if (sx < 0) sx = 0;\ break; \
if (sx > graphics_canvas->width) sx = graphics_canvas->width;\ if (sx < 0) \
if (ex < 0) ex = 0;\ sx = 0; \
if (ex > graphics_canvas->width) ex = graphics_canvas->width;\ if (sx > graphics_canvas->width) \
if (sx == ex) break;\ sx = graphics_canvas->width; \
memset(graphics_canvas->data + sx + sy * graphics_canvas->width,\ if (ex < 0) \
graphics_color, ex - sx);\ ex = 0; \
} while (0) if (ex > graphics_canvas->width) \
ex = graphics_canvas->width; \
if (sx == ex) \
break; \
memset(graphics_canvas->data + sx + sy * graphics_canvas->width, \
graphics_color, ex - sx); \
} while (0)
FILL_ROW( -dx + x, dx + x, dy + y ); FILL_ROW(-dx + x, dx + x, dy + y);
FILL_ROW( -dx + x, dx + x, -dy + y ); FILL_ROW(-dx + x, dx + x, -dy + y);
FILL_ROW( -dy + x, dy + x, dx + y ); FILL_ROW(-dy + x, dy + x, dx + y);
FILL_ROW( -dy + x, dy + x, -dx + y ); FILL_ROW(-dy + x, dy + x, -dx + y);
#undef FILL_ROW #undef FILL_ROW
dy++; dy++;
if(radiusError<0) { if (radiusError < 0) {
radiusError+=2*dy+1; radiusError += 2 * dy + 1;
} else { } else {
dx--; dx--;
radiusError+=2*(dy-dx+1); radiusError += 2 * (dy - dx + 1);
} }
} }
} else { } else {
int dx = radius, dy = 0; int dx = radius, dy = 0;
int radiusError = 1-dx; int radiusError = 1 - dx;
while(dx >= dy) { while (dx >= dy) {
image_setPixel(graphics_canvas, dx + x, dy + y, graphics_color); image_setPixel(graphics_canvas, dx + x, dy + y, graphics_color);
image_setPixel(graphics_canvas, -dx + x, dy + y, graphics_color); image_setPixel(graphics_canvas, -dx + x, dy + y, graphics_color);
image_setPixel(graphics_canvas, dx + x, -dy + y, graphics_color); image_setPixel(graphics_canvas, dx + x, -dy + y, graphics_color);
image_setPixel(graphics_canvas, -dx + x, -dy + y, graphics_color); image_setPixel(graphics_canvas, -dx + x, -dy + y, graphics_color);
image_setPixel(graphics_canvas, dy + x, dx + y, graphics_color); image_setPixel(graphics_canvas, dy + x, dx + y, graphics_color);
image_setPixel(graphics_canvas, -dy + x, dx + y, graphics_color); image_setPixel(graphics_canvas, -dy + x, dx + y, graphics_color);
image_setPixel(graphics_canvas, dy + x, -dx + y, graphics_color); image_setPixel(graphics_canvas, dy + x, -dx + y, graphics_color);
image_setPixel(graphics_canvas, -dy + x, -dx + y, graphics_color); image_setPixel(graphics_canvas, -dy + x, -dx + y, graphics_color);
dy++; dy++;
if(radiusError<0) { if (radiusError < 0) {
radiusError+=2*dy+1; radiusError += 2 * dy + 1;
} else { } else {
dx--; dx--;
radiusError+=2*(dy-dx+1); radiusError += 2 * (dy - dx + 1);
} }
} }
} }
return 0; return 0;
} }
int l_graphics_print(lua_State *L) { int l_graphics_print(lua_State *L) {
luaL_checkany(L, 1); luaL_checkany(L, 1);
const char *str = luaL_tolstring(L, 1, NULL); const char *str = luaL_tolstring(L, 1, NULL);
@@ -449,8 +458,6 @@ int l_graphics_print(lua_State *L) {
return 0; return 0;
} }
int l_image_new(lua_State *L); int l_image_new(lua_State *L);
int l_image_newCanvas(lua_State *L); int l_image_newCanvas(lua_State *L);
int l_quad_new(lua_State *L); int l_quad_new(lua_State *L);
@@ -458,33 +465,33 @@ int l_font_new(lua_State *L);
int luaopen_graphics(lua_State *L) { int luaopen_graphics(lua_State *L) {
luaL_Reg reg[] = { luaL_Reg reg[] = {
{ "getDimensions", l_graphics_getDimensions }, {"getDimensions", l_graphics_getDimensions},
{ "getWidth", l_graphics_getWidth }, {"getWidth", l_graphics_getWidth},
{ "getHeight", l_graphics_getHeight }, {"getHeight", l_graphics_getHeight},
{ "getBackgroundColor", l_graphics_getBackgroundColor }, {"getBackgroundColor", l_graphics_getBackgroundColor},
{ "setBackgroundColor", l_graphics_setBackgroundColor }, {"setBackgroundColor", l_graphics_setBackgroundColor},
{ "getColor", l_graphics_getColor }, {"getColor", l_graphics_getColor},
{ "setColor", l_graphics_setColor }, {"setColor", l_graphics_setColor},
{ "getBlendMode", l_graphics_getBlendMode }, {"getBlendMode", l_graphics_getBlendMode},
{ "setBlendMode", l_graphics_setBlendMode }, {"setBlendMode", l_graphics_setBlendMode},
{ "getFont", l_graphics_getFont }, {"getFont", l_graphics_getFont},
{ "setFont", l_graphics_setFont }, {"setFont", l_graphics_setFont},
{ "getCanvas", l_graphics_getCanvas }, {"getCanvas", l_graphics_getCanvas},
{ "setCanvas", l_graphics_setCanvas }, {"setCanvas", l_graphics_setCanvas},
{ "reset", l_graphics_reset }, {"reset", l_graphics_reset},
{ "clear", l_graphics_clear }, {"clear", l_graphics_clear},
{ "present", l_graphics_present }, {"present", l_graphics_present},
{ "draw", l_graphics_draw }, {"draw", l_graphics_draw},
{ "point", l_graphics_point }, {"point", l_graphics_point},
{ "line", l_graphics_line }, {"line", l_graphics_line},
{ "rectangle", l_graphics_rectangle }, {"rectangle", l_graphics_rectangle},
{ "circle", l_graphics_circle }, {"circle", l_graphics_circle},
{ "print", l_graphics_print }, {"print", l_graphics_print},
{ "newImage", l_image_new }, {"newImage", l_image_new},
{ "newCanvas", l_image_newCanvas }, {"newCanvas", l_image_newCanvas},
{ "newQuad", l_quad_new }, {"newQuad", l_quad_new},
{ "newFont", l_font_new }, {"newFont", l_font_new},
{ 0, 0 }, {0, 0},
}; };
luaL_newlib(L, reg); luaL_newlib(L, reg);

View File

@@ -9,29 +9,29 @@
#include "palette.h" #include "palette.h"
#include "image.h" #include "image.h"
#define CLASS_TYPE LUAOBJ_TYPE_IMAGE
#define CLASS_TYPE LUAOBJ_TYPE_IMAGE #define CLASS_NAME "Image"
#define CLASS_NAME "Image"
int l_image_new(lua_State *L) { int l_image_new(lua_State *L) {
const char *filename = luaL_checkstring(L, 1); const char *filename = luaL_checkstring(L, 1);
image_t *self = luaobj_newudata(L, sizeof(*self)); image_t *self = luaobj_newudata(L, sizeof(*self));
luaobj_setclass(L, CLASS_TYPE, CLASS_NAME); luaobj_setclass(L, CLASS_TYPE, CLASS_NAME);
const char *err = image_init(self, filename); const char *err = image_init(self, filename);
if (err) luaL_error(L, err); if (err)
luaL_error(L, err);
return 1; return 1;
} }
int l_image_newCanvas(lua_State *L) { int l_image_newCanvas(lua_State *L) {
int width = VGA_WIDTH; int width = VGA_WIDTH;
int height = VGA_HEIGHT; int height = VGA_HEIGHT;
if (lua_gettop(L) > 0) { if (lua_gettop(L) > 0) {
width = luaL_checknumber(L, 1); width = luaL_checknumber(L, 1);
height = luaL_checknumber(L, 2); height = luaL_checknumber(L, 2);
if (width <= 0) luaL_argerror(L, 1, "width must be larger than 0"); if (width <= 0)
if (height <= 0) luaL_argerror(L, 2, "height must be larger than 0"); luaL_argerror(L, 1, "width must be larger than 0");
if (height <= 0)
luaL_argerror(L, 2, "height must be larger than 0");
} }
image_t *self = luaobj_newudata(L, sizeof(*self)); image_t *self = luaobj_newudata(L, sizeof(*self));
luaobj_setclass(L, CLASS_TYPE, CLASS_NAME); luaobj_setclass(L, CLASS_TYPE, CLASS_NAME);
@@ -39,14 +39,12 @@ int l_image_newCanvas(lua_State *L) {
return 1; return 1;
} }
int l_image_gc(lua_State *L) { int l_image_gc(lua_State *L) {
image_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); image_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
image_deinit(self); image_deinit(self);
return 0; return 0;
} }
int l_image_getDimensions(lua_State *L) { int l_image_getDimensions(lua_State *L) {
image_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); image_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
lua_pushinteger(L, self->width); lua_pushinteger(L, self->width);
@@ -54,21 +52,18 @@ int l_image_getDimensions(lua_State *L) {
return 2; return 2;
} }
int l_image_getWidth(lua_State *L) { int l_image_getWidth(lua_State *L) {
image_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); image_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
lua_pushinteger(L, self->width); lua_pushinteger(L, self->width);
return 1; return 1;
} }
int l_image_getHeight(lua_State *L) { int l_image_getHeight(lua_State *L) {
image_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); image_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
lua_pushinteger(L, self->height); lua_pushinteger(L, self->height);
return 1; return 1;
} }
int l_image_getPixel(lua_State *L) { int l_image_getPixel(lua_State *L) {
image_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); image_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
int x = luaL_checknumber(L, 2); int x = luaL_checknumber(L, 2);
@@ -94,7 +89,6 @@ int l_image_getPixel(lua_State *L) {
} }
} }
int l_image_setPixel(lua_State *L) { int l_image_setPixel(lua_State *L) {
image_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); image_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
int x = luaL_checknumber(L, 2); int x = luaL_checknumber(L, 2);
@@ -118,17 +112,16 @@ int l_image_setPixel(lua_State *L) {
return 0; return 0;
} }
int luaopen_image(lua_State *L) { int luaopen_image(lua_State *L) {
luaL_Reg reg[] = { luaL_Reg reg[] = {
{ "new", l_image_new }, {"new", l_image_new},
{ "__gc", l_image_gc }, {"__gc", l_image_gc},
{ "getDimensions", l_image_getDimensions }, {"getDimensions", l_image_getDimensions},
{ "getWidth", l_image_getWidth }, {"getWidth", l_image_getWidth},
{ "getHeight", l_image_getHeight }, {"getHeight", l_image_getHeight},
{ "getPixel", l_image_getPixel }, {"getPixel", l_image_getPixel},
{ "setPixel", l_image_setPixel }, {"setPixel", l_image_setPixel},
{ 0, 0 }, {0, 0},
}; };
luaobj_newclass(L, CLASS_NAME, NULL, l_image_new, reg); luaobj_newclass(L, CLASS_NAME, NULL, l_image_new, reg);
return 1; return 1;

View File

@@ -5,17 +5,14 @@
* under the terms of the MIT license. See LICENSE for details. * under the terms of the MIT license. See LICENSE for details.
*/ */
#include "keyboard.h" #include "keyboard.h"
#include "luaobj.h" #include "luaobj.h"
int l_keyboard_setKeyRepeat(lua_State *L) { int l_keyboard_setKeyRepeat(lua_State *L) {
keyboard_setKeyRepeat( lua_toboolean(L, 1) ); keyboard_setKeyRepeat(lua_toboolean(L, 1));
return 0; return 0;
} }
int l_keyboard_isDown(lua_State *L) { int l_keyboard_isDown(lua_State *L) {
int n = lua_gettop(L); int n = lua_gettop(L);
int res = 0; int res = 0;
@@ -28,12 +25,11 @@ int l_keyboard_isDown(lua_State *L) {
return 1; return 1;
} }
int luaopen_keyboard(lua_State *L) { int luaopen_keyboard(lua_State *L) {
luaL_Reg reg[] = { luaL_Reg reg[] = {
{ "setKeyRepeat", l_keyboard_setKeyRepeat }, {"setKeyRepeat", l_keyboard_setKeyRepeat},
{ "isDown", l_keyboard_isDown }, {"isDown", l_keyboard_isDown},
{ 0, 0 }, {0, 0},
}; };
luaL_newlib(L, reg); luaL_newlib(L, reg);
return 1; return 1;

View File

@@ -7,15 +7,13 @@
#include "luaobj.h" #include "luaobj.h"
#define LOVE_VERSION "0.2.1" #define LOVE_VERSION "0.42.23"
int l_love_getVersion(lua_State *L) { int l_love_getVersion(lua_State *L) {
lua_pushstring(L, LOVE_VERSION); lua_pushstring(L, LOVE_VERSION);
return 1; return 1;
} }
int luaopen_image(lua_State *L); int luaopen_image(lua_State *L);
int luaopen_quad(lua_State *L); int luaopen_quad(lua_State *L);
int luaopen_font(lua_State *L); int luaopen_font(lua_State *L);
@@ -34,12 +32,8 @@ int luaopen_love(lua_State *L) {
/* Init classes -- all the built in classes are inited here as to create the /* Init classes -- all the built in classes are inited here as to create the
* metatables required by their constructors. Any new classes must also be * metatables required by their constructors. Any new classes must also be
* registered here before they will work. */ * registered here before they will work. */
int (*classes[])(lua_State *L) = { int (*classes[])(lua_State * L) = {
luaopen_image, luaopen_image, luaopen_quad, luaopen_font, luaopen_source, NULL,
luaopen_quad,
luaopen_font,
luaopen_source,
NULL,
}; };
for (i = 0; classes[i]; i++) { for (i = 0; classes[i]; i++) {
classes[i](L); classes[i](L);
@@ -48,22 +42,25 @@ int luaopen_love(lua_State *L) {
/* Init love module */ /* Init love module */
luaL_Reg reg[] = { luaL_Reg reg[] = {
{ "getVersion", l_love_getVersion }, {"getVersion", l_love_getVersion},
{ 0, 0 }, {0, 0},
}; };
luaL_newlib(L, reg); luaL_newlib(L, reg);
/* Init submodules */ /* Init submodules */
struct { char *name; int (*fn)(lua_State *L); } mods[] = { struct {
{ "system", luaopen_system }, char *name;
{ "event", luaopen_event }, int (*fn)(lua_State *L);
{ "filesystem", luaopen_filesystem }, } mods[] = {
{ "graphics", luaopen_graphics }, {"system", luaopen_system},
{ "audio", luaopen_audio }, {"event", luaopen_event},
{ "timer", luaopen_timer }, {"filesystem", luaopen_filesystem},
{ "keyboard", luaopen_keyboard }, {"graphics", luaopen_graphics},
{ "mouse", luaopen_mouse }, {"audio", luaopen_audio},
{ 0 }, {"timer", luaopen_timer},
{"keyboard", luaopen_keyboard},
{"mouse", luaopen_mouse},
{0},
}; };
for (i = 0; mods[i].name; i++) { for (i = 0; mods[i].name; i++) {
mods[i].fn(L); mods[i].fn(L);

View File

@@ -5,9 +5,8 @@
* under the terms of the MIT license. See LICENSE for details. * under the terms of the MIT license. See LICENSE for details.
*/ */
#include "mouse.h" #include "mouse.h"
#include "luaobj.h" #include "luaobj.h"
int l_mouse_getPosition(lua_State *L) { int l_mouse_getPosition(lua_State *L) {
lua_pushinteger(L, mouse_getX()); lua_pushinteger(L, mouse_getX());
@@ -15,19 +14,16 @@ int l_mouse_getPosition(lua_State *L) {
return 2; return 2;
} }
int l_mouse_getX(lua_State *L) { int l_mouse_getX(lua_State *L) {
lua_pushinteger(L, mouse_getX()); lua_pushinteger(L, mouse_getX());
return 1; return 1;
} }
int l_mouse_getY(lua_State *L) { int l_mouse_getY(lua_State *L) {
lua_pushinteger(L, mouse_getY()); lua_pushinteger(L, mouse_getY());
return 1; return 1;
} }
int l_mouse_isDown(lua_State *L) { int l_mouse_isDown(lua_State *L) {
int n = lua_gettop(L); int n = lua_gettop(L);
int res = 0; int res = 0;
@@ -42,15 +38,13 @@ int l_mouse_isDown(lua_State *L) {
return 1; return 1;
} }
int luaopen_mouse(lua_State *L) { int luaopen_mouse(lua_State *L) {
luaL_Reg reg[] = { luaL_Reg reg[] = {
{ "getPosition", l_mouse_getPosition }, {"getPosition", l_mouse_getPosition},
{ "getX", l_mouse_getX }, {"getX", l_mouse_getX},
{ "getY", l_mouse_getY }, {"getY", l_mouse_getY},
{ "isDown", l_mouse_isDown }, {"isDown", l_mouse_isDown},
{ 0, 0 }, {0, 0},
}; };
luaL_newlib(L, reg); luaL_newlib(L, reg);
return 1; return 1;

View File

@@ -13,10 +13,8 @@
#include "quad.h" #include "quad.h"
#include "luaobj.h" #include "luaobj.h"
#define CLASS_TYPE LUAOBJ_TYPE_QUAD
#define CLASS_TYPE LUAOBJ_TYPE_QUAD #define CLASS_NAME "Quad"
#define CLASS_NAME "Quad"
int l_quad_new(lua_State *L) { int l_quad_new(lua_State *L) {
quad_t *self = luaobj_newudata(L, sizeof(*self)); quad_t *self = luaobj_newudata(L, sizeof(*self));
@@ -28,7 +26,6 @@ int l_quad_new(lua_State *L) {
return 1; return 1;
} }
int l_quad_setViewport(lua_State *L) { int l_quad_setViewport(lua_State *L) {
quad_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); quad_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
self->x = luaL_checknumber(L, 2); self->x = luaL_checknumber(L, 2);
@@ -38,7 +35,6 @@ int l_quad_setViewport(lua_State *L) {
return 0; return 0;
} }
int l_quad_getViewport(lua_State *L) { int l_quad_getViewport(lua_State *L) {
quad_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); quad_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
lua_pushnumber(L, self->x); lua_pushnumber(L, self->x);
@@ -48,15 +44,13 @@ int l_quad_getViewport(lua_State *L) {
return 4; return 4;
} }
int luaopen_quad(lua_State *L) { int luaopen_quad(lua_State *L) {
luaL_Reg reg[] = { luaL_Reg reg[] = {
{ "new", l_quad_new }, {"new", l_quad_new},
{ "getViewport", l_quad_getViewport }, {"getViewport", l_quad_getViewport},
{ "setViewport", l_quad_setViewport }, {"setViewport", l_quad_setViewport},
{ 0, 0 }, {0, 0},
}; };
luaobj_newclass(L, CLASS_NAME, NULL, l_quad_new, reg); luaobj_newclass(L, CLASS_NAME, NULL, l_quad_new, reg);
return 1; return 1;
} }

View File

@@ -10,17 +10,14 @@
#include "filesystem.h" #include "filesystem.h"
#include "luaobj.h" #include "luaobj.h"
#define CLASS_TYPE LUAOBJ_TYPE_SOURCE
#define CLASS_TYPE LUAOBJ_TYPE_SOURCE #define CLASS_NAME "Source"
#define CLASS_NAME "Source"
typedef struct { typedef struct {
cm_Source *source; cm_Source *source;
void *data; void *data;
} source_t; } source_t;
int l_source_new(lua_State *L) { int l_source_new(lua_State *L) {
const char *filename = luaL_checkstring(L, 1); const char *filename = luaL_checkstring(L, 1);
/* Create object */ /* Create object */
@@ -42,15 +39,15 @@ int l_source_new(lua_State *L) {
return 1; return 1;
} }
int l_source_gc(lua_State *L) { int l_source_gc(lua_State *L) {
source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
if (self->source) cm_destroy_source(self->source); if (self->source)
if (self->data) filesystem_free(self->data); cm_destroy_source(self->source);
if (self->data)
filesystem_free(self->data);
return 0; return 0;
} }
int l_source_setVolume(lua_State *L) { int l_source_setVolume(lua_State *L) {
source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
double n = luaL_checknumber(L, 2); double n = luaL_checknumber(L, 2);
@@ -58,7 +55,6 @@ int l_source_setVolume(lua_State *L) {
return 0; return 0;
} }
int l_source_setPitch(lua_State *L) { int l_source_setPitch(lua_State *L) {
source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
double n = luaL_checknumber(L, 2); double n = luaL_checknumber(L, 2);
@@ -66,7 +62,6 @@ int l_source_setPitch(lua_State *L) {
return 0; return 0;
} }
int l_source_setLooping(lua_State *L) { int l_source_setLooping(lua_State *L) {
source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
int enable = lua_toboolean(L, 2); int enable = lua_toboolean(L, 2);
@@ -74,7 +69,6 @@ int l_source_setLooping(lua_State *L) {
return 0; return 0;
} }
int l_source_getDuration(lua_State *L) { int l_source_getDuration(lua_State *L) {
source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
double n = cm_get_length(self->source); double n = cm_get_length(self->source);
@@ -82,28 +76,24 @@ int l_source_getDuration(lua_State *L) {
return 1; return 1;
} }
int l_source_isPlaying(lua_State *L) { int l_source_isPlaying(lua_State *L) {
source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
lua_pushboolean(L, cm_get_state(self->source) == CM_STATE_PLAYING); lua_pushboolean(L, cm_get_state(self->source) == CM_STATE_PLAYING);
return 1; return 1;
} }
int l_source_isPaused(lua_State *L) { int l_source_isPaused(lua_State *L) {
source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
lua_pushboolean(L, cm_get_state(self->source) == CM_STATE_PAUSED); lua_pushboolean(L, cm_get_state(self->source) == CM_STATE_PAUSED);
return 1; return 1;
} }
int l_source_isStopped(lua_State *L) { int l_source_isStopped(lua_State *L) {
source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
lua_pushboolean(L, cm_get_state(self->source) == CM_STATE_STOPPED); lua_pushboolean(L, cm_get_state(self->source) == CM_STATE_STOPPED);
return 1; return 1;
} }
int l_source_tell(lua_State *L) { int l_source_tell(lua_State *L) {
source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
double n = cm_get_position(self->source); double n = cm_get_position(self->source);
@@ -111,44 +101,40 @@ int l_source_tell(lua_State *L) {
return 1; return 1;
} }
int l_source_play(lua_State *L) { int l_source_play(lua_State *L) {
source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
cm_play(self->source); cm_play(self->source);
return 0; return 0;
} }
int l_source_pause(lua_State *L) { int l_source_pause(lua_State *L) {
source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
cm_pause(self->source); cm_pause(self->source);
return 0; return 0;
} }
int l_source_stop(lua_State *L) { int l_source_stop(lua_State *L) {
source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE); source_t *self = luaobj_checkudata(L, 1, CLASS_TYPE);
cm_stop(self->source); cm_stop(self->source);
return 0; return 0;
} }
int luaopen_source(lua_State *L) { int luaopen_source(lua_State *L) {
luaL_Reg reg[] = { luaL_Reg reg[] = {
{ "new", l_source_new }, {"new", l_source_new},
{ "__gc", l_source_gc }, {"__gc", l_source_gc},
{ "setVolume", l_source_setVolume }, {"setVolume", l_source_setVolume},
{ "setPitch", l_source_setPitch }, {"setPitch", l_source_setPitch},
{ "setLooping", l_source_setLooping }, {"setLooping", l_source_setLooping},
{ "getDuration", l_source_getDuration }, {"getDuration", l_source_getDuration},
{ "isPlaying", l_source_isPlaying }, {"isPlaying", l_source_isPlaying},
{ "isPaused", l_source_isPaused }, {"isPaused", l_source_isPaused},
{ "isStopped", l_source_isStopped }, {"isStopped", l_source_isStopped},
{ "tell", l_source_tell }, {"tell", l_source_tell},
{ "play", l_source_play }, {"play", l_source_play},
{ "pause", l_source_pause }, {"pause", l_source_pause},
{ "stop", l_source_stop }, {"stop", l_source_stop},
{ 0, 0 }, {0, 0},
}; };
luaobj_newclass(L, CLASS_NAME, NULL, l_source_new, reg); luaobj_newclass(L, CLASS_NAME, NULL, l_source_new, reg);
return 1; return 1;

View File

@@ -11,25 +11,21 @@
#include "luaobj.h" #include "luaobj.h"
#include "vga.h" #include "vga.h"
int l_system_getOS(lua_State *L) { int l_system_getOS(lua_State *L) {
lua_pushstring(L, "DOS"); lua_pushstring(L, "DOS");
return 1; return 1;
} }
int l_system_getMemUsage(lua_State *L) { int l_system_getMemUsage(lua_State *L) {
lua_pushnumber(L, lua_gc(L, LUA_GCCOUNT, 0) + dmt_usage() / 1024); lua_pushnumber(L, lua_gc(L, LUA_GCCOUNT, 0) + dmt_usage() / 1024);
return 1; return 1;
} }
int luaopen_system(lua_State *L) { int luaopen_system(lua_State *L) {
luaL_Reg reg[] = { luaL_Reg reg[] = {
{ "getOS", l_system_getOS }, {"getOS", l_system_getOS},
{ "getMemUsage", l_system_getMemUsage }, {"getMemUsage", l_system_getMemUsage},
{ 0, 0 }, {0, 0},
}; };
luaL_newlib(L, reg); luaL_newlib(L, reg);
return 1; return 1;

View File

@@ -14,11 +14,10 @@
long long timer_lastStep; long long timer_lastStep;
double timer_lastDt; double timer_lastDt;
double timer_avgLastDt; double timer_avgLastDt;
double timer_avgAcc = 1; double timer_avgAcc = 1;
int timer_avgCount; int timer_avgCount;
double timer_avgTimer; double timer_avgTimer;
int l_timer_step(lua_State *L) { int l_timer_step(lua_State *L) {
/* Do delta */ /* Do delta */
@@ -28,7 +27,7 @@ int l_timer_step(lua_State *L) {
* trying for a proper value if this occurs. */ * trying for a proper value if this occurs. */
do { do {
now = uclock(); now = uclock();
timer_lastDt = (now - timer_lastStep) / (double) UCLOCKS_PER_SEC; timer_lastDt = (now - timer_lastStep) / (double)UCLOCKS_PER_SEC;
} while (timer_lastDt < 0); } while (timer_lastDt < 0);
timer_lastStep = now; timer_lastStep = now;
/* Do average */ /* Do average */
@@ -44,46 +43,40 @@ int l_timer_step(lua_State *L) {
return 0; return 0;
} }
int l_timer_sleep(lua_State *L) { int l_timer_sleep(lua_State *L) {
delay(luaL_checknumber(L, 1) * 1000.); delay(luaL_checknumber(L, 1) * 1000.);
return 1; return 1;
} }
int l_timer_getDelta(lua_State *L) { int l_timer_getDelta(lua_State *L) {
lua_pushnumber(L, timer_lastDt); lua_pushnumber(L, timer_lastDt);
return 1; return 1;
} }
int l_timer_getAverageDelta(lua_State *L) { int l_timer_getAverageDelta(lua_State *L) {
lua_pushnumber(L, timer_avgLastDt); lua_pushnumber(L, timer_avgLastDt);
return 1; return 1;
} }
int l_timer_getFPS(lua_State *L) { int l_timer_getFPS(lua_State *L) {
lua_pushnumber(L, (int)(1. / timer_avgLastDt)); lua_pushnumber(L, (int)(1. / timer_avgLastDt));
return 1; return 1;
} }
int l_timer_getTime(lua_State *L) { int l_timer_getTime(lua_State *L) {
lua_pushnumber(L, uclock() / (double) UCLOCKS_PER_SEC); lua_pushnumber(L, uclock() / (double)UCLOCKS_PER_SEC);
return 1; return 1;
} }
int luaopen_timer(lua_State *L) { int luaopen_timer(lua_State *L) {
luaL_Reg reg[] = { luaL_Reg reg[] = {
{ "step", l_timer_step }, {"step", l_timer_step},
{ "sleep", l_timer_sleep }, {"sleep", l_timer_sleep},
{ "getDelta", l_timer_getDelta }, {"getDelta", l_timer_getDelta},
{ "getAverageDelta", l_timer_getAverageDelta }, {"getAverageDelta", l_timer_getAverageDelta},
{ "getFPS", l_timer_getFPS }, {"getFPS", l_timer_getFPS},
{ "getTime", l_timer_getTime }, {"getTime", l_timer_getTime},
{ 0, 0 }, {0, 0},
}; };
luaL_newlib(L, reg); luaL_newlib(L, reg);
return 1; return 1;

View File

@@ -17,14 +17,12 @@ int mouse_x, mouse_y;
int mouse_lastX, mouse_lastY; int mouse_lastX, mouse_lastY;
int mouse_buttonStates[MOUSE_BUTTON_MAX]; int mouse_buttonStates[MOUSE_BUTTON_MAX];
void mouse_init(void) { void mouse_init(void) {
union REGS regs = {}; union REGS regs = {};
int86(0x33, &regs, &regs); int86(0x33, &regs, &regs);
mouse_inited = regs.x.ax ? 1 : 0; mouse_inited = regs.x.ax ? 1 : 0;
} }
void mouse_update(void) { void mouse_update(void) {
if (!mouse_inited) { if (!mouse_inited) {
return; return;
@@ -75,18 +73,8 @@ void mouse_update(void) {
} }
} }
int mouse_isDown(int button) { return mouse_buttonStates[button]; }
int mouse_getX(void) { return mouse_x; }
int mouse_isDown(int button) { int mouse_getY(void) { return mouse_y; }
return mouse_buttonStates[button];
}
int mouse_getX(void) {
return mouse_x;
}
int mouse_getY(void) {
return mouse_y;
}

View File

@@ -15,7 +15,6 @@ enum {
MOUSE_BUTTON_MAX MOUSE_BUTTON_MAX
}; };
void mouse_init(void); void mouse_init(void);
void mouse_update(void); void mouse_update(void);
int mouse_isDown(int button); int mouse_isDown(int button);

View File

@@ -15,7 +15,6 @@
#include "package.h" #include "package.h"
static void error(const char *fmt, ...) { static void error(const char *fmt, ...) {
va_list argp; va_list argp;
printf("Package error: "); printf("Package error: ");
@@ -26,7 +25,6 @@ static void error(const char *fmt, ...) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
static int tar_stream_write(mtar_t *tar, const void *data, unsigned size) { static int tar_stream_write(mtar_t *tar, const void *data, unsigned size) {
unsigned res = fwrite(data, 1, size, tar->stream); unsigned res = fwrite(data, 1, size, tar->stream);
if (res != size) { if (res != size) {
@@ -35,13 +33,12 @@ static int tar_stream_write(mtar_t *tar, const void *data, unsigned size) {
return MTAR_ESUCCESS; return MTAR_ESUCCESS;
} }
static void concat(char *dst, int dstsz, ...) { static void concat(char *dst, int dstsz, ...) {
const char *s; const char *s;
va_list argp; va_list argp;
int i = 0; int i = 0;
va_start(argp, dstsz); va_start(argp, dstsz);
while ( (s = va_arg(argp, const char*)) ) { while ((s = va_arg(argp, const char *))) {
while (*s) { while (*s) {
dst[i++] = *s++; dst[i++] = *s++;
if (i == dstsz) { if (i == dstsz) {
@@ -53,18 +50,16 @@ static void concat(char *dst, int dstsz, ...) {
va_end(argp); va_end(argp);
} }
static void concat_path(char *dst, int dstsz, const char *dir,
static const char *filename) {
void concat_path(char *dst, int dstsz, const char *dir, const char *filename) {
int dirlen = strlen(dir); int dirlen = strlen(dir);
if ( dir[dirlen - 1] == '/' || *dir == '\0' ) { if (dir[dirlen - 1] == '/' || *dir == '\0') {
concat(dst, dstsz, dir, filename, NULL); concat(dst, dstsz, dir, filename, NULL);
} else { } else {
concat(dst, dstsz, dir, "/", filename, NULL); concat(dst, dstsz, dir, "/", filename, NULL);
} }
} }
static void write_file(mtar_t *tar, const char *inname, const char *outname) { static void write_file(mtar_t *tar, const char *inname, const char *outname) {
FILE *fp = fopen(inname, "rb"); FILE *fp = fopen(inname, "rb");
if (!fp) { if (!fp) {
@@ -86,7 +81,7 @@ static void write_file(mtar_t *tar, const char *inname, const char *outname) {
/* Write file */ /* Write file */
int chr; int chr;
while ( (chr = fgetc(fp)) != EOF ) { while ((chr = fgetc(fp)) != EOF) {
unsigned char byte = chr; unsigned char byte = chr;
mtar_write_data(tar, &byte, 1); mtar_write_data(tar, &byte, 1);
} }
@@ -95,7 +90,6 @@ static void write_file(mtar_t *tar, const char *inname, const char *outname) {
fclose(fp); fclose(fp);
} }
static void write_dir(mtar_t *tar, const char *indir, const char *outdir) { static void write_dir(mtar_t *tar, const char *indir, const char *outdir) {
char inbuf[256]; char inbuf[256];
char outbuf[256]; char outbuf[256];
@@ -117,7 +111,7 @@ static void write_dir(mtar_t *tar, const char *indir, const char *outdir) {
} }
/* Write files */ /* Write files */
while ( (ep = readdir(dir)) ) { while ((ep = readdir(dir))) {
/* Skip `.` and `..` */ /* Skip `.` and `..` */
if (!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, "..")) { if (!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, "..")) {
continue; continue;
@@ -138,8 +132,8 @@ static void write_dir(mtar_t *tar, const char *indir, const char *outdir) {
closedir(dir); closedir(dir);
} }
void package_make(const char *indir, const char *outfile, const char *exefile,
void package_make(const char *indir, const char *outfile, const char *exefile, int type) { int type) {
/* Open file */ /* Open file */
FILE *fp = fopen(outfile, "wb"); FILE *fp = fopen(outfile, "wb");
if (!fp) { if (!fp) {
@@ -153,7 +147,7 @@ void package_make(const char *indir, const char *outfile, const char *exefile, i
error("couldn't open .exe file"); error("couldn't open .exe file");
} }
int chr; int chr;
while ( (chr = fgetc(exefp)) != EOF ) { while ((chr = fgetc(exefp)) != EOF) {
fputc(chr, fp); fputc(chr, fp);
} }
fclose(exefp); fclose(exefp);
@@ -182,13 +176,12 @@ void package_make(const char *indir, const char *outfile, const char *exefile, i
fclose(fp); fclose(fp);
} }
int package_run(int argc, char **argv) { int package_run(int argc, char **argv) {
/* Check for `--pack` argument; return failure if it isn't present */ /* Check for `--pack` argument; return failure if it isn't present */
if (argc < 2) { if (argc < 2) {
return PACKAGE_EFAILURE; return PACKAGE_EFAILURE;
} }
if ( strcmp(argv[1], "--pack") != 0 && strcmp(argv[1], "--PACK") != 0 ) { if (strcmp(argv[1], "--pack") != 0 && strcmp(argv[1], "--PACK") != 0) {
return PACKAGE_EFAILURE; return PACKAGE_EFAILURE;
} }
@@ -199,7 +192,7 @@ int package_run(int argc, char **argv) {
/* Set package type based on file extension */ /* Set package type based on file extension */
int type = PACKAGE_TTAR; int type = PACKAGE_TTAR;
if ( strstr(argv[3], ".exe") || strstr(argv[3], ".EXE") ) { if (strstr(argv[3], ".exe") || strstr(argv[3], ".EXE")) {
type = PACKAGE_TEXE; type = PACKAGE_TEXE;
} }

View File

@@ -5,15 +5,10 @@
* under the terms of the MIT license. See LICENSE for details. * under the terms of the MIT license. See LICENSE for details.
*/ */
enum { enum { PACKAGE_TTAR, PACKAGE_TEXE };
PACKAGE_TTAR,
PACKAGE_TEXE
};
enum { enum { PACKAGE_ESUCCESS = 0, PACKAGE_EFAILURE = -1 };
PACKAGE_ESUCCESS = 0,
PACKAGE_EFAILURE = -1
};
void package_make(const char *indir, const char *outfile, const char *exefile, int type); void package_make(const char *indir, const char *outfile, const char *exefile,
int type);
int package_run(int argc, char **argv); int package_run(int argc, char **argv);

View File

@@ -11,23 +11,25 @@
#include "palette.h" #include "palette.h"
#include "vga.h" #include "vga.h"
#define MAX_IDX 256 #define MAX_IDX 256
#define MAP_SIZE 1024 #define MAP_SIZE 1024
#define MAP_MASK (MAP_SIZE - 1) #define MAP_MASK (MAP_SIZE - 1)
struct { unsigned color; int idx; } palette_map[MAP_SIZE]; struct {
unsigned color;
int idx;
} palette_map[MAP_SIZE];
unsigned palette_palette[MAX_IDX]; unsigned palette_palette[MAX_IDX];
int palette_nextIdx; int palette_nextIdx;
int palette_inited; int palette_inited;
void palette_init(void) { void palette_init(void) {
if (palette_inited) return; if (palette_inited)
return;
palette_reset(); palette_reset();
palette_inited = 1; palette_inited = 1;
} }
void palette_reset(void) { void palette_reset(void) {
/* Reset nextIdx -- start at idx 1 as 0 is used for transparency */ /* Reset nextIdx -- start at idx 1 as 0 is used for transparency */
palette_nextIdx = 1; palette_nextIdx = 1;
@@ -38,7 +40,6 @@ void palette_reset(void) {
} }
} }
static unsigned hash(const void *data, int size) { static unsigned hash(const void *data, int size) {
unsigned hash = 5381; unsigned hash = 5381;
const unsigned char *p = data; const unsigned char *p = data;
@@ -48,12 +49,11 @@ static unsigned hash(const void *data, int size) {
return hash; return hash;
} }
int palette_colorToIdx(int r, int g, int b) { int palette_colorToIdx(int r, int g, int b) {
palette_init(); palette_init();
/* Make 24bit rgb color */ /* Make 24bit rgb color */
unsigned color = ((b & 0xff) << 16) | ((g & 0xff) << 8) | (r & 0xff); unsigned color = ((b & 0xff) << 16) | ((g & 0xff) << 8) | (r & 0xff);
/* Hash color */ /* Hash color */
unsigned h = hash(&color, sizeof(color)); unsigned h = hash(&color, sizeof(color));
@@ -69,7 +69,7 @@ int palette_colorToIdx(int r, int g, int b) {
/* Color wasn't found in hashmap -- Add to system palette and map */ /* Color wasn't found in hashmap -- Add to system palette and map */
if (palette_nextIdx >= MAX_IDX) { if (palette_nextIdx >= MAX_IDX) {
return -1; /* Return -1 for error if we've exceeded the palette capacity */ return -1; /* Return -1 for error if we've exceeded the palette capacity */
} }
int idx = palette_nextIdx++; int idx = palette_nextIdx++;
@@ -85,7 +85,6 @@ int palette_colorToIdx(int r, int g, int b) {
return idx; return idx;
} }
int palette_idxToColor(int idx, int *rgb) { int palette_idxToColor(int idx, int *rgb) {
/* Bounds check, return -1 on error */ /* Bounds check, return -1 on error */
if (idx <= 0 || idx >= MAX_IDX) { if (idx <= 0 || idx >= MAX_IDX) {
@@ -94,8 +93,8 @@ int palette_idxToColor(int idx, int *rgb) {
/* Store color in array */ /* Store color in array */
unsigned color = palette_palette[idx]; unsigned color = palette_palette[idx];
rgb[0] = (color ) & 0xff; /* r */ rgb[0] = (color)&0xff; /* r */
rgb[1] = (color >> 8) & 0xff; /* g */ rgb[1] = (color >> 8) & 0xff; /* g */
rgb[2] = (color >> 16) & 0xff; /* b */ rgb[2] = (color >> 16) & 0xff; /* b */
/* Return 0 for ok */ /* Return 0 for ok */

View File

@@ -15,6 +15,4 @@ typedef struct {
lua_Number width, height; lua_Number width, height;
} quad_t; } quad_t;
#endif #endif

View File

@@ -16,56 +16,53 @@
#include <sys/nearptr.h> #include <sys/nearptr.h>
#include "soundblaster.h" #include "soundblaster.h"
#define BYTE(val, byte) (((val) >> ((byte) * 8)) & 0xFF) #define BYTE(val, byte) (((val) >> ((byte)*8)) & 0xFF)
#define SOUNDBLASTER_SAMPLES_PER_BUFFER 2048 #define SOUNDBLASTER_SAMPLES_PER_BUFFER 2048
#define SAMPLE_BUFFER_SIZE (SOUNDBLASTER_SAMPLES_PER_BUFFER * sizeof(uint16_t) * 2) #define SAMPLE_BUFFER_SIZE \
(SOUNDBLASTER_SAMPLES_PER_BUFFER * sizeof(uint16_t) * 2)
#define SAMPLE_RATE 22050 #define SAMPLE_RATE 22050
// SB16 // SB16
#define BLASTER_RESET_PORT 0x6 #define BLASTER_RESET_PORT 0x6
#define BLASTER_READ_PORT 0xA #define BLASTER_READ_PORT 0xA
#define BLASTER_WRITE_PORT 0xC #define BLASTER_WRITE_PORT 0xC
#define BLASTER_READ_BUFFER_STATUS_PORT 0xE #define BLASTER_READ_BUFFER_STATUS_PORT 0xE
#define BLASTER_INTERRUPT_ACKNOWLEDGE_8BIT 0xE #define BLASTER_INTERRUPT_ACKNOWLEDGE_8BIT 0xE
#define BLASTER_INTERRUPT_ACKNOWLEDGE_16BIT 0xF #define BLASTER_INTERRUPT_ACKNOWLEDGE_16BIT 0xF
#define BLASTER_MIXER_OUT_PORT 0x4 #define BLASTER_MIXER_OUT_PORT 0x4
#define BLASTER_MIXER_IN_PORT 0x5 #define BLASTER_MIXER_IN_PORT 0x5
#define BLASTER_MIXER_INTERRUPT_STATUS 0x82 #define BLASTER_MIXER_INTERRUPT_STATUS 0x82
#define BLASTER_16BIT_INTERRUPT 0x02 #define BLASTER_16BIT_INTERRUPT 0x02
#define BLASTER_READ_BUFFER_STATUS_AVAIL 0x80 #define BLASTER_READ_BUFFER_STATUS_AVAIL 0x80
#define BLASTER_WRITE_BUFFER_STATUS_UNAVAIL 0x80 #define BLASTER_WRITE_BUFFER_STATUS_UNAVAIL 0x80
#define BLASTER_READY_BYTE 0xAA #define BLASTER_READY_BYTE 0xAA
#define BLASTER_SET_OUTPUT_SAMPLING_RATE 0x41 #define BLASTER_SET_OUTPUT_SAMPLING_RATE 0x41
#define BLASTER_PROGRAM_16BIT_IO_CMD 0xB0 #define BLASTER_PROGRAM_16BIT_IO_CMD 0xB0
#define BLASTER_PROGRAM_FLAG_FIFO 0x02 #define BLASTER_PROGRAM_FLAG_FIFO 0x02
#define BLASTER_PROGRAM_FLAG_AUTO_INIT 0x04 #define BLASTER_PROGRAM_FLAG_AUTO_INIT 0x04
#define BLASTER_PROGRAM_FLAG_INPUT 0x08 #define BLASTER_PROGRAM_FLAG_INPUT 0x08
#define BLASTER_PROGRAM_8BIT_IO_CMD 0xC0 #define BLASTER_PROGRAM_8BIT_IO_CMD 0xC0
#define BLASTER_PROGRAM_STEREO 0x20 #define BLASTER_PROGRAM_STEREO 0x20
#define BLASTER_PROGRAM_SIGNED 0x10 #define BLASTER_PROGRAM_SIGNED 0x10
#define BLASTER_SPEAKER_ON_CMD 0xD1 #define BLASTER_SPEAKER_ON_CMD 0xD1
#define BLASTER_SPEAKER_OFF_CMD 0xD3 #define BLASTER_SPEAKER_OFF_CMD 0xD3
#define BLASTER_EXIT_AUTO_DMA 0xD9 #define BLASTER_EXIT_AUTO_DMA 0xD9
// PIC // PIC
#define PIC1_COMMAND 0x20 #define PIC1_COMMAND 0x20
#define PIC2_COMMAND 0xA0 #define PIC2_COMMAND 0xA0
#define PIC1_DATA 0x21 #define PIC1_DATA 0x21
#define PIC2_DATA 0xA1 #define PIC2_DATA 0xA1
#define PIC_EOI 0x20 #define PIC_EOI 0x20
#define PIC_IRQ07_MAP 0x08 #define PIC_IRQ07_MAP 0x08
#define PIC_IRQ8F_MAP 0x70 #define PIC_IRQ8F_MAP 0x70
// DMA // DMA
#define DMA_DIRECTION_READ_FROM_MEMORY 0x08 #define DMA_DIRECTION_READ_FROM_MEMORY 0x08
#define DMA_TRANSFER_MODE_BLOCK 0x80 #define DMA_TRANSFER_MODE_BLOCK 0x80
static const struct {
static const struct {
uint8_t startAddressRegister; uint8_t startAddressRegister;
uint8_t countRegister; uint8_t countRegister;
uint8_t singleChannelMaskRegister; uint8_t singleChannelMaskRegister;
@@ -73,56 +70,49 @@ static const struct {
uint8_t flipFlopResetRegister; uint8_t flipFlopResetRegister;
uint8_t pageRegister; uint8_t pageRegister;
} dmaRegisters[] = { } dmaRegisters[] = {
{ 0x00, 0x01, 0x0A, 0x0B, 0x0C, 0x87 }, {0x00, 0x01, 0x0A, 0x0B, 0x0C, 0x87}, {0x02, 0x03, 0x0A, 0x0B, 0x0C, 0x83},
{ 0x02, 0x03, 0x0A, 0x0B, 0x0C, 0x83 }, {0x04, 0x05, 0x0A, 0x0B, 0x0C, 0x81}, {0x06, 0x07, 0x0A, 0x0B, 0x0C, 0x82},
{ 0x04, 0x05, 0x0A, 0x0B, 0x0C, 0x81 }, {0xC0, 0xC2, 0xD4, 0xD6, 0xD8, 0x8F}, {0xC4, 0xC6, 0xD4, 0xD6, 0xD8, 0x8B},
{ 0x06, 0x07, 0x0A, 0x0B, 0x0C, 0x82 }, {0xC8, 0xCA, 0xD4, 0xD6, 0xD8, 0x89}, {0xCC, 0xCE, 0xD4, 0xD6, 0xD8, 0x8A}};
{ 0xC0, 0xC2, 0xD4, 0xD6, 0xD8, 0x8F },
{ 0xC4, 0xC6, 0xD4, 0xD6, 0xD8, 0x8B },
{ 0xC8, 0xCA, 0xD4, 0xD6, 0xD8, 0x89 },
{ 0xCC, 0xCE, 0xD4, 0xD6, 0xD8, 0x8A }
};
static volatile int stopDma = 0; static volatile int stopDma = 0;
static uint16_t *sampleBuffer; static uint16_t *sampleBuffer;
static int sampleBufferSelector; static int sampleBufferSelector;
static uint16_t baseAddress; static uint16_t baseAddress;
static uint16_t irq; static uint16_t irq;
static uint16_t dmaChannel; static uint16_t dmaChannel;
static bool isrInstalled = false; static bool isrInstalled = false;
static int writePage = 0; static int writePage = 0;
static bool blasterInitialized = false; static bool blasterInitialized = false;
static _go32_dpmi_seginfo oldBlasterHandler, newBlasterHandler; static _go32_dpmi_seginfo oldBlasterHandler, newBlasterHandler;
static soundblaster_getSampleProc getSamples; static soundblaster_getSampleProc getSamples;
static void writeDSP(uint8_t value) { static void writeDSP(uint8_t value) {
while((inportb(baseAddress + BLASTER_WRITE_PORT) & while ((inportb(baseAddress + BLASTER_WRITE_PORT) &
BLASTER_WRITE_BUFFER_STATUS_UNAVAIL) != 0) {} BLASTER_WRITE_BUFFER_STATUS_UNAVAIL) != 0) {
}
outportb(baseAddress + BLASTER_WRITE_PORT, value); outportb(baseAddress + BLASTER_WRITE_PORT, value);
} }
static uint8_t readDSP() { static uint8_t readDSP() {
uint8_t status; uint8_t status;
while(((status = inportb(baseAddress + BLASTER_READ_BUFFER_STATUS_PORT)) while (((status = inportb(baseAddress + BLASTER_READ_BUFFER_STATUS_PORT)) &
& BLASTER_READ_BUFFER_STATUS_AVAIL) == 0) { BLASTER_READ_BUFFER_STATUS_AVAIL) == 0) {
} }
return inportb(baseAddress + BLASTER_READ_PORT); return inportb(baseAddress + BLASTER_READ_PORT);
} }
static inline void delay3us() { static inline void delay3us() {
uint64_t waited = 0; uint64_t waited = 0;
uclock_t lastTime = uclock(); uclock_t lastTime = uclock();
while(waited < (3*UCLOCKS_PER_SEC) / 1000000) { while (waited < (3 * UCLOCKS_PER_SEC) / 1000000) {
uclock_t nowTime = uclock(); uclock_t nowTime = uclock();
// Just ignore timer wraps. In the worst case we get a slightly // Just ignore timer wraps. In the worst case we get a slightly
// longer delay, but who cares? // longer delay, but who cares?
if(nowTime > lastTime) { if (nowTime > lastTime) {
waited += nowTime - lastTime; waited += nowTime - lastTime;
} }
@@ -130,33 +120,31 @@ static inline void delay3us() {
} }
} }
static int resetBlaster(void) { static int resetBlaster(void) {
for(int j = 0; j < 1000; ++j) { for (int j = 0; j < 1000; ++j) {
outportb(baseAddress + BLASTER_RESET_PORT, 1); outportb(baseAddress + BLASTER_RESET_PORT, 1);
delay3us(); delay3us();
outportb(baseAddress + BLASTER_RESET_PORT, 0); outportb(baseAddress + BLASTER_RESET_PORT, 0);
if(readDSP() == BLASTER_READY_BYTE) { if (readDSP() == BLASTER_READY_BYTE) {
return 0; return 0;
} }
} }
return SOUNDBLASTER_RESET_ERROR; return SOUNDBLASTER_RESET_ERROR;
} }
static void soundblasterISR(void) { static void soundblasterISR(void) {
outportb(baseAddress + BLASTER_MIXER_OUT_PORT, outportb(baseAddress + BLASTER_MIXER_OUT_PORT,
BLASTER_MIXER_INTERRUPT_STATUS); BLASTER_MIXER_INTERRUPT_STATUS);
uint8_t status = inportb(baseAddress + BLASTER_MIXER_IN_PORT); uint8_t status = inportb(baseAddress + BLASTER_MIXER_IN_PORT);
if(status & BLASTER_16BIT_INTERRUPT) { if (status & BLASTER_16BIT_INTERRUPT) {
if(stopDma == 1) { if (stopDma == 1) {
writeDSP(BLASTER_EXIT_AUTO_DMA); writeDSP(BLASTER_EXIT_AUTO_DMA);
stopDma = 2; stopDma = 2;
} else { } else {
uint8_t* dst = (uint8_t*)(sampleBuffer) uint8_t *dst =
+ writePage * SAMPLE_BUFFER_SIZE / 2; (uint8_t *)(sampleBuffer) + writePage * SAMPLE_BUFFER_SIZE / 2;
memcpy(dst, getSamples(), SAMPLE_BUFFER_SIZE / 2); memcpy(dst, getSamples(), SAMPLE_BUFFER_SIZE / 2);
@@ -165,78 +153,77 @@ static void soundblasterISR(void) {
} }
} }
if(irq >= 8) { if (irq >= 8) {
outportb(PIC2_COMMAND, PIC_EOI); outportb(PIC2_COMMAND, PIC_EOI);
} }
outportb(PIC1_COMMAND, PIC_EOI); outportb(PIC1_COMMAND, PIC_EOI);
} }
static void setBlasterISR(void) { static void setBlasterISR(void) {
// Map IRQ to interrupt number on the CPU // Map IRQ to interrupt number on the CPU
uint16_t interruptVector = irq + irq + (irq < 8) uint16_t interruptVector =
? PIC_IRQ07_MAP irq + irq + (irq < 8) ? PIC_IRQ07_MAP : PIC_IRQ8F_MAP;
: PIC_IRQ8F_MAP;
_go32_dpmi_get_protected_mode_interrupt_vector(interruptVector, _go32_dpmi_get_protected_mode_interrupt_vector(interruptVector,
&oldBlasterHandler); &oldBlasterHandler);
newBlasterHandler.pm_offset = (int)soundblasterISR; newBlasterHandler.pm_offset = (int)soundblasterISR;
newBlasterHandler.pm_selector = _go32_my_cs(); newBlasterHandler.pm_selector = _go32_my_cs();
_go32_dpmi_chain_protected_mode_interrupt_vector(interruptVector, &newBlasterHandler); _go32_dpmi_chain_protected_mode_interrupt_vector(interruptVector,
&newBlasterHandler);
// PIC: unmask SB IRQ // PIC: unmask SB IRQ
if(irq < 8) { if (irq < 8) {
uint8_t irqmask = inportb(PIC1_DATA); uint8_t irqmask = inportb(PIC1_DATA);
outportb(PIC1_DATA, irqmask & ~(1<<irq)); outportb(PIC1_DATA, irqmask & ~(1 << irq));
} else { } else {
uint8_t irqmask = inportb(PIC2_DATA); uint8_t irqmask = inportb(PIC2_DATA);
outportb(PIC2_DATA, irqmask & ~(1<<(irq-8))); outportb(PIC2_DATA, irqmask & ~(1 << (irq - 8)));
} }
isrInstalled = true; isrInstalled = true;
} }
static int parseBlasterSettings(void) { static int parseBlasterSettings(void) {
char const* blasterEnv = getenv("BLASTER"); char const *blasterEnv = getenv("BLASTER");
if(blasterEnv == 0) { if (blasterEnv == 0) {
return SOUNDBLASTER_ENV_NOT_SET; return SOUNDBLASTER_ENV_NOT_SET;
} }
int res = sscanf(blasterEnv, "A%hx I%hu", &baseAddress, &irq); int res = sscanf(blasterEnv, "A%hx I%hu", &baseAddress, &irq);
if(res < 2) { if (res < 2) {
return SOUNDBLASTER_ENV_INVALID; return SOUNDBLASTER_ENV_INVALID;
} }
// "H" field may be preceeded by any number of other fields, so let's just search it // "H" field may be preceeded by any number of other fields, so let's just
// search it
char const *dmaLoc = strchr(blasterEnv, 'H'); char const *dmaLoc = strchr(blasterEnv, 'H');
if(dmaLoc == NULL) { if (dmaLoc == NULL) {
return SOUNDBLASTER_ENV_INVALID; return SOUNDBLASTER_ENV_INVALID;
} }
dmaChannel = atoi(dmaLoc+1); dmaChannel = atoi(dmaLoc + 1);
return 0; return 0;
} }
static int allocSampleBuffer(void) { static int allocSampleBuffer(void) {
static int maxRetries = 10; static int maxRetries = 10;
int selectors[maxRetries]; int selectors[maxRetries];
int current; int current;
for(current = 0; current < maxRetries; ++current) { for (current = 0; current < maxRetries; ++current) {
int segment = __dpmi_allocate_dos_memory((SAMPLE_BUFFER_SIZE+15)>>4, &selectors[current]); int segment = __dpmi_allocate_dos_memory((SAMPLE_BUFFER_SIZE + 15) >> 4,
if(segment == -1) { &selectors[current]);
if (segment == -1) {
break; break;
} }
uint32_t bufferPhys = __djgpp_conventional_base + segment * 16; uint32_t bufferPhys = __djgpp_conventional_base + segment * 16;
// The DMA buffer must not cross a 64k boundary // The DMA buffer must not cross a 64k boundary
if(bufferPhys % 0x10000 < 0x10000 - SAMPLE_BUFFER_SIZE) { if (bufferPhys % 0x10000 < 0x10000 - SAMPLE_BUFFER_SIZE) {
sampleBuffer = (uint16_t*)bufferPhys; sampleBuffer = (uint16_t *)bufferPhys;
memset(sampleBuffer, 0, SAMPLE_BUFFER_SIZE); memset(sampleBuffer, 0, SAMPLE_BUFFER_SIZE);
sampleBufferSelector = selectors[current]; sampleBufferSelector = selectors[current];
--current; --current;
@@ -245,41 +232,27 @@ static int allocSampleBuffer(void) {
} }
// Free misaligned buffers // Free misaligned buffers
for(; current > 0; --current) { for (; current > 0; --current) {
__dpmi_free_dos_memory(selectors[current]); __dpmi_free_dos_memory(selectors[current]);
} }
if(sampleBuffer == NULL) { if (sampleBuffer == NULL) {
return SOUNDBLASTER_ALLOC_ERROR; return SOUNDBLASTER_ALLOC_ERROR;
} }
return 0; return 0;
} }
static void turnSpeakerOn(void) { writeDSP(BLASTER_SPEAKER_ON_CMD); }
static void turnSpeakerOn(void) { static void turnSpeakerOff(void) { writeDSP(BLASTER_SPEAKER_OFF_CMD); }
writeDSP(BLASTER_SPEAKER_ON_CMD);
}
static void dmaSetupTransfer(int channel, uint8_t direction, bool autoReload,
static void turnSpeakerOff(void) { bool down, uint8_t mode, uint32_t startAddress,
writeDSP(BLASTER_SPEAKER_OFF_CMD);
}
static void dmaSetupTransfer(int channel,
uint8_t direction,
bool autoReload,
bool down,
uint8_t mode,
uint32_t startAddress,
uint32_t count) { uint32_t count) {
uint8_t modeByte = direction uint8_t modeByte = direction | mode | ((uint8_t)autoReload << 4) |
| mode ((uint8_t)down << 5) | (channel & 0x03);
| ((uint8_t)autoReload << 4)
| ((uint8_t)down << 5)
| (channel & 0x03);
uint8_t maskEnable = (channel & 0x03) | 0x04; uint8_t maskEnable = (channel & 0x03) | 0x04;
@@ -288,7 +261,7 @@ static void dmaSetupTransfer(int channel,
// Special handling of 16 bit DMA channels: // Special handling of 16 bit DMA channels:
// The DMA controller needs offset and count to be half the actual value and // The DMA controller needs offset and count to be half the actual value and
// internally doubles it again // internally doubles it again
if(channel > 3) { if (channel > 3) {
offset >>= 1; offset >>= 1;
count >>= 1; count >>= 1;
} }
@@ -296,17 +269,16 @@ static void dmaSetupTransfer(int channel,
uint8_t page = BYTE(startAddress, 2); uint8_t page = BYTE(startAddress, 2);
outportb(dmaRegisters[channel].singleChannelMaskRegister, maskEnable); outportb(dmaRegisters[channel].singleChannelMaskRegister, maskEnable);
outportb(dmaRegisters[channel].flipFlopResetRegister, 0x00); outportb(dmaRegisters[channel].flipFlopResetRegister, 0x00);
outportb(dmaRegisters[channel].modeRegister, modeByte); outportb(dmaRegisters[channel].modeRegister, modeByte);
outportb(dmaRegisters[channel].startAddressRegister, BYTE(offset, 0)); outportb(dmaRegisters[channel].startAddressRegister, BYTE(offset, 0));
outportb(dmaRegisters[channel].startAddressRegister, BYTE(offset, 1)); outportb(dmaRegisters[channel].startAddressRegister, BYTE(offset, 1));
outportb(dmaRegisters[channel].countRegister, BYTE(count-1, 0)); outportb(dmaRegisters[channel].countRegister, BYTE(count - 1, 0));
outportb(dmaRegisters[channel].countRegister, BYTE(count-1, 1)); outportb(dmaRegisters[channel].countRegister, BYTE(count - 1, 1));
outportb(dmaRegisters[channel].pageRegister, page); outportb(dmaRegisters[channel].pageRegister, page);
outportb(dmaRegisters[channel].singleChannelMaskRegister, maskEnable & 0x03); outportb(dmaRegisters[channel].singleChannelMaskRegister, maskEnable & 0x03);
} }
static void startDMAOutput(void) { static void startDMAOutput(void) {
uint32_t offset = ((uint32_t)sampleBuffer) - __djgpp_conventional_base; uint32_t offset = ((uint32_t)sampleBuffer) - __djgpp_conventional_base;
@@ -319,35 +291,34 @@ static void startDMAOutput(void) {
writeDSP(BLASTER_SET_OUTPUT_SAMPLING_RATE); writeDSP(BLASTER_SET_OUTPUT_SAMPLING_RATE);
writeDSP(BYTE(SAMPLE_RATE, 1)); writeDSP(BYTE(SAMPLE_RATE, 1));
writeDSP(BYTE(SAMPLE_RATE, 0)); writeDSP(BYTE(SAMPLE_RATE, 0));
writeDSP(BLASTER_PROGRAM_16BIT_IO_CMD writeDSP(BLASTER_PROGRAM_16BIT_IO_CMD | BLASTER_PROGRAM_FLAG_AUTO_INIT |
| BLASTER_PROGRAM_FLAG_AUTO_INIT BLASTER_PROGRAM_FLAG_FIFO);
| BLASTER_PROGRAM_FLAG_FIFO);
writeDSP(BLASTER_PROGRAM_SIGNED); writeDSP(BLASTER_PROGRAM_SIGNED);
writeDSP(BYTE(samples/2-1, 0)); writeDSP(BYTE(samples / 2 - 1, 0));
writeDSP(BYTE(samples/2-1, 1)); writeDSP(BYTE(samples / 2 - 1, 1));
} }
int soundblaster_init(soundblaster_getSampleProc getsamplesproc) { int soundblaster_init(soundblaster_getSampleProc getsamplesproc) {
if(!__djgpp_nearptr_enable()) { if (!__djgpp_nearptr_enable()) {
return SOUNDBLASTER_DOS_ERROR; return SOUNDBLASTER_DOS_ERROR;
} }
int err = parseBlasterSettings(); int err = parseBlasterSettings();
if(err != 0) { if (err != 0) {
fprintf(stderr, "BLASTER environment variable not set or invalid\n"); fprintf(stderr, "BLASTER environment variable not set or invalid\n");
return err; return err;
} }
err = resetBlaster(); err = resetBlaster();
if(err != 0) { if (err != 0) {
fprintf(stderr, "Could not reset Soundblaster\n"); fprintf(stderr, "Could not reset Soundblaster\n");
return err; return err;
} }
err = allocSampleBuffer(); err = allocSampleBuffer();
if(err != 0) { if (err != 0) {
fprintf(stderr, "Could not allocate sample buffer in conventional memory\n"); fprintf(stderr,
"Could not allocate sample buffer in conventional memory\n");
return err; return err;
} }
@@ -362,32 +333,29 @@ int soundblaster_init(soundblaster_getSampleProc getsamplesproc) {
return 0; return 0;
} }
static void deallocSampleBuffer(void) { static void deallocSampleBuffer(void) {
__dpmi_free_dos_memory(sampleBufferSelector); __dpmi_free_dos_memory(sampleBufferSelector);
} }
static void resetBlasterISR(void) { static void resetBlasterISR(void) {
if(isrInstalled) { if (isrInstalled) {
uint16_t interruptVector = irq + irq + (irq < 8) uint16_t interruptVector =
? PIC_IRQ07_MAP irq + irq + (irq < 8) ? PIC_IRQ07_MAP : PIC_IRQ8F_MAP;
: PIC_IRQ8F_MAP;
_go32_dpmi_set_protected_mode_interrupt_vector(interruptVector, &oldBlasterHandler); _go32_dpmi_set_protected_mode_interrupt_vector(interruptVector,
&oldBlasterHandler);
isrInstalled = false; isrInstalled = false;
} }
} }
static void stopDMAOutput(void) { static void stopDMAOutput(void) {
stopDma = 1; stopDma = 1;
while(stopDma == 1) {} while (stopDma == 1) {
}
} }
void soundblaster_deinit(void) { void soundblaster_deinit(void) {
if(blasterInitialized) { if (blasterInitialized) {
turnSpeakerOff(); turnSpeakerOff();
stopDMAOutput(); stopDMAOutput();
resetBlaster(); resetBlaster();
@@ -397,11 +365,7 @@ void soundblaster_deinit(void) {
} }
} }
int soundblaster_getSampleRate(void) { return SAMPLE_RATE; }
int soundblaster_getSampleRate(void) {
return SAMPLE_RATE;
}
int soundblaster_getSampleBufferSize(void) { int soundblaster_getSampleBufferSize(void) {
return SOUNDBLASTER_SAMPLES_PER_BUFFER; return SOUNDBLASTER_SAMPLES_PER_BUFFER;

View File

@@ -13,13 +13,13 @@
// Error codes // Error codes
#define SOUNDBLASTER_ENV_NOT_SET 1 #define SOUNDBLASTER_ENV_NOT_SET 1
#define SOUNDBLASTER_ENV_INVALID 2 #define SOUNDBLASTER_ENV_INVALID 2
#define SOUNDBLASTER_DOS_ERROR 3 #define SOUNDBLASTER_DOS_ERROR 3
#define SOUNDBLASTER_RESET_ERROR 4 #define SOUNDBLASTER_RESET_ERROR 4
#define SOUNDBLASTER_ALLOC_ERROR 5 #define SOUNDBLASTER_ALLOC_ERROR 5
#define SOUNDBLASTER_SAMPLES_PER_BUFFER 2048 #define SOUNDBLASTER_SAMPLES_PER_BUFFER 2048
typedef int16_t const* (*soundblaster_getSampleProc)(void); typedef int16_t const *(*soundblaster_getSampleProc)(void);
int soundblaster_init(soundblaster_getSampleProc sampleproc); int soundblaster_init(soundblaster_getSampleProc sampleproc);
void soundblaster_deinit(void); void soundblaster_deinit(void);

View File

@@ -15,25 +15,24 @@
int vga_inited = 0; int vga_inited = 0;
void vga_init(void) { void vga_init(void) {
if (vga_inited) return; if (vga_inited)
return;
vga_inited = 1; vga_inited = 1;
union REGS regs = {}; union REGS regs = {};
regs.h.al = 0x13; regs.h.al = 0x13;
int86(0x10, &regs, &regs); int86(0x10, &regs, &regs);
} }
void vga_deinit(void) { void vga_deinit(void) {
if (!vga_inited) return; if (!vga_inited)
return;
vga_inited = 0; vga_inited = 0;
union REGS regs = {}; union REGS regs = {};
regs.h.al = 0x3; regs.h.al = 0x3;
int86(0x10, &regs, &regs); int86(0x10, &regs, &regs);
} }
void vga_setPalette(int idx, int r, int g, int b) { void vga_setPalette(int idx, int r, int g, int b) {
outp(0x03c8, idx); outp(0x03c8, idx);
outp(0x03c9, (r >> 2) & 0x3f); outp(0x03c9, (r >> 2) & 0x3f);
@@ -41,7 +40,6 @@ void vga_setPalette(int idx, int r, int g, int b) {
outp(0x03c9, (b >> 2) & 0x3f); outp(0x03c9, (b >> 2) & 0x3f);
} }
void vga_update(pixel_t *buffer) { void vga_update(pixel_t *buffer) {
dosmemput(buffer, VGA_WIDTH * VGA_HEIGHT, 0xa0000); dosmemput(buffer, VGA_WIDTH * VGA_HEIGHT, 0xa0000);
} }

View File

@@ -8,8 +8,8 @@
#ifndef VGA_H #ifndef VGA_H
#define VGA_H #define VGA_H
#define VGA_WIDTH 320 #define VGA_WIDTH 320
#define VGA_HEIGHT 200 #define VGA_HEIGHT 200
typedef unsigned char pixel_t; typedef unsigned char pixel_t;