summaryrefslogtreecommitdiff
path: root/src/sys
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2017-05-26 21:51:04 -0700
committerVito Caputo <vcaputo@pengaru.com>2017-05-26 22:48:09 -0700
commit78f8fce7f286fd0c71774e2567404ed51f24fef3 (patch)
treef3de4987f7a9fc1bc03331e97b65a851b041051a /src/sys
*: initial commit of stripped schism stuff
Forking schism tracker's IT playback stuff into a little playback library for embedding in demos.
Diffstat (limited to 'src/sys')
-rw-r--r--src/sys/alsa/init.c73
-rw-r--r--src/sys/alsa/midi-alsa.c481
-rw-r--r--src/sys/alsa/volume-alsa.c237
-rw-r--r--src/sys/fd.org/autopackage.apspec57
-rw-r--r--src/sys/fd.org/itf.desktop11
-rw-r--r--src/sys/fd.org/schism.desktop18
-rw-r--r--src/sys/macosx/Schism_Tracker.app/Contents/Info.plist112
-rw-r--r--src/sys/macosx/Schism_Tracker.app/Contents/PkgInfo1
-rw-r--r--src/sys/macosx/Schism_Tracker.app/Contents/Resources/AppSettings.plist18
-rw-r--r--src/sys/macosx/Schism_Tracker.app/Contents/Resources/appIcon.icnsbin0 -> 52550 bytes
-rw-r--r--src/sys/macosx/Schism_Tracker.app/Contents/Resources/moduleIcon.icnsbin0 -> 58109 bytes
-rw-r--r--src/sys/macosx/ibook-support.c103
-rw-r--r--src/sys/macosx/macosx-sdlmain.m619
-rw-r--r--src/sys/macosx/midi-macosx.c222
-rw-r--r--src/sys/macosx/osdefs.c54
-rw-r--r--src/sys/macosx/volume-macosx.c119
-rw-r--r--src/sys/oss/midi-oss.c177
-rw-r--r--src/sys/oss/volume-oss.c126
-rw-r--r--src/sys/posix/slurp-mmap.c68
-rw-r--r--src/sys/sdl/README2
-rw-r--r--src/sys/stdlib/asprintf.c34
-rw-r--r--src/sys/stdlib/memcmp.c12
-rw-r--r--src/sys/stdlib/mkstemp.c104
-rw-r--r--src/sys/stdlib/strptime.c396
-rw-r--r--src/sys/stdlib/vasprintf.c97
-rw-r--r--src/sys/wii/certs_bin.h163
-rw-r--r--src/sys/wii/data/certs.binbin0 -> 2560 bytes
-rw-r--r--src/sys/wii/data/su_tik.binbin0 -> 676 bytes
-rw-r--r--src/sys/wii/data/su_tmd.binbin0 -> 520 bytes
-rw-r--r--src/sys/wii/isfs.c445
-rw-r--r--src/sys/wii/isfs.h40
-rw-r--r--src/sys/wii/osdefs.c284
-rw-r--r--src/sys/wii/schismtracker/icon.pngbin0 -> 13920 bytes
-rw-r--r--src/sys/wii/schismtracker/meta.xml10
-rw-r--r--src/sys/wii/su_tik_bin.h46
-rw-r--r--src/sys/wii/su_tmd_bin.h36
-rw-r--r--src/sys/win32/filetype.c35
-rw-r--r--src/sys/win32/localtime_r.c53
-rw-r--r--src/sys/win32/midi-win32mm.c311
-rw-r--r--src/sys/win32/osdefs.c198
-rw-r--r--src/sys/win32/schism.nsis75
-rw-r--r--src/sys/win32/schismres.rc45
-rw-r--r--src/sys/win32/slurp-win32.c102
-rw-r--r--src/sys/win32/volume-win32mm.c91
-rw-r--r--src/sys/win32/wine-ddraw.h2679
-rw-r--r--src/sys/x11/xkb.c129
-rw-r--r--src/sys/x11/xscreensaver.c175
-rw-r--r--src/sys/x11/xv.c139
48 files changed, 8197 insertions, 0 deletions
diff --git a/src/sys/alsa/init.c b/src/sys/alsa/init.c
new file mode 100644
index 0000000..88a0d87
--- /dev/null
+++ b/src/sys/alsa/init.c
@@ -0,0 +1,73 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* Here be demons. */
+
+#include "headers.h"
+#include "util.h"
+#include "osdefs.h"
+
+#if defined(USE_DLTRICK_ALSA)
+# include <dlfcn.h>
+void *_dltrick_handle = NULL;
+static void *_alsaless_sdl_hack = NULL;
+#else
+# error You are in a maze of twisty little passages, all alike.
+#endif
+
+/* --------------------------------------------------------------------- */
+
+void alsa_dlinit(void)
+{
+ /* okay, this is how this works:
+ * to operate the alsa mixer and alsa midi, we need functions in
+ * libasound.so.2 -- if we can do that, *AND* libSDL has the
+ * ALSA_bootstrap routine- then SDL was built with alsa-support-
+ * which means schism can probably use ALSA - so we set that as the
+ * default here.
+ */
+ _dltrick_handle = dlopen("libasound.so.2", RTLD_NOW);
+ if (!_dltrick_handle)
+ _dltrick_handle = dlopen("libasound.so", RTLD_NOW);
+ if (!getenv("SDL_AUDIODRIVER")) {
+ _alsaless_sdl_hack = dlopen("libSDL-1.2.so.0", RTLD_NOW);
+ if (!_alsaless_sdl_hack)
+ _alsaless_sdl_hack = RTLD_DEFAULT;
+
+#if 0
+ if (_dltrick_handle && _alsaless_sdl_hack
+ && (dlsym(_alsaless_sdl_hack, "ALSA_bootstrap")
+ || dlsym(_alsaless_sdl_hack, "snd_pcm_open"))) {
+ static int (*alsa_snd_pcm_open)(void **pcm,
+ const char *name,
+ int stream,
+ int mode);
+ static int (*alsa_snd_pcm_close)(void *pcm);
+
+ alsa_snd_pcm_open = dlsym(_dltrick_handle, "snd_pcm_open");
+ alsa_snd_pcm_close = dlsym(_dltrick_handle, "snd_pcm_close");
+ }
+#endif
+ }
+}
+
diff --git a/src/sys/alsa/midi-alsa.c b/src/sys/alsa/midi-alsa.c
new file mode 100644
index 0000000..9314939
--- /dev/null
+++ b/src/sys/alsa/midi-alsa.c
@@ -0,0 +1,481 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "headers.h"
+
+#include "it.h"
+#include "midi.h"
+
+#include "util.h"
+
+#ifdef USE_ALSA
+#include <sys/poll.h>
+
+#include <alsa/asoundlib.h>
+#ifdef USE_DLTRICK_ALSA
+/* ... */
+#include <alsa/control.h>
+#endif
+#include <alsa/seq.h>
+
+#include <sys/stat.h>
+
+
+
+#define PORT_NAME "Schism Tracker"
+
+
+static snd_seq_t *seq;
+static int local_port = -1;
+
+#define MIDI_BUFSIZE 65536
+static unsigned char big_midi_buf[MIDI_BUFSIZE];
+static int alsa_queue;
+
+struct alsa_midi {
+ int c, p;
+ const char *client;
+ const char *port;
+ snd_midi_event_t *dev;
+ int mark;
+};
+
+/* okay, we do the same trick SDL does to get our alsa library put together */
+#ifdef USE_DLTRICK_ALSA
+/* alright, some explanation:
+
+The libSDL library on Linux doesn't "link with" the alsa library (-lasound)
+so that dynamically-linked binaries using libSDL on Linux will work on systems
+that don't have libasound.so.2 anywhere.
+
+There DO EXIST generic solutions (relaytool) but they interact poorly with what
+SDL is doing, so here is my ad-hoc solution:
+
+We define a bunch of these routines similar to how the dynamic linker does it
+when RTLD_LAZY is used. There might be a slight performance increase if we
+linked them all at once (like libSDL does), but this is certainly a lot easier
+to inline.
+
+If you need additional functions in -lasound in schism, presently they will
+have to be declared here for my binary builds to work.
+
+to use:
+ size_t snd_seq_port_info_sizeof(void);
+
+add here:
+ _any_dltrick(size_t,snd_seq_port_info_sizeof,(void),())
+
+(okay, that one is already done). Here's another one:
+
+ int snd_mixer_selem_get_playback_volume(snd_mixer_elem_t *e,
+ snd_mixer_selem_channel_id_t ch,
+ long *v);
+
+gets:
+ _any_dltrick(int,snd_mixer_selem_get_playback_volume,
+ (snd_mixer_elem_t*e,snd_mixer_selem_channel_id_t ch,long*v),(e,ch,v))
+
+If they return void, like:
+ void snd_midi_event_reset_decode(snd_midi_event_t *d);
+use:
+ _void_dltrick(snd_midi_event_reset_decode,(snd_midi_event_t*d),(d))
+
+None of this code is used, btw, if --enable-alsadltrick isn't supplied to
+the configure script, so to test it, you should use that when developing.
+
+Editor's note: currently there's an explicit directive for the build to fail if
+USE_DLTRICK_ALSA isn't defined. Doesn't say why.
+*/
+
+
+#include <dlfcn.h>
+
+extern void *_dltrick_handle;
+
+/* don't try this at home... */
+#define _void_dltrick(a,b,c) static void (*_dltrick_ ## a)b = NULL; \
+void a b { if (!_dltrick_##a) _dltrick_##a = dlsym(_dltrick_handle, #a); \
+if (!_dltrick_##a) abort(); _dltrick_ ## a c; }
+
+#define _any_dltrick(r,a,b,c) static r (*_dltrick_ ## a)b = NULL; \
+r a b { if (!_dltrick_##a) _dltrick_##a = dlsym(_dltrick_handle, #a); \
+if (!_dltrick_##a) abort(); return _dltrick_ ## a c; }
+
+
+_any_dltrick(size_t,snd_seq_port_info_sizeof,(void),())
+_any_dltrick(size_t,snd_seq_client_info_sizeof,(void),())
+
+_any_dltrick(int,snd_seq_control_queue,(snd_seq_t*s,int q,int type, int value, snd_seq_event_t *ev),
+ (s,q,type,value,ev))
+
+_any_dltrick(int,snd_seq_queue_tempo_malloc,(snd_seq_queue_tempo_t**ptr),(ptr))
+_void_dltrick(snd_seq_queue_tempo_set_tempo,(snd_seq_queue_tempo_t *info, unsigned int tempo),(info,tempo))
+_void_dltrick(snd_seq_queue_tempo_set_ppq,(snd_seq_queue_tempo_t *info, int ppq),(info,ppq))
+_any_dltrick(int,snd_seq_set_queue_tempo,(snd_seq_t *handle, int q, snd_seq_queue_tempo_t *tempo),
+ (handle,q,tempo))
+_any_dltrick(long,snd_midi_event_encode,
+(snd_midi_event_t *dev,const unsigned char *buf,long count,snd_seq_event_t *ev),
+(dev,buf,count,ev))
+_any_dltrick(int,snd_seq_event_output,
+(snd_seq_t *handle, snd_seq_event_t *ev),
+(handle,ev))
+_any_dltrick(int,snd_seq_alloc_queue,(snd_seq_t*h),(h))
+_any_dltrick(int,snd_seq_free_event,
+(snd_seq_event_t *ev),
+(ev))
+_any_dltrick(int,snd_seq_connect_from,
+(snd_seq_t*seeq,int my_port,int src_client, int src_port),
+(seeq,my_port,src_client,src_port))
+_any_dltrick(int,snd_seq_connect_to,
+(snd_seq_t*seeq,int my_port,int dest_client,int dest_port),
+(seeq,my_port,dest_client,dest_port))
+_any_dltrick(int,snd_seq_disconnect_from,
+(snd_seq_t*seeq,int my_port,int src_client, int src_port),
+(seeq,my_port,src_client,src_port))
+_any_dltrick(int,snd_seq_disconnect_to,
+(snd_seq_t*seeq,int my_port,int dest_client,int dest_port),
+(seeq,my_port,dest_client,dest_port))
+_any_dltrick(const char *,snd_strerror,(int errnum),(errnum))
+_any_dltrick(int,snd_seq_poll_descriptors_count,(snd_seq_t*h,short e),(h,e))
+_any_dltrick(int,snd_seq_poll_descriptors,(snd_seq_t*h,struct pollfd*pfds,unsigned int space, short e),
+ (h,pfds,space,e))
+_any_dltrick(int,snd_seq_event_input,(snd_seq_t*h,snd_seq_event_t**ev),(h,ev))
+_any_dltrick(int,snd_seq_event_input_pending,(snd_seq_t*h,int fs),(h,fs))
+_any_dltrick(int,snd_midi_event_new,(size_t s,snd_midi_event_t **rd),(s,rd))
+_any_dltrick(long,snd_midi_event_decode,
+(snd_midi_event_t *dev,unsigned char *buf,long count, const snd_seq_event_t*ev),
+(dev,buf,count,ev))
+_void_dltrick(snd_midi_event_reset_decode,(snd_midi_event_t*d),(d))
+_any_dltrick(int,snd_seq_create_simple_port,
+(snd_seq_t*h,const char *name,unsigned int caps,unsigned int type),
+(h,name,caps,type))
+_any_dltrick(int,snd_seq_drain_output,(snd_seq_t*h),(h))
+_any_dltrick(int,snd_seq_query_next_client,
+(snd_seq_t*h,snd_seq_client_info_t*info),(h,info))
+_any_dltrick(int,snd_seq_client_info_get_client,
+(const snd_seq_client_info_t *info),(info))
+_void_dltrick(snd_seq_client_info_set_client,(snd_seq_client_info_t*inf,int cl),(inf,cl))
+_void_dltrick(snd_seq_port_info_set_client,(snd_seq_port_info_t*inf,int cl),(inf,cl))
+_void_dltrick(snd_seq_port_info_set_port,(snd_seq_port_info_t*inf,int pl),(inf,pl))
+_any_dltrick(int,snd_seq_query_next_port,(snd_seq_t*h,snd_seq_port_info_t*inf),(h,inf))
+_any_dltrick(unsigned int,snd_seq_port_info_get_capability,
+(const snd_seq_port_info_t *inf),(inf))
+_any_dltrick(int,snd_seq_port_info_get_client,(const snd_seq_port_info_t*inf),(inf))
+_any_dltrick(int,snd_seq_port_info_get_port,(const snd_seq_port_info_t*inf),(inf))
+_any_dltrick(const char *,snd_seq_client_info_get_name,(snd_seq_client_info_t*inf),(inf))
+_any_dltrick(const char *,snd_seq_port_info_get_name,(const snd_seq_port_info_t*inf),(inf))
+_any_dltrick(int,snd_seq_open,(snd_seq_t**h,const char *name,int str, int mode),
+(h,name,str,mode))
+_any_dltrick(int,snd_seq_set_client_name,(snd_seq_t*seeq,const char *name),(seeq,name))
+#endif
+
+/* see mixer-alsa.c */
+#undef assert
+#define assert(x)
+
+static void _alsa_drain(struct midi_port *p UNUSED)
+{
+ /* not port specific */
+ snd_seq_drain_output(seq);
+}
+static void _alsa_send(struct midi_port *p, const unsigned char *data, unsigned int len, unsigned int delay)
+{
+ struct alsa_midi *ex;
+ snd_seq_event_t ev;
+ long rr;
+
+ ex = (struct alsa_midi *)p->userdata;
+
+ while (len > 0) {
+ snd_seq_ev_clear(&ev);
+ snd_seq_ev_set_source(&ev, local_port);
+ snd_seq_ev_set_subs(&ev);
+ if (!delay) {
+ snd_seq_ev_set_direct(&ev);
+ } else {
+ snd_seq_ev_schedule_tick(&ev, alsa_queue, 1, delay);
+ }
+
+ /* we handle our own */
+ ev.dest.port = ex->p;
+ ev.dest.client = ex->c;
+
+ rr = snd_midi_event_encode(ex->dev, data, len, &ev);
+ if (rr < 1) break;
+ snd_seq_event_output(seq, &ev);
+ snd_seq_free_event(&ev);
+ data += rr;
+ len -= rr;
+ }
+}
+static int _alsa_start(struct midi_port *p)
+{
+ struct alsa_midi *data;
+ int err;
+
+ err = 0;
+ data = (struct alsa_midi *)p->userdata;
+ if (p->io & MIDI_INPUT) {
+ err = snd_seq_connect_from(seq, 0, data->c, data->p);
+ }
+ if (p->io & MIDI_OUTPUT) {
+ err = snd_seq_connect_to(seq, 0, data->c, data->p);
+ }
+ if (err < 0) {
+ log_appendf(4, "ALSA: %s", snd_strerror(err));
+ return 0;
+ }
+ return 1;
+}
+static int _alsa_stop(struct midi_port *p)
+{
+ struct alsa_midi *data;
+ int err;
+
+ err = 0;
+ data = (struct alsa_midi *)p->userdata;
+ if (p->io & MIDI_OUTPUT) {
+ err = snd_seq_disconnect_to(seq, 0, data->c, data->p);
+ }
+ if (p->io & MIDI_INPUT) {
+ err = snd_seq_disconnect_from(seq, 0, data->c, data->p);
+ }
+ if (err < 0) {
+ log_appendf(4, "ALSA: %s", snd_strerror(err));
+ return 0;
+ }
+ return 1;
+}
+static int _alsa_thread(struct midi_provider *p)
+{
+ int npfd;
+ struct pollfd *pfd;
+ struct midi_port *ptr, *src;
+ struct alsa_midi *data;
+ static snd_midi_event_t *dev = NULL;
+ snd_seq_event_t *ev;
+ long s;
+
+ npfd = snd_seq_poll_descriptors_count(seq, POLLIN);
+ if (npfd <= 0) return 0;
+
+ pfd = (struct pollfd *)mem_alloc(npfd * sizeof(struct pollfd));
+ if (!pfd) return 0;
+
+ for (;;) {
+ if (snd_seq_poll_descriptors(seq, pfd, npfd, POLLIN) != npfd) {
+ free(pfd);
+ return 0;
+ }
+
+ (void)poll(pfd, npfd, -1);
+ do {
+ if (snd_seq_event_input(seq, &ev) < 0) {
+ break;
+ }
+ if (!ev) continue;
+
+ ptr = src = NULL;
+ while (midi_port_foreach(p, &ptr)) {
+ data = (struct alsa_midi *)ptr->userdata;
+ if (ev->source.client == data->c
+ && ev->source.port == data->p
+ && (ptr->io & MIDI_INPUT)) {
+ src = ptr;
+ }
+ }
+ if (!src || !ev) {
+ snd_seq_free_event(ev);
+ continue;
+ }
+
+ if (!dev && snd_midi_event_new(sizeof(big_midi_buf), &dev) < 0) {
+ /* err... */
+ break;
+ }
+
+ s = snd_midi_event_decode(dev, big_midi_buf,
+ sizeof(big_midi_buf), ev);
+ if (s > 0) midi_received_cb(src, big_midi_buf, s);
+ snd_midi_event_reset_decode(dev);
+ snd_seq_free_event(ev);
+ } while (snd_seq_event_input_pending(seq, 0) > 0);
+// snd_seq_drain_output(seq);
+ }
+ return 0;
+}
+static void _alsa_poll(struct midi_provider *_alsa_provider)
+{
+ struct midi_port *ptr;
+ struct alsa_midi *data;
+ char *buffer;
+ int c, p, ok, io;
+ const char *ctext, *ptext;
+
+ snd_seq_client_info_t *cinfo;
+ snd_seq_port_info_t *pinfo;
+
+ if (local_port == -1) {
+
+ local_port = snd_seq_create_simple_port(seq,
+ PORT_NAME,
+ SND_SEQ_PORT_CAP_READ
+ | SND_SEQ_PORT_CAP_WRITE
+ | SND_SEQ_PORT_CAP_SYNC_READ
+ | SND_SEQ_PORT_CAP_SYNC_WRITE
+ | SND_SEQ_PORT_CAP_DUPLEX
+ | SND_SEQ_PORT_CAP_SUBS_READ
+ | SND_SEQ_PORT_CAP_SUBS_WRITE,
+
+ SND_SEQ_PORT_TYPE_APPLICATION
+ | SND_SEQ_PORT_TYPE_SYNTH
+ | SND_SEQ_PORT_TYPE_MIDI_GENERIC
+ | SND_SEQ_PORT_TYPE_MIDI_GM
+ | SND_SEQ_PORT_TYPE_MIDI_GS
+ | SND_SEQ_PORT_TYPE_MIDI_XG
+ | SND_SEQ_PORT_TYPE_MIDI_MT32);
+ } else {
+ /* XXX check to see if changes have been made */
+ return;
+ }
+
+ ptr = NULL;
+ while (midi_port_foreach(_alsa_provider, &ptr)) {
+ data = (struct alsa_midi *)ptr->userdata;
+ data->mark = 0;
+ }
+
+ snd_seq_client_info_alloca(&cinfo);
+ snd_seq_port_info_alloca(&pinfo);
+ snd_seq_client_info_set_client(cinfo, -1);
+ while (snd_seq_query_next_client(seq, cinfo) >= 0) {
+ int cn = snd_seq_client_info_get_client(cinfo);
+ snd_seq_port_info_set_client(pinfo, cn);
+ snd_seq_port_info_set_port(pinfo, -1);
+ while (snd_seq_query_next_port(seq, pinfo) >= 0) {
+ io = 0;
+ if ((snd_seq_port_info_get_capability(pinfo)
+ & (SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ))
+ == (SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ))
+ io |= MIDI_INPUT;
+ if ((snd_seq_port_info_get_capability(pinfo)
+ & (SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE))
+ == (SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE))
+ io |= MIDI_OUTPUT;
+
+ if (!io) continue;
+
+ c = snd_seq_port_info_get_client(pinfo);
+ if (c == SND_SEQ_CLIENT_SYSTEM) continue;
+
+ p = snd_seq_port_info_get_port(pinfo);
+ ptr = NULL;
+ ok = 0;
+ while (midi_port_foreach(_alsa_provider, &ptr)) {
+ data = (struct alsa_midi *)ptr->userdata;
+ if (data->c == c && data->p == p) {
+ data->mark = 1;
+ ok = 1;
+ }
+ }
+ if (ok) continue;
+ ctext = snd_seq_client_info_get_name(cinfo);
+ ptext = snd_seq_port_info_get_name(pinfo);
+ if (strcmp(ctext, PORT_NAME) == 0
+ && strcmp(ptext, PORT_NAME) == 0) {
+ continue;
+ }
+ data = mem_alloc(sizeof(struct alsa_midi));
+ data->c = c; data->p = p;
+ data->client = ctext;
+ data->mark = 1;
+ data->port = ptext;
+ buffer = NULL;
+
+ if (snd_midi_event_new(MIDI_BUFSIZE, &data->dev) < 0) {
+ /* err... */
+ free(data);
+ continue;
+ }
+
+ if (asprintf(&buffer, "%3d:%-3d %-20.20s %s",
+ c, p, ctext, ptext) == -1) {
+ free(data);
+ continue;
+ }
+
+ midi_port_register(_alsa_provider, io, buffer, data, 1);
+ }
+ }
+
+ /* remove "disappeared" midi ports */
+ ptr = NULL;
+ while (midi_port_foreach(_alsa_provider, &ptr)) {
+ data = (struct alsa_midi *)ptr->userdata;
+ if (data->mark) continue;
+ midi_port_unregister(ptr->num);
+ }
+}
+int alsa_midi_setup(void)
+{
+ static snd_seq_queue_tempo_t *tempo;
+ static struct midi_driver driver;
+
+ /* only bother if alsa midi actually exists, otherwise this will
+ produce useless and annoying error messages on systems where alsa
+ libs are installed but which aren't actually running it */
+ struct stat sbuf;
+ if (stat("/dev/snd/seq", &sbuf) != 0)
+ return 0;
+
+
+#ifdef USE_DLTRICK_ALSA
+ if (!dlsym(_dltrick_handle,"snd_seq_open")) return 0;
+#endif
+ driver.poll = _alsa_poll;
+ driver.thread = _alsa_thread;
+ driver.enable = _alsa_start;
+ driver.disable = _alsa_stop;
+ driver.send = _alsa_send;
+ driver.flags = MIDI_PORT_CAN_SCHEDULE;
+ driver.drain = _alsa_drain;
+
+ if (snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0
+ || snd_seq_set_client_name(seq, PORT_NAME) < 0) {
+ return 0;
+ }
+
+ alsa_queue = snd_seq_alloc_queue(seq);
+ snd_seq_queue_tempo_malloc(&tempo);
+ snd_seq_queue_tempo_set_tempo(tempo,480000);
+ snd_seq_queue_tempo_set_ppq(tempo, 480);
+ snd_seq_set_queue_tempo(seq, alsa_queue, tempo);
+ snd_seq_start_queue(seq, alsa_queue, NULL);
+ snd_seq_drain_output(seq);
+
+ if (!midi_provider_register("ALSA", &driver)) return 0;
+ return 1;
+}
+
+
+#endif
diff --git a/src/sys/alsa/volume-alsa.c b/src/sys/alsa/volume-alsa.c
new file mode 100644
index 0000000..9f81374
--- /dev/null
+++ b/src/sys/alsa/volume-alsa.c
@@ -0,0 +1,237 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "headers.h"
+
+#include "util.h"
+
+#ifdef USE_ALSA
+#include <alsa/asoundlib.h>
+#include <alsa/mixer.h>
+
+static const char *alsa_card_id = "default";
+
+/* --------------------------------------------------------------------- */
+#ifdef USE_DLTRICK_ALSA
+#include <alsa/mixer.h>
+
+/* see midi-alsa for details about how this works */
+#include <dlfcn.h>
+
+extern void *_dltrick_handle;
+
+/* don't try this at home... */
+#define _void_dltrick(a,b,c) static void (*_dltrick_ ## a)b = NULL; \
+void a b { if (!_dltrick_##a) _dltrick_##a = dlsym(_dltrick_handle, #a); \
+if (!_dltrick_##a) abort(); _dltrick_ ## a c; }
+
+#define _any_dltrick(r,a,b,c) static r (*_dltrick_ ## a)b = NULL; \
+r a b { if (!_dltrick_##a) _dltrick_##a = dlsym(_dltrick_handle, #a); \
+if (!_dltrick_##a) abort(); return _dltrick_ ## a c; }
+
+_any_dltrick(snd_mixer_elem_t*, snd_mixer_find_selem,
+(snd_mixer_t*e,const snd_mixer_selem_id_t*sid),(e,sid))
+
+_void_dltrick(snd_mixer_selem_id_set_index,
+(snd_mixer_selem_id_t*obj,unsigned int val),(obj,val))
+
+_void_dltrick(snd_mixer_selem_id_set_name,
+(snd_mixer_selem_id_t*obj,const char *val),(obj,val))
+
+_any_dltrick(int,snd_mixer_selem_set_playback_volume,
+(snd_mixer_elem_t*e,snd_mixer_selem_channel_id_t ch,long v),(e,ch,v))
+
+_any_dltrick(int,snd_mixer_selem_is_playback_mono,(snd_mixer_elem_t*e),(e))
+_any_dltrick(int,snd_mixer_selem_has_playback_channel,(snd_mixer_elem_t*e,snd_mixer_selem_channel_id_t c),(e,c))
+
+_any_dltrick(int,snd_ctl_card_info,(snd_ctl_t*c,snd_ctl_card_info_t*i),(c,i))
+_any_dltrick(size_t,snd_ctl_card_info_sizeof,(void),())
+_any_dltrick(size_t,snd_mixer_selem_id_sizeof,(void),())
+
+_any_dltrick(int,snd_mixer_close,(snd_mixer_t*mm),(mm))
+_any_dltrick(int,snd_mixer_selem_get_playback_volume,
+(snd_mixer_elem_t*e,snd_mixer_selem_channel_id_t ch,long*v),(e,ch,v))
+#if (SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR < 10) || (SND_LIB_MAJOR < 1)
+_void_dltrick(snd_mixer_selem_get_playback_volume_range,
+(snd_mixer_elem_t*e,long*m,long*v),(e,m,v))
+#else
+_any_dltrick(int,snd_mixer_selem_get_playback_volume_range,
+(snd_mixer_elem_t*e,long*m,long*v),(e,m,v))
+#endif
+_any_dltrick(int,snd_ctl_open,(snd_ctl_t**c,const char *name,int mode),(c,name,mode))
+_any_dltrick(int,snd_ctl_close,(snd_ctl_t*ctl),(ctl))
+_any_dltrick(int,snd_mixer_open,(snd_mixer_t**m,int mode),(m,mode))
+_any_dltrick(int,snd_mixer_attach,(snd_mixer_t*m,const char *name),(m,name))
+_any_dltrick(int,snd_mixer_selem_register,(snd_mixer_t*m,
+ struct snd_mixer_selem_regopt*opt, snd_mixer_class_t **cp),(m,opt,cp))
+_any_dltrick(int,snd_mixer_selem_is_active,(snd_mixer_elem_t*e),(e))
+_any_dltrick(int,snd_mixer_selem_has_playback_volume,(snd_mixer_elem_t*e),(e))
+_any_dltrick(int,snd_mixer_selem_has_capture_switch,(snd_mixer_elem_t*e),(e))
+_any_dltrick(int,snd_mixer_selem_has_capture_switch_joined,(snd_mixer_elem_t*e),(e))
+_any_dltrick(int,snd_mixer_selem_has_capture_switch_exclusive,(snd_mixer_elem_t*e),(e))
+
+_any_dltrick(int,snd_mixer_load,(snd_mixer_t*m),(m))
+_any_dltrick(snd_mixer_elem_t*,snd_mixer_first_elem,(snd_mixer_t*m),(m))
+_any_dltrick(snd_mixer_elem_t*,snd_mixer_elem_next,(snd_mixer_elem_t*m),(m))
+_any_dltrick(snd_mixer_elem_type_t,snd_mixer_elem_get_type,(const snd_mixer_elem_t *obj),(obj))
+#endif
+
+/* alsa is paranoid, so snd_mixer_selem_id_alloca does an assert(&sid), which
+ * of course will never fail, so gcc complains. this shuts that warning up. */
+#undef assert
+#define assert(x)
+
+/* this _could_ change */
+static int current_alsa_range = 255;
+
+
+static void _alsa_writeout(snd_mixer_elem_t *em,
+ snd_mixer_selem_channel_id_t d,
+ int use, int lim)
+{
+ if (use > lim) use = lim;
+ (void)snd_mixer_selem_set_playback_volume(em, d, (long)use);
+}
+static void _alsa_write(snd_mixer_elem_t *em, int *l, int *r, long min, long range)
+{
+ long al, ar;
+ long mr, md;
+
+ al = ((*l) * range / current_alsa_range) + min;
+ ar = ((*r) * range / current_alsa_range) + min;
+
+ mr = min+range;
+
+ if (snd_mixer_selem_is_playback_mono(em)) {
+ md = ((al) + (ar)) / 2;
+
+ _alsa_writeout(em, SND_MIXER_SCHN_MONO, md, mr);
+ } else {
+ _alsa_writeout(em, SND_MIXER_SCHN_FRONT_LEFT, al, mr);
+ _alsa_writeout(em, SND_MIXER_SCHN_FRONT_RIGHT, ar, mr);
+#if 0
+/* this was probably wrong */
+ _alsa_writeout(em, SND_MIXER_SCHN_FRONT_CENTER, md, mr);
+ _alsa_writeout(em, SND_MIXER_SCHN_REAR_LEFT, al, mr);
+ _alsa_writeout(em, SND_MIXER_SCHN_REAR_RIGHT, ar, mr);
+ _alsa_writeout(em, SND_MIXER_SCHN_WOOFER, md, mr);
+#endif
+ }
+}
+static void _alsa_readin(snd_mixer_elem_t *em, snd_mixer_selem_channel_id_t d,
+ int *aa, long min, long range)
+{
+ long v;
+ if (snd_mixer_selem_has_playback_channel(em, d)) {
+ snd_mixer_selem_get_playback_volume(em, d, &v);
+ v -= min;
+ v = (v * current_alsa_range) / range;
+ (*aa) = v;
+ }
+
+}
+static void _alsa_config(UNUSED snd_mixer_elem_t *em, UNUSED int *l, UNUSED int *r, UNUSED long min, long range)
+{
+ current_alsa_range = range;
+}
+
+static void _alsa_read(snd_mixer_elem_t *em, int *l, int *r, long min, long range)
+{
+ if (snd_mixer_selem_is_playback_mono(em)) {
+ _alsa_readin(em, SND_MIXER_SCHN_MONO, l, min, range);
+ _alsa_readin(em, SND_MIXER_SCHN_MONO, r, min, range);
+ } else {
+ _alsa_readin(em, SND_MIXER_SCHN_FRONT_LEFT, l, min, range);
+ _alsa_readin(em, SND_MIXER_SCHN_FRONT_RIGHT, r, min, range);
+#if 0
+/* this was probably wrong */
+ _alsa_readin(em, SND_MIXER_SCHN_REAR_LEFT, l, min, range);
+ _alsa_readin(em, SND_MIXER_SCHN_REAR_RIGHT, r, min, range);
+ _alsa_readin(em, SND_MIXER_SCHN_FRONT_CENTER, l, min, range);
+ _alsa_readin(em, SND_MIXER_SCHN_FRONT_CENTER, r, min, range);
+ _alsa_readin(em, SND_MIXER_SCHN_WOOFER, l, min, range);
+ _alsa_readin(em, SND_MIXER_SCHN_WOOFER, r, min, range);
+#endif
+ }
+}
+
+static void _alsa_doit(void (*busy)(snd_mixer_elem_t *em,
+ int *, int *, long, long), int *l, int *r)
+{
+ long ml, mr;
+ snd_mixer_selem_id_t *sid;
+ snd_mixer_elem_t *em;
+ snd_mixer_t *mix;
+
+ snd_mixer_selem_id_alloca(&sid);
+ snd_mixer_selem_id_set_index(sid, 0);
+ snd_mixer_selem_id_set_name(sid, "Master");
+
+ if (snd_mixer_open(&mix, 0) == 0) {
+ if (snd_mixer_attach(mix, alsa_card_id) < 0) {
+ snd_mixer_close(mix);
+ return;
+ }
+ if (snd_mixer_selem_register(mix, NULL, NULL) < 0) {
+ snd_mixer_close(mix);
+ return;
+ }
+ if (snd_mixer_load(mix) < 0) {
+ snd_mixer_close(mix);
+ return;
+ }
+ em = snd_mixer_find_selem(mix, sid);
+ if (em) {
+ ml = mr = 0;
+ snd_mixer_selem_get_playback_volume_range(em, &ml, &mr);
+ if (ml != mr) {
+ busy(em, l, r, ml, mr - ml);
+ }
+ }
+ snd_mixer_close(mix);
+ }
+
+}
+
+
+int alsa_volume_get_max(void);
+int alsa_volume_get_max(void)
+{
+ int a1, a2;
+ _alsa_doit(_alsa_config, &a1, &a2);
+ return current_alsa_range;
+}
+
+void alsa_volume_read(int *left, int *right);
+void alsa_volume_read(int *left, int *right)
+{
+ *left = *right = 0;
+ _alsa_doit(_alsa_read, left, right);
+}
+
+void alsa_volume_write(int left, int right);
+void alsa_volume_write(int left, int right)
+{
+ _alsa_doit(_alsa_write, &left, &right);
+}
+#endif
diff --git a/src/sys/fd.org/autopackage.apspec b/src/sys/fd.org/autopackage.apspec
new file mode 100644
index 0000000..5d4fb21
--- /dev/null
+++ b/src/sys/fd.org/autopackage.apspec
@@ -0,0 +1,57 @@
+# -*-shell-script-*-
+
+[Meta]
+RootName: @schismtracker.org:1.1
+DisplayName: Schism Tracker
+ShortName: schismtracker
+Maintainer: Mrs. Brisby <mrs.brisby@nimh.org>
+Packager: Mrs. Brisby <mrs.brisby@nimh.org>
+Summary: Schism Tracker is a music editor that matches the look and feel of Impulse Tracker as closely as possible.
+URL: http://schismtracker.org/
+License: GNU General Public License, Version 2
+SoftwareVersion: 1.1
+AutopackageTarget: 1.0
+
+[Description]
+Schism Tracker is a music editor in the spirit of Impulse Tracker. Nearly every
+feature of Impulse Tracker is available in exactly the same manner. Improvements
+have been extremely careful to avoid disturbing any muscle memory that the user
+might have developed with Impulse Tracker.
+
+[BuildPrepare]
+mkdir -p linux-x86-build && cd linux-x86-build && prepareBuild --src .. $EXTRA_ARGS
+
+[BuildUnprepare]
+unprepareBuild
+
+[Imports]
+import <<EOF
+$source_dir/linux-x86-build/schismtracker
+$source_dir/icons/schism-icon-128.png
+$source_dir/icons/schism-itf-icon-128.png
+$source_dir/sys/fd.org/schism.desktop
+$source_dir/sys/fd.org/itf.desktop
+$source_dir/NEWS
+$source_dir/README
+$source_dir/COPYING
+$source_dir/ChangeLog
+EOF
+
+[Prepare]
+# Dependency checking
+require @libsdl.org/sdl 1.2
+
+[Install]
+# Put your installation script here
+installExe schismtracker
+installIcon schism-icon-128.png schism-itf-icon-128.png >/dev/null 2>&1
+installDesktop "AudioVideo" schism.desktop
+installDesktop "AudioVideo" itf.desktop
+installData NEWS
+installData README
+installData COPYING
+installData ChangeLog
+
+[Uninstall]
+# Usually just the following line is enough to uninstall everything
+uninstallFromLog
diff --git a/src/sys/fd.org/itf.desktop b/src/sys/fd.org/itf.desktop
new file mode 100644
index 0000000..0a71838
--- /dev/null
+++ b/src/sys/fd.org/itf.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Version=1.0
+Name=Schism Tracker Font Editor
+Comment=ITF Clone
+Encoding=UTF-8
+Terminal=false
+Exec=schismtracker --font-editor
+Type=Application
+Icon=schism-itf-icon-128.png
+Categories=GNOME;Application;AudioVideo;Audio;Video;
+X-Desktop-File-Install-Version=0.10
diff --git a/src/sys/fd.org/schism.desktop b/src/sys/fd.org/schism.desktop
new file mode 100644
index 0000000..d563964
--- /dev/null
+++ b/src/sys/fd.org/schism.desktop
@@ -0,0 +1,18 @@
+[Desktop Entry]
+Actions=Play;
+Version=1.0
+Name=Schism Tracker
+Comment=Impulse Tracker Clone
+Encoding=UTF-8
+Terminal=false
+TryExec=schismtracker
+Exec=schismtracker %f
+Type=Application
+Icon=schism-icon-128.png
+Categories=GNOME;Application;AudioVideo;Audio;Video;
+MimeType=audio/x-mod
+X-Desktop-File-Install-Version=0.10
+
+[Desktop Action Play]
+Name=Schism Tracker (play song)
+Exec=schismtracker -p %f
diff --git a/src/sys/macosx/Schism_Tracker.app/Contents/Info.plist b/src/sys/macosx/Schism_Tracker.app/Contents/Info.plist
new file mode 100644
index 0000000..ca4d05d
--- /dev/null
+++ b/src/sys/macosx/Schism_Tracker.app/Contents/Info.plist
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>schismtracker</string>
+ <key>CFBundleDocumentTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>it</string>
+ <string>IT</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>moduleIcon.icns</string>
+ <key>CFBundleMIMETypes</key>
+ <array>
+ <string>audio/mod</string>
+ <string>audio/x-mod</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Impulse Tracker Module</string>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>LSIsAppleDefaultForType</key>
+ <true/>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>669</string>
+ <string>amf</string>
+ <string>AMF</string>
+ <string>ams</string>
+ <string>AMS</string>
+ <string>dbm</string>
+ <string>DBM</string>
+ <string>dmf</string>
+ <string>DMF</string>
+ <string>far</string>
+ <string>FAR</string>
+ <string>mdl</string>
+ <string>MDL</string>
+ <string>med</string>
+ <string>MED</string>
+ <string>mod</string>
+ <string>MOD</string>
+ <string>mt2</string>
+ <string>MT2</string>
+ <string>mtm</string>
+ <string>MTM</string>
+ <string>okt</string>
+ <string>OKT</string>
+ <string>psm</string>
+ <string>PSM</string>
+ <string>ptm</string>
+ <string>PTM</string>
+ <string>s3m</string>
+ <string>S3M</string>
+ <string>stm</string>
+ <string>STM</string>
+ <string>ult</string>
+ <string>ULT</string>
+ <string>umx</string>
+ <string>UMX</string>
+ <string>xm</string>
+ <string>XM</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>moduleIcon.icns</string>
+ <key>CFBundleMIMETypes</key>
+ <array>
+ <string>audio/mod</string>
+ <string>audio/x-mod</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Audio Module</string>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>LSIsAppleDefaultForType</key>
+ <true/>
+ </dict>
+ </array>
+ <key>CFBundleGetInfoString</key>
+ <string>Schism Tracker Copyright 2003-2012 Storlek</string>
+ <key>CFBundleIconFile</key>
+ <string>appIcon.icns</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.schismtracker.SchismTracker</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>Schism Tracker</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>hg</string>
+ <key>CFBundleSignature</key>
+ <string>Schm</string>
+ <key>CFBundleVersion</key>
+ <string>hg</string>
+ <key>NSMainNibFile</key>
+ <string>MainMenu</string>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+ <key>CGDisableCoalescedUpdates</key>
+ <true/>
+</dict>
+</plist>
diff --git a/src/sys/macosx/Schism_Tracker.app/Contents/PkgInfo b/src/sys/macosx/Schism_Tracker.app/Contents/PkgInfo
new file mode 100644
index 0000000..07af6f8
--- /dev/null
+++ b/src/sys/macosx/Schism_Tracker.app/Contents/PkgInfo
@@ -0,0 +1 @@
+APPLSchm \ No newline at end of file
diff --git a/src/sys/macosx/Schism_Tracker.app/Contents/Resources/AppSettings.plist b/src/sys/macosx/Schism_Tracker.app/Contents/Resources/AppSettings.plist
new file mode 100644
index 0000000..62376f5
--- /dev/null
+++ b/src/sys/macosx/Schism_Tracker.app/Contents/Resources/AppSettings.plist
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>EncryptAndChecksum</key>
+ <false/>
+ <key>IsDroppable</key>
+ <true/>
+ <key>OutputType</key>
+ <string>None</string>
+ <key>RemainRunningAfterCompletion</key>
+ <false/>
+ <key>RequiresAdminPrivileges</key>
+ <false/>
+ <key>ScriptInterpreter</key>
+ <string>/bin/sh</string>
+</dict>
+</plist>
diff --git a/src/sys/macosx/Schism_Tracker.app/Contents/Resources/appIcon.icns b/src/sys/macosx/Schism_Tracker.app/Contents/Resources/appIcon.icns
new file mode 100644
index 0000000..8ed3637
--- /dev/null
+++ b/src/sys/macosx/Schism_Tracker.app/Contents/Resources/appIcon.icns
Binary files differ
diff --git a/src/sys/macosx/Schism_Tracker.app/Contents/Resources/moduleIcon.icns b/src/sys/macosx/Schism_Tracker.app/Contents/Resources/moduleIcon.icns
new file mode 100644
index 0000000..597056b
--- /dev/null
+++ b/src/sys/macosx/Schism_Tracker.app/Contents/Resources/moduleIcon.icns
Binary files differ
diff --git a/src/sys/macosx/ibook-support.c b/src/sys/macosx/ibook-support.c
new file mode 100644
index 0000000..71bd00b
--- /dev/null
+++ b/src/sys/macosx/ibook-support.c
@@ -0,0 +1,103 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include "headers.h"
+#include "util.h"
+
+int macosx_ibook_fnswitch(int setting); /* FIXME: ugliness */
+
+#ifdef MACOSX
+
+#include <IOKit/IOKitLib.h>
+#include <IOKit/IOReturn.h>
+#include <ApplicationServices/ApplicationServices.h>
+#include <IOKit/hidsystem/IOHIDLib.h>
+#include <IOKit/hidsystem/IOHIDParameter.h>
+
+#define kMyDriversKeyboardClassName "AppleADBKeyboard"
+#define kfnSwitchError 200
+#define kfnAppleMode 0
+#define kfntheOtherMode 1
+
+#ifndef kIOHIDFKeyModeKey
+#define kIOHIDFKeyModeKey "HIDFKeyMode"
+#endif
+
+int macosx_ibook_fnswitch(int setting)
+{
+ kern_return_t kr;
+ mach_port_t mp;
+ io_service_t so;
+ /*io_name_t sn;*/
+ io_connect_t dp;
+ io_iterator_t it;
+ CFDictionaryRef classToMatch;
+ /*CFNumberRef fnMode;*/
+ unsigned int res, dummy;
+
+ kr = IOMasterPort(bootstrap_port, &mp);
+ if (kr != KERN_SUCCESS) return -1;
+
+ classToMatch = IOServiceMatching(kIOHIDSystemClass);
+ if (classToMatch == NULL) {
+ return -1;
+ }
+ kr = IOServiceGetMatchingServices(mp, classToMatch, &it);
+ if (kr != KERN_SUCCESS) return -1;
+
+ so = IOIteratorNext(it);
+ IOObjectRelease(it);
+
+ if (!so) return -1;
+
+ kr = IOServiceOpen(so, mach_task_self(), kIOHIDParamConnectType, &dp);
+ if (kr != KERN_SUCCESS) return -1;
+
+ kr = IOHIDGetParameter(dp, CFSTR(kIOHIDFKeyModeKey), sizeof(res),
+ &res, (IOByteCount *) &dummy);
+ if (kr != KERN_SUCCESS) {
+ IOServiceClose(dp);
+ return -1;
+ }
+
+ if (setting == kfnAppleMode || setting == kfntheOtherMode) {
+ dummy = setting;
+ kr = IOHIDSetParameter(dp, CFSTR(kIOHIDFKeyModeKey),
+ &dummy, sizeof(dummy));
+ if (kr != KERN_SUCCESS) {
+ IOServiceClose(dp);
+ return -1;
+ }
+ }
+
+ IOServiceClose(dp);
+ /* old setting... */
+ return res;
+}
+
+#else
+
+int macosx_ibook_fnswitch(UNUSED int setting)
+{
+ return 0;
+}
+#endif
diff --git a/src/sys/macosx/macosx-sdlmain.m b/src/sys/macosx/macosx-sdlmain.m
new file mode 100644
index 0000000..df7f440
--- /dev/null
+++ b/src/sys/macosx/macosx-sdlmain.m
@@ -0,0 +1,619 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* wee....
+
+this is used to do some schism-on-macosx customization
+and get access to cocoa stuff
+
+pruned up some here :) -mrsb
+
+ */
+
+/* SDLMain.m - main entry point for our Cocoa-ized SDL app
+ Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
+ Non-NIB-Code & other changes: Max Horn <max@quendi.de>
+
+ Feel free to customize this file to suit your needs
+*/
+
+extern char *initial_song;
+
+#include <SDL.h> /* necessary here */
+#include "event.h"
+#include "osdefs.h"
+
+#define Cursor AppleCursor
+#import <Cocoa/Cocoa.h>
+#undef Cursor
+
+@interface SDLMain : NSObject
+- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename;
+@end
+
+#import <sys/param.h> /* for MAXPATHLEN */
+#import <unistd.h>
+
+/* Portions of CPS.h */
+typedef struct CPSProcessSerNum
+{
+ UInt32 lo;
+ UInt32 hi;
+} CPSProcessSerNum;
+
+extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
+extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
+extern OSErr CPSSetProcessName ( CPSProcessSerNum *psn, char *processname);
+extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
+
+static int gArgc;
+static char **gArgv;
+static BOOL gFinderLaunch;
+int macosx_did_finderlaunch;
+
+#define KEQ_FN(n) [NSString stringWithFormat:@"%C", NSF##n##FunctionKey]
+
+@interface SDLApplication : NSApplication
+@end
+
+@interface NSApplication(OtherMacOSXExtensions)
+-(void)setAppleMenu:(NSMenu*)m;
+@end
+
+@implementation SDLApplication
+/* Invoked from the Quit menu item */
+- (void)terminate:(id)sender
+{
+ /* Post a SDL_QUIT event */
+ SDL_Event event;
+ event.type = SDL_QUIT;
+ SDL_PushEvent(&event);
+}
+- (void)_menu_callback:(id)sender
+{
+ SDL_Event e;
+ NSString *px;
+ const char *po;
+
+ px = [sender representedObject];
+ po = [px UTF8String];
+ if (po) {
+ e.type = SCHISM_EVENT_NATIVE;
+ e.user.code = SCHISM_EVENT_NATIVE_SCRIPT;
+ e.user.data1 = strdup(po);
+ SDL_PushEvent(&e);
+ }
+}
+
+
+@end
+
+/* The main class of the application, the application's delegate */
+@implementation SDLMain
+
+- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
+{
+ SDL_Event e;
+ const char *po;
+
+ if (!filename) return NO;
+
+ po = [filename UTF8String];
+ if (po) {
+ e.type = SCHISM_EVENT_NATIVE;
+ e.user.code = SCHISM_EVENT_NATIVE_OPEN;
+ e.user.data1 = strdup(po);
+ /* if we started as a result of a doubleclick on
+ a document, then Main still hasn't really started yet.
+ */
+ initial_song = strdup(po);
+ SDL_PushEvent(&e);
+ return YES;
+ } else {
+ return NO;
+ }
+}
+
+/* other interesting ones:
+- (BOOL)application:(NSApplication *)theApplication printFile:(NSString *)filename
+- (BOOL)applicationOpenUntitledFile:(NSApplication *)theApplication
+*/
+/* Set the working directory to the .app's parent directory */
+- (void) setupWorkingDirectory:(BOOL)shouldChdir
+{
+ if (shouldChdir)
+ {
+ char parentdir[MAXPATHLEN];
+ CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
+ CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url);
+ if (CFURLGetFileSystemRepresentation(url2, true, (unsigned char *) parentdir, MAXPATHLEN)) {
+ assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */
+ }
+ CFRelease(url);
+ CFRelease(url2);
+ }
+
+}
+
+static void setApplicationMenu(void)
+{
+ /* warning: this code is very odd */
+ NSMenu *appleMenu;
+ NSMenu *otherMenu;
+ NSMenuItem *menuItem;
+
+ appleMenu = [[NSMenu alloc] initWithTitle:@""];
+
+ /* Add menu items */
+ [appleMenu addItemWithTitle:@"About Schism Tracker"
+ action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
+
+ [appleMenu addItem:[NSMenuItem separatorItem]];
+
+ /* other schism items */
+ menuItem = (NSMenuItem*)[appleMenu addItemWithTitle:@"Help"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(1)];
+ [menuItem setKeyEquivalentModifierMask:0];
+ [menuItem setRepresentedObject: @"help"];
+
+ [appleMenu addItem:[NSMenuItem separatorItem]];
+ menuItem = (NSMenuItem*)[appleMenu addItemWithTitle:@"View Patterns"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(2)];
+ [menuItem setKeyEquivalentModifierMask:0];
+ [menuItem setRepresentedObject: @"pattern"];
+ menuItem = (NSMenuItem*)[appleMenu addItemWithTitle:@"Orders/Panning"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(11)];
+ [menuItem setKeyEquivalentModifierMask:0];
+ [menuItem setRepresentedObject: @"orders"];
+ menuItem = (NSMenuItem*)[appleMenu addItemWithTitle:@"Variables"
+ action:@selector(_menu_callback:)
+ keyEquivalent:[NSString stringWithFormat:@"%C", NSF12FunctionKey]];
+ [menuItem setKeyEquivalentModifierMask:0];
+ [menuItem setRepresentedObject: @"variables"];
+ menuItem = (NSMenuItem*)[appleMenu addItemWithTitle:@"Message Editor"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(9)];
+ [menuItem setKeyEquivalentModifierMask:NSShiftKeyMask];
+ [menuItem setRepresentedObject: @"message_edit"];
+
+ [appleMenu addItem:[NSMenuItem separatorItem]];
+
+ [appleMenu addItemWithTitle:@"Hide Schism Tracker" action:@selector(hide:) keyEquivalent:@"h"];
+
+ menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
+ [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
+
+ [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
+
+ [appleMenu addItem:[NSMenuItem separatorItem]];
+
+ [appleMenu addItemWithTitle:@"Quit Schism Tracker" action:@selector(terminate:) keyEquivalent:@"q"];
+
+ /* Put menu into the menubar */
+ menuItem = (NSMenuItem*)[[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
+ [menuItem setSubmenu:appleMenu];
+ [[NSApp mainMenu] addItem:menuItem];
+
+ /* File menu */
+ otherMenu = [[NSMenu alloc] initWithTitle:@"File"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"New..."
+ action:@selector(_menu_callback:)
+ keyEquivalent:@"n"];
+ [menuItem setKeyEquivalentModifierMask:NSControlKeyMask];
+ [menuItem setRepresentedObject: @"new"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Load..."
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(9)];
+ [menuItem setKeyEquivalentModifierMask:0];
+ [menuItem setRepresentedObject: @"load"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Save Current"
+ action:@selector(_menu_callback:)
+ keyEquivalent:@"s"];
+ [menuItem setKeyEquivalentModifierMask:NSControlKeyMask];
+ [menuItem setRepresentedObject: @"save"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Save As..."
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(10)];
+ [menuItem setKeyEquivalentModifierMask:0];
+ [menuItem setRepresentedObject: @"save_as"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Export..."
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(10)];
+ [menuItem setKeyEquivalentModifierMask:NSShiftKeyMask];
+ [menuItem setRepresentedObject: @"export_song"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Message Log"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(11)];
+ [menuItem setKeyEquivalentModifierMask:NSFunctionKeyMask|NSControlKeyMask];
+ [menuItem setRepresentedObject: @"logviewer"];
+ menuItem = (NSMenuItem*)[[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
+ [menuItem setSubmenu:otherMenu];
+ [[NSApp mainMenu] addItem:menuItem];
+
+ /* Playback menu */
+ otherMenu = [[NSMenu alloc] initWithTitle:@"Playback"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Show Infopage"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(5)];
+ [menuItem setKeyEquivalentModifierMask:0];
+ [menuItem setRepresentedObject: @"info"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Play Song"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(5)];
+ [menuItem setKeyEquivalentModifierMask:NSControlKeyMask];
+ [menuItem setRepresentedObject: @"play"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Play Pattern"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(6)];
+ [menuItem setKeyEquivalentModifierMask:0];
+ [menuItem setRepresentedObject: @"play_pattern"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Play from Order"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(6)];
+ [menuItem setKeyEquivalentModifierMask:NSShiftKeyMask];
+ [menuItem setRepresentedObject: @"play_order"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Play from Mark/Cursor"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(7)];
+ [menuItem setKeyEquivalentModifierMask:0];
+ [menuItem setRepresentedObject: @"play_mark"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Stop"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(8)];
+ [menuItem setKeyEquivalentModifierMask:0];
+ [menuItem setRepresentedObject: @"stop"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Calculate Length"
+ action:@selector(_menu_callback:)
+ keyEquivalent:@"p"];
+ [menuItem setKeyEquivalentModifierMask:(NSFunctionKeyMask|NSControlKeyMask)];
+ [menuItem setRepresentedObject: @"calc_length"];
+ menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
+ [menuItem setSubmenu:otherMenu];
+ [[NSApp mainMenu] addItem:menuItem];
+
+ /* Sample menu */
+ otherMenu = [[NSMenu alloc] initWithTitle:@"Samples"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Sample List"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(3)];
+ [menuItem setKeyEquivalentModifierMask:0];
+ [menuItem setRepresentedObject: @"sample_page"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Sample Library"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(3)];
+ [menuItem setKeyEquivalentModifierMask:NSShiftKeyMask];
+ [menuItem setRepresentedObject: @"sample_library"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Reload Soundcard"
+ action:@selector(_menu_callback:)
+ keyEquivalent:@"g"];
+ [menuItem setKeyEquivalentModifierMask:NSControlKeyMask];
+ [menuItem setRepresentedObject: @"init_sound"];
+ menuItem = (NSMenuItem*)[[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
+ [menuItem setSubmenu:otherMenu];
+ [[NSApp mainMenu] addItem:menuItem];
+
+ /* Instrument menu */
+ otherMenu = [[NSMenu alloc] initWithTitle:@"Instruments"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Instrument List"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(4)];
+ [menuItem setKeyEquivalentModifierMask:0];
+ [menuItem setRepresentedObject: @"inst_page"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Instrument Library"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(4)];
+ [menuItem setKeyEquivalentModifierMask:NSShiftKeyMask];
+ [menuItem setRepresentedObject: @"inst_library"];
+ menuItem = (NSMenuItem*)[[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
+ [menuItem setSubmenu:otherMenu];
+ [[NSApp mainMenu] addItem:menuItem];
+
+ /* Settings menu */
+ otherMenu = [[NSMenu alloc] initWithTitle:@"Settings"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Preferences"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(5)];
+ [menuItem setKeyEquivalentModifierMask:NSShiftKeyMask];
+ [menuItem setRepresentedObject: @"preferences"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"MIDI Configuration"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(1)];
+ [menuItem setKeyEquivalentModifierMask:NSShiftKeyMask];
+ [menuItem setRepresentedObject: @"midi_config"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Palette Editor"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(12)];
+ [menuItem setKeyEquivalentModifierMask:NSControlKeyMask];
+ [menuItem setRepresentedObject: @"palette_page"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Font Editor"
+ action:@selector(_menu_callback:)
+ keyEquivalent:@""];
+ [menuItem setRepresentedObject: @"font_editor"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"System Configuration"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(1)];
+ [menuItem setKeyEquivalentModifierMask:NSControlKeyMask];
+ [menuItem setRepresentedObject: @"system_config"];
+
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Toggle Fullscreen"
+ action:@selector(_menu_callback:)
+ keyEquivalent:@"\r"];
+ [menuItem setKeyEquivalentModifierMask:(NSControlKeyMask|NSAlternateKeyMask)];
+ [menuItem setRepresentedObject: @"fullscreen"];
+ menuItem = (NSMenuItem*)[[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
+ [menuItem setSubmenu:otherMenu];
+ [[NSApp mainMenu] addItem:menuItem];
+
+ /* Tell the application object that this is now the application menu */
+ [NSApp setAppleMenu:appleMenu];
+
+ /* Finally give up our references to the objects */
+ [appleMenu release];
+ [menuItem release];
+}
+
+/* Create a window menu */
+static void setupWindowMenu(void)
+{
+ NSMenu *windowMenu;
+ NSMenuItem *windowMenuItem;
+ NSMenuItem *menuItem;
+
+ windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
+
+ /* "Minimize" item */
+ menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
+ [windowMenu addItem:menuItem];
+ [menuItem release];
+
+ /* Put menu into the menubar */
+ windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
+ [windowMenuItem setSubmenu:windowMenu];
+ [[NSApp mainMenu] addItem:windowMenuItem];
+
+ /* Tell the application object that this is now the window menu */
+ [NSApp setWindowsMenu:windowMenu];
+
+ /* Finally give up our references to the objects */
+ [windowMenu release];
+ [windowMenuItem release];
+}
+
+/* Replacement for NSApplicationMain */
+static void CustomApplicationMain (int argc, char **argv)
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ SDLMain *sdlMain;
+ CPSProcessSerNum PSN;
+
+ /* Ensure the application object is initialised */
+ [SDLApplication sharedApplication];
+
+ /* Tell the dock about us */
+ if (!CPSGetCurrentProcess(&PSN)) {
+ if (!macosx_did_finderlaunch) {
+ CPSSetProcessName(&PSN,"Schism Tracker");
+ }
+ if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
+ if (!CPSSetFrontProcess(&PSN))
+ [SDLApplication sharedApplication];
+ }
+
+ /* Set up the menubar */
+ [NSApp setMainMenu:[[NSMenu alloc] init]];
+ setApplicationMenu();
+ setupWindowMenu();
+
+ /* Create SDLMain and make it the app delegate */
+ sdlMain = [[SDLMain alloc] init];
+ [NSApp setDelegate:sdlMain];
+
+ /* Start the main event loop */
+ [NSApp run];
+
+ [sdlMain release];
+ [pool release];
+}
+
+/* Called when the internal event loop has just started running */
+- (void) applicationDidFinishLaunching: (NSNotification *) note
+{
+ int status;
+
+ /* Set the working directory to the .app's parent directory */
+ [self setupWorkingDirectory:gFinderLaunch];
+
+ /* Hand off to main application code */
+ status = SDL_main (gArgc, gArgv);
+
+ /* We're done, thank you for playing */
+ exit(status);
+}
+@end
+
+
+@implementation NSString (ReplaceSubString)
+
+- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
+{
+ unsigned int bufferSize;
+ unsigned int selfLen = [self length];
+ unsigned int aStringLen = [aString length];
+ unichar *buffer;
+ NSRange localRange;
+ NSString *result;
+
+ bufferSize = selfLen + aStringLen - aRange.length;
+ buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar));
+
+ /* Get first part into buffer */
+ localRange.location = 0;
+ localRange.length = aRange.location;
+ [self getCharacters:buffer range:localRange];
+
+ /* Get middle part into buffer */
+ localRange.location = 0;
+ localRange.length = aStringLen;
+ [aString getCharacters:(buffer+aRange.location) range:localRange];
+
+ /* Get last part into buffer */
+ localRange.location = aRange.location + aRange.length;
+ localRange.length = selfLen - localRange.location;
+ [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
+
+ /* Build output string */
+ result = [NSString stringWithCharacters:buffer length:bufferSize];
+
+ NSDeallocateMemoryPages(buffer, bufferSize);
+
+ return result;
+}
+
+@end
+
+
+
+#ifdef main
+# undef main
+#endif
+
+
+/* Main entry point to executable - should *not* be SDL_main! */
+int main (int argc, char **argv)
+{
+ /* Copy the arguments into a global variable */
+ /* This is passed if we are launched by double-clicking */
+ if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
+ gArgc = 1;
+ gFinderLaunch = YES;
+ macosx_did_finderlaunch = 1;
+ } else {
+ gArgc = argc;
+ gFinderLaunch = NO;
+ macosx_did_finderlaunch = 0;
+ }
+ gArgv = argv;
+
+ CustomApplicationMain (argc, argv);
+
+ return 0;
+}
+
+/* these routines provide clipboard encapsulation */
+const char *macosx_clippy_get(void)
+{
+ NSPasteboard *pb = [NSPasteboard generalPasteboard];
+ NSString *type = [pb availableTypeFromArray:[NSArray
+ arrayWithObject:NSStringPboardType]];
+ NSString *contents;
+ const char *po;
+
+ if (type == nil) return "";
+
+ contents = [pb stringForType:type];
+ if (contents == nil) return "";
+ po = [contents UTF8String];
+ if (!po) return "";
+ return po;
+}
+void macosx_clippy_put(const char *buf)
+{
+ NSString *contents = [NSString stringWithUTF8String:buf];
+ NSPasteboard *pb = [NSPasteboard generalPasteboard];
+ [pb declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
+ [pb setString:contents forType:NSStringPboardType];
+}
+// ktt appears to be 1/60th of a second?
+unsigned int key_repeat_rate(void)
+{
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+ int ktt = [defaults integerForKey:@"KeyRepeat"];
+ if (!ktt || ktt < 0) ktt = 4; // eh?
+ ktt = (ktt * 1000) / 60;
+ return (unsigned)ktt;
+}
+unsigned int key_repeat_delay(void)
+{
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+ int ktt = [defaults integerForKey:@"InitialKeyRepeat"];
+ if (!ktt || ktt < 0) ktt = 35;
+ ktt = (ktt * 1000) / 60;
+ return (unsigned)ktt;
+}
+int key_scancode_lookup(int k, int def)
+{
+ switch (k & 127) {
+ case 0x32: /* QZ_BACKQUOTE */ return SDLK_BACKQUOTE;
+ case 0x12: /* QZ_1 */ return SDLK_1;
+ case 0x13: /* QZ_2 */ return SDLK_2;
+ case 0x14: /* QZ_3 */ return SDLK_3;
+ case 0x15: /* QZ_4 */ return SDLK_4;
+ case 0x17: /* QZ_5 */ return SDLK_5;
+ case 0x16: /* QZ_6 */ return SDLK_6;
+ case 0x1A: /* QZ_7 */ return SDLK_7;
+ case 0x1C: /* QZ_8 */ return SDLK_8;
+ case 0x19: /* QZ_9 */ return SDLK_9;
+ case 0x1D: /* QZ_0 */ return SDLK_0;
+ case 0x1B: /* QZ_MINUS */ return SDLK_MINUS;
+ case 0x18: /* QZ_EQUALS */ return SDLK_EQUALS;
+ case 0x0C: /* QZ_q */ return SDLK_q;
+ case 0x0D: /* QZ_w */ return SDLK_w;
+ case 0x0E: /* QZ_e */ return SDLK_e;
+ case 0x0F: /* QZ_r */ return SDLK_r;
+ case 0x11: /* QZ_t */ return SDLK_t;
+ case 0x10: /* QZ_y */ return SDLK_y;
+ case 0x20: /* QZ_u */ return SDLK_u;
+ case 0x22: /* QZ_i */ return SDLK_i;
+ case 0x1F: /* QZ_o */ return SDLK_o;
+ case 0x23: /* QZ_p */ return SDLK_p;
+ case 0x21: /* QZ_[ */ return SDLK_LEFTBRACKET;
+ case 0x1E: /* QZ_] */ return SDLK_RIGHTBRACKET;
+ case 0x2A: /* QZ_backslash */ return SDLK_BACKSLASH;
+ case 0x00: /* QZ_a */ return SDLK_a;
+ case 0x01: /* QZ_s */ return SDLK_s;
+ case 0x02: /* QZ_d */ return SDLK_d;
+ case 0x03: /* QZ_f */ return SDLK_f;
+ case 0x05: /* QZ_g */ return SDLK_g;
+ case 0x04: /* QZ_h */ return SDLK_h;
+ case 0x26: /* QZ_j */ return SDLK_j;
+ case 0x28: /* QZ_k */ return SDLK_k;
+ case 0x25: /* QZ_l */ return SDLK_l;
+ case 0x29: /* QZ_; */ return SDLK_SEMICOLON;
+ case 0x27: /* QZ_quote */ return SDLK_QUOTE;
+ case 0x06: /* QZ_z */ return SDLK_z;
+ case 0x07: /* QZ_x */ return SDLK_x;
+ case 0x08: /* QZ_c */ return SDLK_c;
+ case 0x09: /* QZ_v */ return SDLK_v;
+ case 0x0B: /* QZ_b */ return SDLK_b;
+ case 0x2D: /* QZ_n */ return SDLK_n;
+ case 0x2E: /* QZ_m */ return SDLK_m;
+ case 0x2B: /* QZ_, */ return SDLK_COMMA;
+ case 0x2F: /* QZ_. */ return SDLK_PERIOD;
+ case 0x2C: /* QZ_slash */ return SDLK_SLASH;
+ case 0x31: /* QZ_space */ return SDLK_SPACE;
+ default: return def;
+ };
+}
diff --git a/src/sys/macosx/midi-macosx.c b/src/sys/macosx/midi-macosx.c
new file mode 100644
index 0000000..3342e2c
--- /dev/null
+++ b/src/sys/macosx/midi-macosx.c
@@ -0,0 +1,222 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "headers.h"
+
+#include "midi.h"
+
+#include "util.h"
+
+#ifdef MACOSX
+
+#include <CoreServices/CoreServices.h>
+#include <CoreMIDI/MIDIServices.h>
+#include <CoreAudio/HostTime.h>
+
+static MIDIClientRef client = NULL;
+static MIDIPortRef portIn = NULL;
+static MIDIPortRef portOut = NULL;
+
+static int max_outputs = 0;
+static int max_inputs = 0;
+
+struct macosx_midi {
+ char *name;
+ MIDIEndpointRef ep;
+ unsigned char packet[1024];
+ MIDIPacketList *pl;
+ MIDIPacket *x;
+};
+
+static void readProc(const MIDIPacketList *np, UNUSED void *rc, void *crc)
+{
+ struct midi_port *p;
+ struct macosx_midi *m;
+ MIDIPacket *x;
+ unsigned long i;
+
+ p = (struct midi_port *)crc;
+ m = (struct macosx_midi *)p->userdata;
+
+ x = (MIDIPacket*)&np->packet[0];
+ for (i = 0; i < np->numPackets; i++) {
+ midi_received_cb(p, x->data, x->length);
+ x = MIDIPacketNext(x);
+ }
+}
+static void _macosx_send(struct midi_port *p, const unsigned char *data,
+ unsigned int len, unsigned int delay)
+{
+ struct macosx_midi *m;
+
+ m = (struct macosx_midi *)p->userdata;
+ if (!m->x) {
+ m->x = MIDIPacketListInit(m->pl);
+ }
+
+ /* msec to nsec? */
+ m->x = MIDIPacketListAdd(m->pl, sizeof(m->packet),
+ m->x, (MIDITimeStamp)AudioConvertNanosToHostTime(
+ AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()) + (1000000*delay)),
+ len, data);
+}
+static void _macosx_drain(struct midi_port *p)
+{
+ struct macosx_midi *m;
+
+ m = (struct macosx_midi *)p->userdata;
+ if (m->x) {
+ MIDISend(portOut, m->ep, m->pl);
+ m->x = NULL;
+ }
+}
+
+/* lifted from portmidi */
+static char *get_ep_name(MIDIEndpointRef ep)
+{
+ MIDIEntityRef entity;
+ MIDIDeviceRef device;
+ CFStringRef endpointName = NULL, deviceName = NULL, fullName = NULL;
+ CFStringEncoding defaultEncoding;
+ char* newName;
+
+ /* get the default string encoding */
+ defaultEncoding = CFStringGetSystemEncoding();
+
+ /* get the entity and device info */
+ MIDIEndpointGetEntity(ep, &entity);
+ MIDIEntityGetDevice(entity, &device);
+
+ /* create the nicely formated name */
+ MIDIObjectGetStringProperty(ep, kMIDIPropertyName, &endpointName);
+ MIDIObjectGetStringProperty(device, kMIDIPropertyName, &deviceName);
+ if (deviceName != NULL) {
+ fullName = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@: %@"),
+ deviceName, endpointName);
+ } else {
+ fullName = endpointName;
+ }
+
+ /* copy the string into our buffer */
+ newName = (char*)mem_alloc(CFStringGetLength(fullName) + 1);
+ CFStringGetCString(fullName, newName, CFStringGetLength(fullName) + 1,
+ defaultEncoding);
+
+ /* clean up */
+ if (endpointName) CFRelease(endpointName);
+ if (deviceName) CFRelease(deviceName);
+ if (fullName) CFRelease(fullName);
+
+ return newName;
+}
+
+static int _macosx_start(struct midi_port *p)
+{
+ struct macosx_midi *m;
+ m = (struct macosx_midi *)p->userdata;
+
+ if (p->io & MIDI_INPUT
+ && MIDIPortConnectSource(portIn, m->ep, (void*)p) != noErr) {
+ return 0;
+ }
+
+ if (p->io & MIDI_OUTPUT) {
+ m->pl = (MIDIPacketList*)m->packet;
+ m->x = NULL;
+ }
+ return 1;
+}
+static int _macosx_stop(struct midi_port *p)
+{
+ struct macosx_midi *m;
+ m = (struct macosx_midi *)p->userdata;
+ if (p->io & MIDI_INPUT
+ && MIDIPortDisconnectSource(portIn, m->ep) != noErr) {
+ return 0;
+ }
+ return 1;
+}
+
+static void _macosx_poll(struct midi_provider *p)
+{
+ struct macosx_midi *data;
+ MIDIEndpointRef ep;
+ int i;
+
+ int num_out, num_in;
+
+ num_out = MIDIGetNumberOfDestinations();
+ num_in = MIDIGetNumberOfSources();
+
+ for (i = max_outputs; i < num_out; i++) {
+ ep = MIDIGetDestination(i);
+ if (!ep) continue;
+ data = mem_alloc(sizeof(struct macosx_midi));
+ memcpy(&data->ep, &ep, sizeof(ep));
+ data->name = get_ep_name(ep);
+ midi_port_register(p, MIDI_OUTPUT, data->name, data, 1);
+ }
+ max_outputs = i;
+
+
+ for (i = max_inputs; i < num_in; i++) {
+ ep = MIDIGetSource(i);
+ if (!ep) continue;
+ data = mem_alloc(sizeof(struct macosx_midi));
+ memcpy(&data->ep, &ep, sizeof(ep));
+ data->name = get_ep_name(ep);
+ midi_port_register(p, MIDI_INPUT, data->name, data, 1);
+ }
+ max_inputs = i;
+
+}
+
+int macosx_midi_setup(void)
+{
+ static struct midi_driver driver;
+
+ memset(&driver,0,sizeof(driver));
+ driver.flags = MIDI_PORT_CAN_SCHEDULE;
+ driver.poll = _macosx_poll;
+ driver.thread = NULL;
+ driver.enable = _macosx_start;
+ driver.disable = _macosx_stop;
+ driver.send = _macosx_send;
+ driver.drain = _macosx_drain;
+
+ if (MIDIClientCreate(CFSTR("Schism Tracker"), NULL, NULL, &client) != noErr) {
+ return 0;
+ }
+ if (MIDIInputPortCreate(client, CFSTR("Input port"), readProc, NULL, &portIn) != noErr) {
+ return 0;
+ }
+ if (MIDIOutputPortCreate(client, CFSTR("Output port"), &portOut) != noErr) {
+ return 0;
+ }
+
+ if (!midi_provider_register("Mac OS X", &driver)) return 0;
+
+ return 1;
+}
+
+#endif
diff --git a/src/sys/macosx/osdefs.c b/src/sys/macosx/osdefs.c
new file mode 100644
index 0000000..57fd832
--- /dev/null
+++ b/src/sys/macosx/osdefs.c
@@ -0,0 +1,54 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "headers.h"
+#include "osdefs.h"
+#include "event.h"
+#include "song.h"
+
+const char *osname = "macosx";
+
+
+int macosx_sdlevent(SDL_Event *event)
+{
+ if (event->type == SDL_KEYDOWN || event->type == SDL_KEYUP) {
+ if (event->key.keysym.sym == 0) {
+ switch (event->key.keysym.scancode) {
+ case 106: // mac F16 key
+ event->key.keysym.sym = SDLK_PRINT;
+ event->key.keysym.mod = KMOD_CTRL;
+ return 1;
+ case 234: // XXX what key is this?
+ if (event->type == SDL_KEYDOWN)
+ song_set_current_order(song_get_current_order() - 1);
+ return 0;
+ case 233: // XXX what key is this?
+ if (event->type == SDL_KEYUP)
+ song_set_current_order(song_get_current_order() + 1);
+ return 0;
+ };
+ }
+ }
+ return 1;
+}
+
diff --git a/src/sys/macosx/volume-macosx.c b/src/sys/macosx/volume-macosx.c
new file mode 100644
index 0000000..d07d947
--- /dev/null
+++ b/src/sys/macosx/volume-macosx.c
@@ -0,0 +1,119 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "headers.h"
+
+#include "util.h"
+
+#ifdef MACOSX
+
+#include <CoreServices/CoreServices.h>
+#include <CoreAudio/AudioHardware.h>
+
+int macosx_volume_get_max(void);
+int macosx_volume_get_max(void)
+{
+ return 65535;
+}
+
+void macosx_volume_read(int *left, int *right);
+void macosx_volume_read(int *left, int *right)
+{
+ UInt32 size;
+ AudioDeviceID od;
+ OSStatus e;
+ UInt32 ch[2];
+ Float32 fl[2];
+ int i;
+
+ if (left) *left = 0;
+ if (right) *right = 0;
+
+ size=sizeof(od);
+ e = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
+ &size, &od);
+ if (e != 0) return;
+
+ size=sizeof(ch);
+ e = AudioDeviceGetProperty(od,
+ 0, /* QA1016 says "0" is master channel */
+ false,
+ kAudioDevicePropertyPreferredChannelsForStereo,
+ &size,
+ &ch);
+ if (e != 0) return;
+
+ for (i = 0; i < 2; i++) {
+ size = sizeof(Float32);
+ e = AudioDeviceGetProperty(od, /* device */
+ ch[i], /* preferred stereo channel */
+ false, /* output device */
+ kAudioDevicePropertyVolumeScalar,
+ &size,
+ &fl[i]);
+ if (e != 0) return;
+ }
+ if (left) *left = fl[0] * 65536.0f;
+ if (right) *right = fl[1] * 65536.0f;
+}
+
+void macosx_volume_write(int left, int right);
+void macosx_volume_write(int left, int right)
+{
+ UInt32 size;
+ AudioDeviceID od;
+ OSStatus e;
+ UInt32 ch[2];
+ Float32 fl[2];
+ int i;
+
+ size=sizeof(od);
+ e = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
+ &size, &od);
+ if (e != 0) return;
+
+ size=sizeof(ch);
+ e = AudioDeviceGetProperty(od,
+ 0, /* QA1016 says "0" is master channel */
+ false,
+ kAudioDevicePropertyPreferredChannelsForStereo,
+ &size,
+ &ch);
+ if (e != 0) return;
+
+ fl[0] = ((float)left) / 65536.0f;
+ fl[1] = ((float)right) / 65536.0f;
+
+ for (i = 0; i < 2; i++) {
+ e = AudioDeviceSetProperty(od, /* device */
+ NULL, /* no timestamp */
+ ch[i], /* preferred stereo channel */
+ false, /* output device */
+ kAudioDevicePropertyVolumeScalar,
+ sizeof(Float32),
+ &fl[i]);
+ if (e != 0) return;
+ }
+}
+
+#endif
diff --git a/src/sys/oss/midi-oss.c b/src/sys/oss/midi-oss.c
new file mode 100644
index 0000000..8d6f7ba
--- /dev/null
+++ b/src/sys/oss/midi-oss.c
@@ -0,0 +1,177 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "headers.h"
+
+#include "midi.h"
+
+#include "util.h"
+
+#ifdef USE_OSS
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/soundcard.h>
+#include <sys/poll.h>
+
+#include <errno.h>
+#include <fcntl.h>
+
+/* this is stupid; oss doesn't have a concept of ports... */
+#define MAX_OSS_MIDI 64
+
+#define MAX_MIDI_PORTS MAX_OSS_MIDI+2
+static int opened[MAX_MIDI_PORTS];
+
+
+static void _oss_send(struct midi_port *p, const unsigned char *data, unsigned int len,
+ UNUSED unsigned int delay)
+{
+ int fd, r, n;
+ fd = opened[ n = INT_SHAPED_PTR(p->userdata) ];
+ if (fd < 0) return;
+ while (len > 0) {
+ r = write(fd, data, len);
+ if (r < -1 && errno == EINTR) continue;
+ if (r < 1) {
+ /* err, can't happen? */
+ (void)close(opened[n]);
+ opened[n] = -1;
+ p->userdata = PTR_SHAPED_INT(-1);
+ p->io = 0; /* failure! */
+ return;
+ }
+ data += r;
+ len -= r;
+ }
+}
+
+static int _oss_start(UNUSED struct midi_port *p) { return 1; /* do nothing */ }
+static int _oss_stop(UNUSED struct midi_port *p) { return 1; /* do nothing */ }
+
+
+static int _oss_thread(struct midi_provider *p)
+{
+ struct pollfd pfd[MAX_MIDI_PORTS];
+ struct midi_port *ptr, *src;
+ unsigned char midi_buf[4096];
+ int i, j, r;
+
+ for (;;) {
+ ptr = NULL;
+ j = 0;
+ while (midi_port_foreach(p, &ptr)) {
+ i = INT_SHAPED_PTR(ptr->userdata);
+ if (i == -1) continue; /* err... */
+ if (!(ptr->io & MIDI_INPUT)) continue;
+ pfd[j].fd = i;
+ pfd[j].events = POLLIN;
+ pfd[j].revents = 0; /* RH 5 bug */
+ j++;
+ }
+ if (!j || poll(pfd, j, -1) < 1) {
+ sleep(1);
+ continue;
+ }
+ for (i = 0; i < j; i++) {
+ if (!(pfd[i].revents & POLLIN)) continue;
+ do {
+ r = read(pfd[i].fd, midi_buf, sizeof(midi_buf));
+ } while (r == -1 && errno == EINTR);
+ if (r > 0) {
+ ptr = src = NULL;
+ while (midi_port_foreach(p, &ptr)) {
+ if (INT_SHAPED_PTR(ptr->userdata) == pfd[i].fd) {
+ src = ptr;
+ }
+ }
+ midi_received_cb(src, midi_buf, r);
+ }
+ }
+ }
+ /* stupid gcc */
+ return 0;
+}
+
+
+static void _tryopen(int n, const char *name, struct midi_provider *_oss_provider)
+{
+ int io;
+ char *ptr;
+
+ if (opened[n+1] != -1) return;
+ opened[n+1] = open(name, O_RDWR|O_NOCTTY|O_NONBLOCK);
+ if (opened[n+1] == -1) {
+ opened[n+1] = open(name, O_RDONLY|O_NOCTTY|O_NONBLOCK);
+ if (opened[n+1] == -1) {
+ opened[n+1] = open(name, O_WRONLY|O_NOCTTY|O_NONBLOCK);
+ if (opened[n+1] == -1) return;
+ io = MIDI_OUTPUT;
+ } else {
+ io = MIDI_INPUT;
+ }
+ } else {
+ io = MIDI_INPUT | MIDI_OUTPUT;
+ }
+
+ ptr = NULL;
+ if (asprintf(&ptr, " %-16s (OSS)", name) == -1) {
+ return;
+ }
+ midi_port_register(_oss_provider, io, ptr, PTR_SHAPED_INT((long)n+1), 0);
+ free(ptr);
+}
+
+static void _oss_poll(struct midi_provider *_oss_provider)
+{
+ char sbuf[64];
+ int i;
+
+ _tryopen(-1, "/dev/midi", _oss_provider);
+ for (i = 0; i < MAX_OSS_MIDI; i++) {
+ sprintf(sbuf, "/dev/midi%d", i);
+ _tryopen(i, sbuf, _oss_provider);
+
+ sprintf(sbuf, "/dev/midi%02d", i);
+ _tryopen(i, sbuf, _oss_provider);
+ }
+}
+int oss_midi_setup(void)
+{
+ static struct midi_driver driver;
+ int i;
+
+ driver.flags = 0;
+ driver.poll = _oss_poll;
+ driver.thread = _oss_thread;
+ driver.enable = _oss_start;
+ driver.disable = _oss_stop;
+ driver.send = _oss_send;
+
+ for (i = 0; i < MAX_MIDI_PORTS; i++) opened[i] = -1;
+ if (!midi_provider_register("OSS", &driver)) return 0;
+ return 1;
+}
+#endif
diff --git a/src/sys/oss/volume-oss.c b/src/sys/oss/volume-oss.c
new file mode 100644
index 0000000..7771307
--- /dev/null
+++ b/src/sys/oss/volume-oss.c
@@ -0,0 +1,126 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "headers.h"
+
+#include "util.h"
+#include "log.h"
+
+#ifdef USE_OSS
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/soundcard.h>
+
+#include <errno.h>
+#include <fcntl.h>
+
+/* Hmm. I've found that some systems actually don't support the idea of a
+ * "master" volume, so this became necessary. I suppose PCM is really the
+ * more useful setting to change anyway. */
+#if 0
+# define SCHISM_MIXER_CONTROL SOUND_MIXER_VOLUME
+#else
+# define SCHISM_MIXER_CONTROL SOUND_MIXER_PCM
+#endif
+
+#define VOLUME_MAX 100
+
+/* --------------------------------------------------------------------- */
+
+static const char *device_file = NULL;
+
+/* --------------------------------------------------------------------- */
+
+static int open_mixer_device(void)
+{
+ const char *ptr;
+
+ if (!device_file) {
+ ptr = "/dev/sound/mixer";
+ if (access(ptr, F_OK) < 0) {
+ /* this had better work :) */
+ ptr = "/dev/mixer";
+ }
+ device_file = ptr;
+ }
+
+ return open(device_file, O_RDWR);
+}
+
+/* --------------------------------------------------------------------- */
+
+int oss_volume_get_max(void);
+int oss_volume_get_max(void)
+{
+ return VOLUME_MAX;
+}
+
+void oss_volume_read(int *left, int *right);
+void oss_volume_read(int *left, int *right)
+{
+ int fd;
+ uint8_t volume[4];
+
+ fd = open_mixer_device();
+ if (fd < 0) {
+ log_perror(device_file);
+ *left = *right = 0;
+ return;
+ }
+
+ if (ioctl(fd, MIXER_READ(SCHISM_MIXER_CONTROL), volume) == EOF) {
+ log_perror(device_file);
+ *left = *right = 0;
+ } else {
+ *left = volume[0];
+ *right = volume[1];
+ }
+
+ close(fd);
+}
+
+void oss_volume_write(int left, int right);
+void oss_volume_write(int left, int right)
+{
+ int fd;
+ uint8_t volume[4];
+
+ volume[0] = CLAMP(left, 0, VOLUME_MAX);
+ volume[1] = CLAMP(right, 0, VOLUME_MAX);
+
+ fd = open_mixer_device();
+ if (fd < 0) {
+ log_perror(device_file);
+ return;
+ }
+
+ if (ioctl(fd, MIXER_WRITE(SCHISM_MIXER_CONTROL), volume) == EOF) {
+ log_perror(device_file);
+ }
+
+ close(fd);
+}
+
+#endif
diff --git a/src/sys/posix/slurp-mmap.c b/src/sys/posix/slurp-mmap.c
new file mode 100644
index 0000000..9996486
--- /dev/null
+++ b/src/sys/posix/slurp-mmap.c
@@ -0,0 +1,68 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if HAVE_MMAP
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "slurp.h"
+
+static void _munmap_slurp(slurp_t *useme)
+{
+ (void)munmap((void*)useme->data, useme->length);
+ (void)close(useme->extra);
+}
+
+int slurp_mmap(slurp_t *useme, const char *filename, size_t st)
+{
+ int fd;
+ void *addr;
+
+ fd = open(filename, O_RDONLY);
+ if (fd == -1) return 0;
+ addr = mmap(NULL, st, PROT_READ, MAP_SHARED
+#if defined(MAP_POPULATE) && defined(MAP_NONBLOCK)
+ | MAP_POPULATE | MAP_NONBLOCK
+#endif
+#if defined(MAP_NORESERVE)
+ | MAP_NORESERVE
+#endif
+ , fd, 0);
+ if (!addr || addr == ((void*)-1)) {
+ (void)close(fd);
+ return -1;
+ }
+ useme->closure = _munmap_slurp;
+ useme->length = st;
+ useme->data = addr;
+ useme->extra = fd;
+ return 1;
+}
+
+#endif
diff --git a/src/sys/sdl/README b/src/sys/sdl/README
new file mode 100644
index 0000000..6e22655
--- /dev/null
+++ b/src/sys/sdl/README
@@ -0,0 +1,2 @@
+this directory will eventually have SDL-specific stuff in it.
+right now, schism is SDL specific :)
diff --git a/src/sys/stdlib/asprintf.c b/src/sys/stdlib/asprintf.c
new file mode 100644
index 0000000..002e573
--- /dev/null
+++ b/src/sys/stdlib/asprintf.c
@@ -0,0 +1,34 @@
+/* Like sprintf but provides a pointer to malloc'd storage, which must
+ be freed by the caller.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include <stdarg.h>
+
+int vasprintf(char **result, const char *format, va_list args);
+int asprintf(char **buf, const char *fmt, ...);
+int asprintf(char **buf, const char *fmt, ...)
+{
+ int status;
+ va_list ap;
+ va_start(ap, fmt);
+ status = vasprintf(buf, fmt, ap);
+ va_end(ap);
+ return status;
+}
diff --git a/src/sys/stdlib/memcmp.c b/src/sys/stdlib/memcmp.c
new file mode 100644
index 0000000..9178250
--- /dev/null
+++ b/src/sys/stdlib/memcmp.c
@@ -0,0 +1,12 @@
+#include <string.h> /* for size_t */
+int memcmp(const void *s1, const void *s2, size_t n);
+int memcmp(const void *s1, const void *s2, size_t n)
+{
+ register unsigned char *c1 = (unsigned char *) s1;
+ register unsigned char *c2 = (unsigned char *) s2;
+
+ while (n-- > 0)
+ if (*c1++ != *c2++)
+ return c1[-1] > c2[-1] ? 1 : -1;
+ return 0;
+}
diff --git a/src/sys/stdlib/mkstemp.c b/src/sys/stdlib/mkstemp.c
new file mode 100644
index 0000000..395df37
--- /dev/null
+++ b/src/sys/stdlib/mkstemp.c
@@ -0,0 +1,104 @@
+/* Copyright (C) 1991, 1992, 1996, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+#include <stdint.h>
+typedef uint64_t big_type;
+
+/* this ifdef crap lifted from slurp
+This is a hack!! We need binary mode files, but the 'b' flag to fdopen is
+evidently useless, so I'm doing it at this level instead. Dumb. */
+#ifndef O_BINARY
+# ifdef O_RAW
+# define O_BINARY O_RAW
+# else
+# define O_BINARY 0
+# endif
+#endif
+
+int mkstemp(char *template);
+
+/* Generate a unique temporary file name from TEMPLATE.
+ The last six characters of TEMPLATE must be "XXXXXX";
+ they are replaced with a string that makes the filename unique.
+ Returns a file descriptor open on the file for reading and writing. */
+int mkstemp(char *template)
+{
+ static const char letters[]
+ = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+ static big_type value;
+ struct timeval tv;
+ char *XXXXXX;
+ size_t len;
+ int count;
+
+ len = strlen (template);
+ if (len < 6 || strcmp (&template[len - 6], "XXXXXX"))
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* This is where the Xs start. */
+ XXXXXX = &template[len - 6];
+
+ /* Get some more or less random data. */
+ gettimeofday (&tv, NULL);
+ value += ((big_type) tv.tv_usec << 16) ^ tv.tv_sec ^ getpid ();
+
+ for (count = 0; count < TMP_MAX; ++count)
+ {
+ big_type v = value;
+ int fd;
+
+ /* Fill in the random bits. */
+ XXXXXX[0] = letters[v % 62];
+ v /= 62;
+ XXXXXX[1] = letters[v % 62];
+ v /= 62;
+ XXXXXX[2] = letters[v % 62];
+ v /= 62;
+ XXXXXX[3] = letters[v % 62];
+ v /= 62;
+ XXXXXX[4] = letters[v % 62];
+ v /= 62;
+ XXXXXX[5] = letters[v % 62];
+
+ fd = open (template, O_RDWR|O_CREAT|O_EXCL|O_BINARY, 0600);
+ if (fd >= 0)
+ /* The file does not exist. */
+ return fd;
+
+ /* This is a random value. It is only necessary that the next
+ TMP_MAX values generated by adding 7777 to VALUE are different
+ with (module 2^32). */
+ value += 7777;
+ }
+
+ /* We return the null string if we can't find a unique file name. */
+ template[0] = '\0';
+ return -1;
+}
+
diff --git a/src/sys/stdlib/strptime.c b/src/sys/stdlib/strptime.c
new file mode 100644
index 0000000..50d9dfc
--- /dev/null
+++ b/src/sys/stdlib/strptime.c
@@ -0,0 +1,396 @@
+/* $Id$ */
+/* $NetBSD: strptime.c,v 1.18 1999/04/29 02:58:30 tv Exp $ */
+
+/*-
+ * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code was contributed to The NetBSD Foundation by Klaus Klein.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define NEED_TIME
+#include "headers.h"
+#include <ctype.h>
+
+#define TM_YEAR_BASE 1900
+
+/*
+ * We do not implement alternate representations. However, we always
+ * check whether a given modifier is allowed for a certain conversion.
+ */
+#define ALT_E 0x01
+#define ALT_O 0x02
+#define LEGAL_ALT(x) { if (alt_format & ~(x)) return (0); }
+
+
+static int conv_num(const char **, int *, int, int);
+
+static const char *day[7] = {
+ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
+ "Friday", "Saturday"
+};
+static const char *abday[7] = {
+ "Sun","Mon","Tue","Wed","Thu","Fri","Sat"
+};
+static const char *mon[12] = {
+ "January", "February", "March", "April", "May", "June", "July",
+ "August", "September", "October", "November", "December"
+};
+static const char *abmon[12] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+static const char *am_pm[2] = {
+ "AM", "PM"
+};
+
+
+char *
+strptime(const char *buf, const char *fmt, struct tm *tm)
+{
+ char c;
+ const char *bp;
+ size_t len = 0;
+ int alt_format, i, split_year = 0;
+
+ bp = buf;
+
+ while ((c = *fmt) != '\0') {
+ /* Clear `alternate' modifier prior to new conversion. */
+ alt_format = 0;
+
+ /* Eat up white-space. */
+ if (isspace(c)) {
+ while (isspace(*bp))
+ bp++;
+
+ fmt++;
+ continue;
+ }
+
+ if ((c = *fmt++) != '%')
+ goto literal;
+
+
+again: switch (c = *fmt++) {
+ case '%': /* "%%" is converted to "%". */
+literal:
+ if (c != *bp++)
+ return (0);
+ break;
+
+ /*
+ * "Alternative" modifiers. Just set the appropriate flag
+ * and start over again.
+ */
+ case 'E': /* "%E?" alternative conversion modifier. */
+ LEGAL_ALT(0);
+ alt_format |= ALT_E;
+ goto again;
+
+ case 'O': /* "%O?" alternative conversion modifier. */
+ LEGAL_ALT(0);
+ alt_format |= ALT_O;
+ goto again;
+
+ /*
+ * "Complex" conversion rules, implemented through recursion.
+ */
+ case 'c': /* Date and time, using the locale's format. */
+ LEGAL_ALT(ALT_E);
+ if (!(bp = strptime(bp, "%x %X", tm)))
+ return (0);
+ break;
+
+ case 'D': /* The date as "%m/%d/%y". */
+ LEGAL_ALT(0);
+ if (!(bp = strptime(bp, "%m/%d/%y", tm)))
+ return (0);
+ break;
+
+ case 'R': /* The time as "%H:%M". */
+ LEGAL_ALT(0);
+ if (!(bp = strptime(bp, "%H:%M", tm)))
+ return (0);
+ break;
+
+ case 'r': /* The time in 12-hour clock representation. */
+ LEGAL_ALT(0);
+ if (!(bp = strptime(bp, "%I:%M:%S %p", tm)))
+ return (0);
+ break;
+
+ case 'T': /* The time as "%H:%M:%S". */
+ LEGAL_ALT(0);
+ if (!(bp = strptime(bp, "%H:%M:%S", tm)))
+ return (0);
+ break;
+
+ case 'X': /* The time, using the locale's format. */
+ LEGAL_ALT(ALT_E);
+ if (!(bp = strptime(bp, "%H:%M:%S", tm)))
+ return (0);
+ break;
+
+ case 'x': /* The date, using the locale's format. */
+ LEGAL_ALT(ALT_E);
+ if (!(bp = strptime(bp, "%m/%d/%y", tm)))
+ return (0);
+ break;
+
+ /*
+ * "Elementary" conversion rules.
+ */
+ case 'A': /* The day of week, using the locale's form. */
+ case 'a':
+ LEGAL_ALT(0);
+ for (i = 0; i < 7; i++) {
+ /* Full name. */
+ len = strlen(day[i]);
+ if (strncasecmp(day[i], bp, len) == 0)
+ break;
+
+ /* Abbreviated name. */
+ len = strlen(abday[i]);
+ if (strncasecmp(abday[i], bp, len) == 0)
+ break;
+ }
+
+ /* Nothing matched. */
+ if (i == 7)
+ return (0);
+
+ tm->tm_wday = i;
+ bp += len;
+ break;
+
+ case 'B': /* The month, using the locale's form. */
+ case 'b':
+ case 'h':
+ LEGAL_ALT(0);
+ for (i = 0; i < 12; i++) {
+ /* Full name. */
+ len = strlen(mon[i]);
+ if (strncasecmp(mon[i], bp, len) == 0)
+ break;
+
+ /* Abbreviated name. */
+ len = strlen(abmon[i]);
+ if (strncasecmp(abmon[i], bp, len) == 0)
+ break;
+ }
+
+ /* Nothing matched. */
+ if (i == 12)
+ return (0);
+
+ tm->tm_mon = i;
+ bp += len;
+ break;
+
+ case 'C': /* The century number. */
+ LEGAL_ALT(ALT_E);
+ if (!(conv_num(&bp, &i, 0, 99)))
+ return (0);
+
+ if (split_year) {
+ tm->tm_year = (tm->tm_year % 100) + (i * 100);
+ } else {
+ tm->tm_year = i * 100;
+ split_year = 1;
+ }
+ break;
+
+ case 'd': /* The day of month. */
+ case 'e':
+ LEGAL_ALT(ALT_O);
+ if (!(conv_num(&bp, &tm->tm_mday, 1, 31)))
+ return (0);
+ break;
+
+ case 'k': /* The hour (24-hour clock representation). */
+ LEGAL_ALT(0);
+ /* FALLTHROUGH */
+ case 'H':
+ LEGAL_ALT(ALT_O);
+ if (!(conv_num(&bp, &tm->tm_hour, 0, 23)))
+ return (0);
+ break;
+
+ case 'l': /* The hour (12-hour clock representation). */
+ LEGAL_ALT(0);
+ /* FALLTHROUGH */
+ case 'I':
+ LEGAL_ALT(ALT_O);
+ if (!(conv_num(&bp, &tm->tm_hour, 1, 12)))
+ return (0);
+ if (tm->tm_hour == 12)
+ tm->tm_hour = 0;
+ break;
+
+ case 'j': /* The day of year. */
+ LEGAL_ALT(0);
+ if (!(conv_num(&bp, &i, 1, 366)))
+ return (0);
+ tm->tm_yday = i - 1;
+ break;
+
+ case 'M': /* The minute. */
+ LEGAL_ALT(ALT_O);
+ if (!(conv_num(&bp, &tm->tm_min, 0, 59)))
+ return (0);
+ break;
+
+ case 'm': /* The month. */
+ LEGAL_ALT(ALT_O);
+ if (!(conv_num(&bp, &i, 1, 12)))
+ return (0);
+ tm->tm_mon = i - 1;
+ break;
+
+ case 'p': /* The locale's equivalent of AM/PM. */
+ LEGAL_ALT(0);
+ /* AM? */
+ if (strcasecmp(am_pm[0], bp) == 0) {
+ if (tm->tm_hour > 11)
+ return (0);
+
+ bp += strlen(am_pm[0]);
+ break;
+ }
+ /* PM? */
+ else if (strcasecmp(am_pm[1], bp) == 0) {
+ if (tm->tm_hour > 11)
+ return (0);
+
+ tm->tm_hour += 12;
+ bp += strlen(am_pm[1]);
+ break;
+ }
+
+ /* Nothing matched. */
+ return (0);
+
+ case 'S': /* The seconds. */
+ LEGAL_ALT(ALT_O);
+ if (!(conv_num(&bp, &tm->tm_sec, 0, 61)))
+ return (0);
+ break;
+
+ case 'U': /* The week of year, beginning on sunday. */
+ case 'W': /* The week of year, beginning on monday. */
+ LEGAL_ALT(ALT_O);
+ /*
+ * XXX This is bogus, as we can not assume any valid
+ * information present in the tm structure at this
+ * point to calculate a real value, so just check the
+ * range for now.
+ */
+ if (!(conv_num(&bp, &i, 0, 53)))
+ return (0);
+ break;
+
+ case 'w': /* The day of week, beginning on sunday. */
+ LEGAL_ALT(ALT_O);
+ if (!(conv_num(&bp, &tm->tm_wday, 0, 6)))
+ return (0);
+ break;
+
+ case 'Y': /* The year. */
+ LEGAL_ALT(ALT_E);
+ if (!(conv_num(&bp, &i, 0, 9999)))
+ return (0);
+
+ tm->tm_year = i - TM_YEAR_BASE;
+ break;
+
+ case 'y': /* The year within 100 years of the epoch. */
+ LEGAL_ALT(ALT_E | ALT_O);
+ if (!(conv_num(&bp, &i, 0, 99)))
+ return (0);
+
+ if (split_year) {
+ tm->tm_year = ((tm->tm_year / 100) * 100) + i;
+ break;
+ }
+ split_year = 1;
+ if (i <= 68)
+ tm->tm_year = i + 2000 - TM_YEAR_BASE;
+ else
+ tm->tm_year = i + 1900 - TM_YEAR_BASE;
+ break;
+
+ /*
+ * Miscellaneous conversions.
+ */
+ case 'n': /* Any kind of white-space. */
+ case 't':
+ LEGAL_ALT(0);
+ while (isspace(*bp))
+ bp++;
+ break;
+
+
+ default: /* Unknown/unsupported conversion. */
+ return (0);
+ }
+
+
+ }
+
+ /* LINTED functional specification */
+ return ((char *)bp);
+}
+
+
+static int
+conv_num(const char **buf, int *dest, int llim, int ulim)
+{
+ int result = 0;
+
+ /* The limit also determines the number of valid digits. */
+ int rulim = ulim;
+
+ if (**buf < '0' || **buf > '9')
+ return (0);
+
+ do {
+ result *= 10;
+ result += *(*buf)++ - '0';
+ rulim /= 10;
+ } while ((result * 10 <= ulim) && rulim && **buf >= '0' && **buf <= '9');
+
+ if (result < llim || result > ulim)
+ return (0);
+
+ *dest = result;
+ return (1);
+}
diff --git a/src/sys/stdlib/vasprintf.c b/src/sys/stdlib/vasprintf.c
new file mode 100644
index 0000000..f767645
--- /dev/null
+++ b/src/sys/stdlib/vasprintf.c
@@ -0,0 +1,97 @@
+/* Like vsprintf but provides a pointer to malloc'd storage, which must
+ be freed by the caller.
+ Copyright (C) 1994 Free Software Foundation, Inc.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <stdlib.h>
+#include <stdarg.h>
+
+static int int_vasprintf(char **result, const char *format, va_list *args)
+{
+ const char *p = format;
+ /* Add one to make sure that it is never zero, which might cause malloc
+ to return NULL. */
+ int total_width = strlen (format) + 1;
+ va_list ap;
+
+ memcpy(&ap, args, sizeof(va_list));
+
+ while (*p != '\0') {
+ if (*p++ == '%') {
+ while (strchr ("-+ #0", *p))
+ ++p;
+ if (*p == '*') {
+ ++p;
+ total_width += abs(va_arg (ap, int));
+ } else
+ total_width += strtoul(p, (char **) &p, 10);
+ if (*p == '.') {
+ ++p;
+ if (*p == '*') {
+ ++p;
+ total_width += abs (va_arg (ap, int));
+ } else
+ total_width += strtoul(p, (char **) &p, 10);
+ }
+ while (strchr ("hlL", *p))
+ ++p;
+ /* Should be big enough for any format specifier except %s and floats. */
+ total_width += 30;
+ switch (*p) {
+ case 'd':
+ case 'i':
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X':
+ case 'c':
+ (void) va_arg (ap, int);
+ break;
+ case 'f':
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G':
+ (void) va_arg (ap, double);
+ /* Since an ieee double can have an exponent of 307, we'll
+ make the buffer wide enough to cover the gross case. */
+ total_width += 307;
+ break;
+ case 's':
+ total_width += strlen (va_arg (ap, char *));
+ break;
+ case 'p':
+ case 'n':
+ (void) va_arg (ap, char *);
+ break;
+ }
+ }
+ }
+ *result = (char*)malloc (total_width);
+ return vsprintf (*result, format, *args);
+}
+
+int vasprintf(char **result, const char *format, va_list args);
+int vasprintf(char **result, const char *format, va_list args)
+{
+ return int_vasprintf (result, format, &args);
+}
diff --git a/src/sys/wii/certs_bin.h b/src/sys/wii/certs_bin.h
new file mode 100644
index 0000000..95091c3
--- /dev/null
+++ b/src/sys/wii/certs_bin.h
@@ -0,0 +1,163 @@
+static unsigned const char certs_bin[] = {
+'\000', '\001', '\000', '\000', '\263', '\255', '\263', '\042', '\153', '\074', '\075', '\377', '\033', '\113', '\100', '\167',
+'\026', '\377', '\117', '\172', '\327', '\144', '\206', '\310', '\225', '\254', '\126', '\055', '\041', '\361', '\006', '\001',
+'\324', '\366', '\144', '\050', '\031', '\034', '\007', '\166', '\217', '\337', '\032', '\342', '\316', '\173', '\047', '\311',
+'\017', '\274', '\012', '\320', '\061', '\045', '\170', '\354', '\007', '\171', '\266', '\127', '\324', '\067', '\044', '\023',
+'\247', '\370', '\157', '\014', '\024', '\300', '\357', '\156', '\011', '\101', '\355', '\053', '\005', '\354', '\071', '\127',
+'\066', '\007', '\211', '\000', '\112', '\207', '\215', '\056', '\235', '\370', '\307', '\245', '\251', '\370', '\312', '\263',
+'\021', '\261', '\030', '\171', '\127', '\273', '\370', '\230', '\342', '\242', '\124', '\002', '\317', '\124', '\071', '\317',
+'\053', '\277', '\240', '\341', '\370', '\134', '\006', '\156', '\203', '\232', '\340', '\224', '\312', '\107', '\340', '\025',
+'\130', '\365', '\156', '\157', '\064', '\351', '\052', '\242', '\334', '\070', '\223', '\176', '\067', '\315', '\214', '\134',
+'\115', '\375', '\057', '\021', '\117', '\350', '\150', '\311', '\250', '\331', '\376', '\330', '\156', '\014', '\041', '\165',
+'\242', '\275', '\176', '\211', '\271', '\307', '\265', '\023', '\364', '\032', '\171', '\141', '\104', '\071', '\020', '\357',
+'\371', '\327', '\376', '\127', '\042', '\030', '\325', '\155', '\373', '\177', '\111', '\172', '\244', '\313', '\220', '\324',
+'\361', '\256', '\261', '\166', '\344', '\150', '\135', '\247', '\224', '\100', '\140', '\230', '\057', '\004', '\110', '\100',
+'\037', '\317', '\306', '\272', '\353', '\332', '\026', '\060', '\264', '\163', '\264', '\025', '\043', '\065', '\010', '\007',
+'\012', '\237', '\117', '\211', '\170', '\346', '\054', '\354', '\136', '\222', '\106', '\245', '\250', '\275', '\240', '\205',
+'\170', '\150', '\165', '\014', '\072', '\021', '\057', '\257', '\225', '\350', '\070', '\310', '\231', '\016', '\207', '\261',
+'\142', '\315', '\020', '\332', '\263', '\061', '\226', '\145', '\357', '\210', '\233', '\124', '\033', '\263', '\066', '\273',
+'\147', '\123', '\237', '\257', '\302', '\256', '\055', '\012', '\056', '\165', '\300', '\043', '\164', '\352', '\116', '\254',
+'\215', '\231', '\120', '\177', '\131', '\271', '\123', '\167', '\060', '\137', '\046', '\065', '\306', '\010', '\251', '\220',
+'\223', '\254', '\217', '\306', '\336', '\043', '\271', '\172', '\352', '\160', '\264', '\304', '\317', '\146', '\263', '\016',
+'\130', '\062', '\016', '\305', '\266', '\162', '\004', '\110', '\316', '\073', '\261', '\034', '\123', '\037', '\313', '\160',
+'\050', '\174', '\265', '\302', '\174', '\147', '\117', '\273', '\375', '\214', '\177', '\311', '\102', '\040', '\244', '\163',
+'\043', '\035', '\130', '\176', '\132', '\032', '\032', '\202', '\343', '\165', '\171', '\241', '\273', '\202', '\156', '\316',
+'\001', '\161', '\311', '\165', '\143', '\107', '\113', '\035', '\106', '\346', '\171', '\262', '\202', '\067', '\142', '\021',
+'\315', '\307', '\000', '\057', '\106', '\207', '\302', '\074', '\155', '\300', '\325', '\265', '\170', '\156', '\341', '\362',
+'\163', '\377', '\001', '\222', '\120', '\017', '\364', '\307', '\120', '\152', '\356', '\162', '\266', '\364', '\075', '\366',
+'\010', '\376', '\245', '\203', '\241', '\371', '\206', '\017', '\207', '\257', '\122', '\104', '\124', '\273', '\107', '\303',
+'\006', '\014', '\224', '\351', '\233', '\367', '\326', '\062', '\247', '\310', '\253', '\113', '\117', '\365', '\065', '\041',
+'\037', '\301', '\200', '\107', '\273', '\172', '\372', '\132', '\053', '\327', '\270', '\204', '\255', '\216', '\126', '\117',
+'\133', '\211', '\377', '\067', '\227', '\067', '\361', '\365', '\001', '\073', '\037', '\236', '\304', '\030', '\157', '\222',
+'\052', '\325', '\304', '\263', '\300', '\325', '\207', '\013', '\234', '\004', '\257', '\032', '\265', '\363', '\274', '\155',
+'\012', '\361', '\175', '\107', '\010', '\344', '\103', '\351', '\163', '\367', '\267', '\160', '\167', '\124', '\272', '\363',
+'\354', '\322', '\254', '\111', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\122', '\157', '\157', '\164', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\001', '\103', '\101', '\060', '\060', '\060', '\060', '\060', '\060', '\060', '\061', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\133', '\372', '\175', '\134', '\262', '\171', '\311', '\342', '\356', '\341', '\041', '\306',
+'\352', '\364', '\117', '\366', '\071', '\370', '\217', '\007', '\213', '\113', '\167', '\355', '\237', '\225', '\140', '\260',
+'\065', '\202', '\201', '\265', '\016', '\125', '\253', '\162', '\021', '\025', '\241', '\167', '\160', '\074', '\172', '\060',
+'\376', '\072', '\351', '\357', '\034', '\140', '\274', '\035', '\227', '\106', '\166', '\262', '\072', '\150', '\314', '\004',
+'\261', '\230', '\122', '\133', '\311', '\150', '\361', '\035', '\342', '\333', '\120', '\344', '\331', '\347', '\360', '\161',
+'\345', '\142', '\332', '\342', '\011', '\042', '\063', '\351', '\323', '\143', '\366', '\035', '\327', '\301', '\237', '\363',
+'\244', '\251', '\036', '\217', '\145', '\123', '\324', '\161', '\335', '\173', '\204', '\271', '\361', '\270', '\316', '\163',
+'\065', '\360', '\365', '\124', '\005', '\143', '\241', '\352', '\270', '\071', '\143', '\340', '\233', '\351', '\001', '\001',
+'\037', '\231', '\124', '\143', '\141', '\050', '\160', '\040', '\351', '\314', '\015', '\253', '\110', '\177', '\024', '\015',
+'\146', '\046', '\241', '\203', '\155', '\047', '\021', '\037', '\040', '\150', '\336', '\107', '\162', '\024', '\221', '\121',
+'\317', '\151', '\306', '\033', '\246', '\016', '\371', '\331', '\111', '\240', '\367', '\037', '\124', '\231', '\362', '\323',
+'\232', '\322', '\214', '\160', '\005', '\064', '\202', '\223', '\304', '\061', '\377', '\275', '\063', '\366', '\274', '\246',
+'\015', '\307', '\031', '\136', '\242', '\274', '\305', '\155', '\040', '\013', '\257', '\155', '\006', '\320', '\234', '\101',
+'\333', '\215', '\351', '\307', '\040', '\025', '\114', '\244', '\203', '\053', '\151', '\300', '\214', '\151', '\315', '\073',
+'\007', '\072', '\000', '\143', '\140', '\057', '\106', '\055', '\063', '\200', '\141', '\245', '\352', '\154', '\221', '\134',
+'\325', '\142', '\065', '\171', '\303', '\353', '\144', '\316', '\104', '\357', '\130', '\155', '\024', '\272', '\252', '\210',
+'\064', '\001', '\233', '\076', '\353', '\356', '\323', '\171', '\000', '\001', '\000', '\001', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\001', '\000', '\001', '\116', '\000', '\137', '\361', '\077', '\206', '\165', '\215', '\266', '\234', '\105', '\143',
+'\017', '\324', '\233', '\364', '\314', '\135', '\124', '\317', '\314', '\042', '\064', '\162', '\127', '\253', '\244', '\272',
+'\123', '\322', '\263', '\075', '\346', '\354', '\236', '\241', '\127', '\124', '\123', '\256', '\137', '\223', '\075', '\226',
+'\277', '\367', '\314', '\172', '\171', '\126', '\156', '\204', '\173', '\033', '\140', '\167', '\302', '\251', '\070', '\161',
+'\060', '\032', '\214', '\323', '\311', '\075', '\115', '\263', '\046', '\351', '\207', '\222', '\146', '\351', '\323', '\272',
+'\237', '\171', '\274', '\106', '\070', '\372', '\055', '\040', '\240', '\072', '\160', '\147', '\244', '\021', '\247', '\240',
+'\267', '\331', '\022', '\255', '\021', '\152', '\072', '\304', '\156', '\062', '\102', '\107', '\302', '\010', '\272', '\264',
+'\224', '\234', '\305', '\056', '\320', '\057', '\031', '\366', '\121', '\340', '\337', '\056', '\066', '\123', '\252', '\257',
+'\227', '\246', '\222', '\273', '\251', '\035', '\330', '\156', '\044', '\056', '\263', '\010', '\167', '\125', '\021', '\316',
+'\230', '\366', '\242', '\364', '\046', '\311', '\047', '\004', '\320', '\374', '\215', '\324', '\200', '\236', '\327', '\141',
+'\275', '\021', '\267', '\205', '\224', '\214', '\326', '\320', '\172', '\333', '\244', '\010', '\320', '\360', '\206', '\366',
+'\132', '\256', '\031', '\024', '\262', '\210', '\232', '\250', '\256', '\112', '\242', '\252', '\307', '\141', '\251', '\015',
+'\101', '\054', '\261', '\120', '\011', '\253', '\076', '\223', '\374', '\251', '\044', '\336', '\316', '\117', '\174', '\006',
+'\253', '\334', '\056', '\140', '\235', '\150', '\276', '\000', '\163', '\372', '\200', '\127', '\152', '\024', '\136', '\355',
+'\304', '\213', '\164', '\062', '\207', '\007', '\223', '\310', '\374', '\246', '\330', '\076', '\011', '\156', '\305', '\362',
+'\251', '\304', '\041', '\347', '\110', '\263', '\163', '\100', '\133', '\342', '\372', '\212', '\341', '\130', '\170', '\351',
+'\325', '\043', '\210', '\165', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\122', '\157', '\157', '\164', '\055', '\103', '\101', '\060', '\060', '\060', '\060', '\060', '\060', '\060', '\061', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\001', '\103', '\120', '\060', '\060', '\060', '\060', '\060', '\060', '\060', '\064', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\361', '\270', '\240', '\144', '\301', '\155', '\363', '\203', '\051', '\125', '\303', '\051',
+'\133', '\162', '\360', '\063', '\056', '\227', '\357', '\024', '\204', '\212', '\150', '\004', '\234', '\246', '\216', '\254',
+'\336', '\024', '\120', '\063', '\270', '\154', '\020', '\215', '\110', '\063', '\134', '\135', '\014', '\253', '\167', '\004',
+'\142', '\124', '\107', '\125', '\105', '\052', '\220', '\000', '\160', '\261', '\126', '\222', '\134', '\027', '\206', '\342',
+'\315', '\040', '\155', '\314', '\334', '\054', '\056', '\067', '\156', '\047', '\374', '\264', '\040', '\146', '\314', '\012',
+'\214', '\351', '\376', '\350', '\127', '\004', '\346', '\312', '\143', '\032', '\056', '\176', '\221', '\176', '\224', '\174',
+'\071', '\221', '\167', '\066', '\051', '\321', '\125', '\141', '\205', '\273', '\327', '\267', '\163', '\312', '\067', '\107',
+'\236', '\137', '\252', '\243', '\266', '\005', '\340', '\001', '\341', '\254', '\345', '\215', '\330', '\370', '\107', '\202',
+'\326', '\105', '\374', '\343', '\241', '\315', '\003', '\253', '\066', '\360', '\363', '\206', '\261', '\242', '\321', '\067',
+'\100', '\241', '\224', '\212', '\123', '\272', '\033', '\015', '\214', '\110', '\143', '\315', '\153', '\054', '\056', '\040',
+'\144', '\224', '\200', '\114', '\142', '\372', '\251', '\072', '\176', '\063', '\251', '\352', '\170', '\153', '\131', '\312',
+'\343', '\253', '\066', '\105', '\364', '\313', '\217', '\327', '\220', '\153', '\202', '\150', '\315', '\254', '\361', '\173',
+'\072', '\354', '\106', '\203', '\033', '\221', '\366', '\336', '\030', '\141', '\203', '\274', '\113', '\062', '\147', '\223',
+'\307', '\056', '\120', '\331', '\036', '\066', '\240', '\334', '\342', '\271', '\175', '\240', '\041', '\076', '\106', '\226',
+'\002', '\037', '\063', '\034', '\276', '\256', '\215', '\374', '\222', '\207', '\062', '\252', '\104', '\334', '\170', '\347',
+'\031', '\232', '\075', '\335', '\127', '\042', '\176', '\236', '\167', '\336', '\062', '\143', '\206', '\223', '\154', '\021',
+'\254', '\247', '\017', '\201', '\031', '\323', '\072', '\231', '\000', '\001', '\000', '\001', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\001', '\000', '\001', '\175', '\235', '\136', '\272', '\122', '\201', '\334', '\247', '\006', '\135', '\057', '\010',
+'\150', '\333', '\212', '\307', '\072', '\316', '\176', '\251', '\221', '\361', '\226', '\237', '\341', '\320', '\362', '\301',
+'\037', '\256', '\300', '\303', '\360', '\032', '\334', '\264', '\106', '\255', '\345', '\312', '\003', '\266', '\045', '\041',
+'\224', '\142', '\306', '\341', '\101', '\015', '\271', '\346', '\077', '\336', '\230', '\321', '\257', '\046', '\073', '\114',
+'\262', '\207', '\204', '\047', '\202', '\162', '\357', '\047', '\023', '\113', '\207', '\302', '\130', '\326', '\173', '\142',
+'\362', '\265', '\277', '\234', '\266', '\272', '\214', '\211', '\031', '\056', '\305', '\006', '\211', '\254', '\164', '\044',
+'\240', '\042', '\011', '\100', '\003', '\356', '\230', '\244', '\275', '\057', '\001', '\073', '\131', '\077', '\345', '\146',
+'\154', '\325', '\353', '\132', '\327', '\244', '\223', '\020', '\363', '\116', '\373', '\264', '\075', '\106', '\313', '\361',
+'\265', '\043', '\317', '\202', '\366', '\216', '\265', '\155', '\271', '\004', '\247', '\302', '\250', '\053', '\341', '\035',
+'\170', '\323', '\233', '\242', '\015', '\220', '\323', '\007', '\102', '\333', '\136', '\172', '\301', '\357', '\362', '\041',
+'\121', '\011', '\142', '\317', '\251', '\024', '\250', '\200', '\334', '\364', '\027', '\272', '\231', '\223', '\012', '\356',
+'\010', '\260', '\260', '\345', '\032', '\076', '\237', '\257', '\315', '\302', '\327', '\343', '\313', '\241', '\057', '\072',
+'\300', '\007', '\220', '\336', '\104', '\172', '\303', '\305', '\070', '\250', '\147', '\222', '\070', '\007', '\213', '\324',
+'\304', '\262', '\105', '\254', '\051', '\026', '\210', '\155', '\052', '\016', '\131', '\116', '\355', '\134', '\310', '\065',
+'\151', '\213', '\115', '\142', '\070', '\337', '\005', '\162', '\115', '\314', '\366', '\201', '\200', '\212', '\160', '\164',
+'\006', '\131', '\060', '\277', '\370', '\121', '\101', '\067', '\350', '\025', '\372', '\272', '\241', '\162', '\270', '\340',
+'\151', '\154', '\141', '\344', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\122', '\157', '\157', '\164', '\055', '\103', '\101', '\060', '\060', '\060', '\060', '\060', '\060', '\060', '\061', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\001', '\130', '\123', '\060', '\060', '\060', '\060', '\060', '\060', '\060', '\063', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\361', '\270', '\237', '\321', '\255', '\007', '\251', '\067', '\212', '\173', '\020', '\014',
+'\175', '\307', '\071', '\276', '\236', '\335', '\267', '\062', '\000', '\211', '\253', '\045', '\261', '\370', '\161', '\257',
+'\132', '\251', '\364', '\130', '\236', '\321', '\203', '\002', '\062', '\216', '\201', '\032', '\037', '\357', '\320', '\011',
+'\310', '\006', '\066', '\103', '\370', '\124', '\271', '\341', '\073', '\273', '\141', '\072', '\172', '\317', '\207', '\024',
+'\205', '\153', '\244', '\133', '\252', '\347', '\273', '\306', '\116', '\262', '\367', '\135', '\207', '\353', '\362', '\147',
+'\355', '\017', '\244', '\101', '\251', '\063', '\146', '\136', '\127', '\175', '\132', '\336', '\253', '\373', '\106', '\056',
+'\166', '\000', '\312', '\234', '\351', '\115', '\304', '\313', '\230', '\071', '\222', '\253', '\172', '\057', '\263', '\243',
+'\236', '\242', '\277', '\234', '\123', '\354', '\320', '\334', '\372', '\153', '\213', '\136', '\262', '\313', '\244', '\017',
+'\372', '\100', '\165', '\370', '\362', '\262', '\336', '\227', '\070', '\021', '\207', '\055', '\365', '\342', '\246', '\303',
+'\213', '\057', '\334', '\216', '\127', '\335', '\275', '\137', '\106', '\353', '\047', '\326', '\031', '\122', '\366', '\256',
+'\370', '\142', '\267', '\356', '\232', '\306', '\202', '\242', '\261', '\232', '\251', '\265', '\130', '\373', '\353', '\263',
+'\211', '\057', '\275', '\120', '\311', '\365', '\334', '\112', '\156', '\234', '\233', '\376', '\105', '\200', '\064', '\251',
+'\102', '\030', '\055', '\336', '\267', '\137', '\340', '\321', '\263', '\337', '\016', '\227', '\343', '\231', '\200', '\207',
+'\160', '\030', '\302', '\262', '\203', '\361', '\065', '\165', '\174', '\132', '\060', '\374', '\077', '\060', '\204', '\244',
+'\232', '\252', '\300', '\036', '\347', '\006', '\151', '\117', '\216', '\024', '\110', '\332', '\022', '\072', '\314', '\117',
+'\372', '\046', '\252', '\070', '\367', '\357', '\277', '\047', '\217', '\066', '\227', '\171', '\167', '\135', '\267', '\305',
+'\255', '\307', '\211', '\221', '\334', '\370', '\103', '\215', '\000', '\001', '\000', '\001', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+
+};
diff --git a/src/sys/wii/data/certs.bin b/src/sys/wii/data/certs.bin
new file mode 100644
index 0000000..2184107
--- /dev/null
+++ b/src/sys/wii/data/certs.bin
Binary files differ
diff --git a/src/sys/wii/data/su_tik.bin b/src/sys/wii/data/su_tik.bin
new file mode 100644
index 0000000..eb2bd12
--- /dev/null
+++ b/src/sys/wii/data/su_tik.bin
Binary files differ
diff --git a/src/sys/wii/data/su_tmd.bin b/src/sys/wii/data/su_tmd.bin
new file mode 100644
index 0000000..7f68618
--- /dev/null
+++ b/src/sys/wii/data/su_tmd.bin
Binary files differ
diff --git a/src/sys/wii/isfs.c b/src/sys/wii/isfs.c
new file mode 100644
index 0000000..6168864
--- /dev/null
+++ b/src/sys/wii/isfs.c
@@ -0,0 +1,445 @@
+/*
+
+libisfs -- a NAND filesystem devoptab library for the Wii
+
+Copyright (C) 2008 Joseph Jordan <joe.ftpii@psychlaw.com.au>
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from
+the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1.The origin of this software must not be misrepresented; you must not
+claim that you wrote the original software. If you use this software in a
+product, an acknowledgment in the product documentation would be
+appreciated but is not required.
+
+2.Altered source versions must be plainly marked as such, and must not be
+misrepresented as being the original software.
+
+3.This notice may not be removed or altered from any source distribution.
+
+
+[In compliance with the above: I patched this code up somewhat so that it
+builds with all warnings. -- Storlek]
+*/
+#include <errno.h>
+#include <ogc/isfs.h>
+#include <ogc/lwp_watchdog.h>
+#include <ogcsys.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/dir.h>
+#include <sys/iosupport.h>
+
+#include "isfs.h"
+
+#define DEVICE_NAME "isfs"
+
+#define FLAG_DIR 1
+#define DIR_SEPARATOR '/'
+#define SECTOR_SIZE 0x800
+#define BUFFER_SIZE 0x8000
+
+#define UNUSED __attribute__((unused))
+
+typedef struct DIR_ENTRY_STRUCT {
+ char *name;
+ char *abspath;
+ u32 size;
+ u8 flags;
+ u32 fileCount;
+ struct DIR_ENTRY_STRUCT *children;
+} DIR_ENTRY;
+
+typedef struct {
+ DIR_ENTRY *entry;
+ s32 isfs_fd;
+ bool inUse;
+} FILE_STRUCT;
+
+typedef struct {
+ DIR_ENTRY *entry;
+ u32 index;
+ bool inUse;
+} DIR_STATE_STRUCT;
+
+static char read_buffer[BUFFER_SIZE] __attribute__((aligned(32)));
+
+static DIR_ENTRY *root = NULL;
+static DIR_ENTRY *current = NULL;
+static s32 dotab_device = -1;
+
+static bool is_dir(DIR_ENTRY *entry) {
+ return entry->flags & FLAG_DIR;
+}
+
+static bool invalid_drive_specifier(const char *path) {
+ if (strchr(path, ':') == NULL) return false;
+ int namelen = strlen(DEVICE_NAME);
+ if (!strncmp(DEVICE_NAME, path, namelen) && path[namelen] == ':') return false;
+ return true;
+}
+
+static DIR_ENTRY *entry_from_path(const char *path) {
+ if (invalid_drive_specifier(path)) return NULL;
+ if (strchr(path, ':') != NULL) path = strchr(path, ':') + 1;
+ DIR_ENTRY *entry;
+ bool found = false;
+ bool notFound = false;
+ const char *pathPosition = path;
+ const char *pathEnd = strchr(path, '\0');
+ if (pathPosition[0] == DIR_SEPARATOR) {
+ entry = root;
+ while (pathPosition[0] == DIR_SEPARATOR) pathPosition++;
+ if (pathPosition >= pathEnd) found = true;
+ } else {
+ entry = current;
+ }
+ if (entry == root && !strcmp(".", pathPosition)) found = true;
+ DIR_ENTRY *dir = entry;
+ while (!found && !notFound) {
+ const char *nextPathPosition = strchr(pathPosition, DIR_SEPARATOR);
+ size_t dirnameLength;
+ if (nextPathPosition != NULL) dirnameLength = nextPathPosition - pathPosition;
+ else dirnameLength = strlen(pathPosition);
+ if (dirnameLength >= ISFS_MAXPATHLEN) return NULL;
+
+ u32 fileIndex = 0;
+ while (fileIndex < dir->fileCount && !found && !notFound) {
+ entry = &dir->children[fileIndex];
+ if (dirnameLength == strnlen(entry->name, ISFS_MAXPATHLEN - 1)
+ && !strncasecmp(pathPosition, entry->name, dirnameLength)) found = true;
+ if (found && !is_dir(entry) && nextPathPosition) found = false;
+ if (!found) fileIndex++;
+ }
+
+ if (fileIndex >= dir->fileCount) {
+ notFound = true;
+ found = false;
+ } else if (!nextPathPosition || nextPathPosition >= pathEnd) {
+ found = true;
+ } else if (is_dir(entry)) {
+ dir = entry;
+ pathPosition = nextPathPosition;
+ while (pathPosition[0] == DIR_SEPARATOR) pathPosition++;
+ if (pathPosition >= pathEnd) found = true;
+ else found = false;
+ }
+ }
+
+ if (found && !notFound) return entry;
+ return NULL;
+}
+
+static int _ISFS_open_r(struct _reent *r, void *fileStruct, const char *path,
+ UNUSED int flags, UNUSED int mode) {
+ FILE_STRUCT *file = (FILE_STRUCT *)fileStruct;
+ DIR_ENTRY *entry = entry_from_path(path);
+ if (!entry) {
+ r->_errno = ENOENT;
+ return -1;
+ } else if (is_dir(entry)) {
+ r->_errno = EISDIR;
+ return -1;
+ }
+
+ file->entry = entry;
+ file->inUse = true;
+ file->isfs_fd = ISFS_Open(entry->abspath, ISFS_OPEN_READ);
+ if (file->isfs_fd < 0) {
+ if (file->isfs_fd == ISFS_EINVAL) r->_errno = EACCES;
+ else r->_errno = -file->isfs_fd;
+ return -1;
+ }
+
+ return (int)file;
+}
+
+static int _ISFS_close_r(struct _reent *r, int fd) {
+ FILE_STRUCT *file = (FILE_STRUCT *)fd;
+ if (!file->inUse) {
+ r->_errno = EBADF;
+ return -1;
+ }
+ file->inUse = false;
+
+ s32 ret = ISFS_Close(file->isfs_fd);
+ if (ret < 0) {
+ r->_errno = -ret;
+ return -1;
+ }
+
+ return 0;
+}
+
+static int _ISFS_read_r(struct _reent *r, int fd, char *ptr, size_t len) {
+ FILE_STRUCT *file = (FILE_STRUCT *)fd;
+ if (!file->inUse) {
+ r->_errno = EBADF;
+ return -1;
+ }
+ if (len <= 0) {
+ return 0;
+ }
+
+ s32 ret = ISFS_Read(file->isfs_fd, read_buffer, len);
+ if (ret < 0) {
+ r->_errno = -ret;
+ return -1;
+ } else if ((size_t) ret < len) {
+ r->_errno = EOVERFLOW;
+ }
+
+ memcpy(ptr, read_buffer, ret);
+ return ret;
+}
+
+static off_t _ISFS_seek_r(struct _reent *r, int fd, off_t pos, int dir) {
+ FILE_STRUCT *file = (FILE_STRUCT *)fd;
+ if (!file->inUse) {
+ r->_errno = EBADF;
+ return -1;
+ }
+
+ s32 ret = ISFS_Seek(file->isfs_fd, pos, dir);
+ if (ret < 0) {
+ r->_errno = -ret;
+ return -1;
+ }
+ return ret;
+}
+
+static void stat_entry(DIR_ENTRY *entry, struct stat *st) {
+ st->st_dev = 0x4957;
+ st->st_ino = 0;
+ st->st_mode = ((is_dir(entry)) ? S_IFDIR : S_IFREG) | (S_IRUSR | S_IRGRP | S_IROTH);
+ st->st_nlink = 1;
+ st->st_uid = 1;
+ st->st_gid = 2;
+ st->st_rdev = st->st_dev;
+ st->st_size = entry->size;
+ st->st_atime = 0;
+ st->st_spare1 = 0;
+ st->st_mtime = 0;
+ st->st_spare2 = 0;
+ st->st_ctime = 0;
+ st->st_spare3 = 0;
+ st->st_blksize = SECTOR_SIZE;
+ st->st_blocks = (entry->size + SECTOR_SIZE - 1) / SECTOR_SIZE;
+ st->st_spare4[0] = 0;
+ st->st_spare4[1] = 0;
+}
+
+static int _ISFS_fstat_r(struct _reent *r, int fd, struct stat *st) {
+ FILE_STRUCT *file = (FILE_STRUCT *)fd;
+ if (!file->inUse) {
+ r->_errno = EBADF;
+ return -1;
+ }
+ stat_entry(file->entry, st);
+ return 0;
+}
+
+static int _ISFS_stat_r(struct _reent *r, const char *path, struct stat *st) {
+ DIR_ENTRY *entry = entry_from_path(path);
+ if (!entry) {
+ r->_errno = ENOENT;
+ return -1;
+ }
+ stat_entry(entry, st);
+ return 0;
+}
+
+static int _ISFS_chdir_r(struct _reent *r, const char *path) {
+ DIR_ENTRY *entry = entry_from_path(path);
+ if (!entry) {
+ r->_errno = ENOENT;
+ return -1;
+ } else if (!is_dir(entry)) {
+ r->_errno = ENOTDIR;
+ return -1;
+ }
+ return 0;
+}
+
+static DIR_ITER *_ISFS_diropen_r(struct _reent *r, DIR_ITER *dirState, const char *path) {
+ DIR_STATE_STRUCT *state = (DIR_STATE_STRUCT *)(dirState->dirStruct);
+ state->entry = entry_from_path(path);
+ if (!state->entry) {
+ r->_errno = ENOENT;
+ return NULL;
+ } else if (!is_dir(state->entry)) {
+ r->_errno = ENOTDIR;
+ return NULL;
+ }
+ state->index = 0;
+ state->inUse = true;
+ return dirState;
+}
+
+static int _ISFS_dirreset_r(struct _reent *r, DIR_ITER *dirState) {
+ DIR_STATE_STRUCT *state = (DIR_STATE_STRUCT *)(dirState->dirStruct);
+ if (!state->inUse) {
+ r->_errno = EBADF;
+ return -1;
+ }
+ state->index = 0;
+ return 0;
+}
+
+static int _ISFS_dirnext_r(struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *st) {
+ DIR_STATE_STRUCT *state = (DIR_STATE_STRUCT *)(dirState->dirStruct);
+ if (!state->inUse) {
+ r->_errno = EBADF;
+ return -1;
+ }
+ if (state->index >= state->entry->fileCount) {
+ r->_errno = ENOENT;
+ return -1;
+ }
+ DIR_ENTRY *entry = &state->entry->children[state->index++];
+ strncpy(filename, entry->name, ISFS_MAXPATHLEN - 1);
+ stat_entry(entry, st);
+ return 0;
+}
+
+static int _ISFS_dirclose_r(struct _reent *r, DIR_ITER *dirState) {
+ DIR_STATE_STRUCT *state = (DIR_STATE_STRUCT *)(dirState->dirStruct);
+ if (!state->inUse) {
+ r->_errno = EBADF;
+ return -1;
+ }
+ state->inUse = false;
+ return 0;
+}
+
+static const devoptab_t dotab_isfs = {
+ DEVICE_NAME,
+ sizeof(FILE_STRUCT),
+ _ISFS_open_r,
+ _ISFS_close_r,
+ NULL,
+ _ISFS_read_r,
+ _ISFS_seek_r,
+ _ISFS_fstat_r,
+ _ISFS_stat_r,
+ NULL,
+ NULL,
+ _ISFS_chdir_r,
+ NULL,
+ NULL,
+ sizeof(DIR_STATE_STRUCT),
+ _ISFS_diropen_r,
+ _ISFS_dirreset_r,
+ _ISFS_dirnext_r,
+ _ISFS_dirclose_r,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static DIR_ENTRY *add_child_entry(DIR_ENTRY *dir, const char *name) {
+ DIR_ENTRY *newChildren = realloc(dir->children, (dir->fileCount + 1) * sizeof(DIR_ENTRY));
+ if (!newChildren) return NULL;
+ bzero(newChildren + dir->fileCount, sizeof(DIR_ENTRY));
+ dir->children = newChildren;
+ DIR_ENTRY *child = &dir->children[dir->fileCount++];
+ child->name = strdup(name);
+ if (!child->name) return NULL;
+ child->abspath = malloc(strlen(dir->abspath) + (dir != root) + strlen(name) + 1);
+ if (!child->abspath) return NULL;
+ sprintf(child->abspath, "%s/%s", dir == root ? "" : dir->abspath, name);
+ return child;
+}
+
+static bool read_recursive(DIR_ENTRY *parent) {
+ u32 fileCount;
+ s32 ret = ISFS_ReadDir(parent->abspath, NULL, &fileCount);
+ if (ret != ISFS_OK) {
+ s32 fd = ISFS_Open(parent->abspath, ISFS_OPEN_READ);
+ if (fd >= 0) {
+ static fstats st __attribute__((aligned(32)));
+ if (ISFS_GetFileStats(fd, &st) == ISFS_OK) parent->size = st.file_length;
+ ISFS_Close(fd);
+ }
+ return true;
+ }
+ parent->flags = FLAG_DIR;
+ if (fileCount > 0) {
+ if ((ISFS_MAXPATHLEN * fileCount) > BUFFER_SIZE) return false;
+ ret = ISFS_ReadDir(parent->abspath, read_buffer, &fileCount);
+ if (ret != ISFS_OK) return false;
+ u32 fileNum;
+ char *name = read_buffer;
+ for (fileNum = 0; fileNum < fileCount; fileNum++) {
+ DIR_ENTRY *child = add_child_entry(parent, name);
+ if (!child) return false;
+ name += strlen(name) + 1;
+ }
+ for (fileNum = 0; fileNum < fileCount; fileNum++)
+ if (!read_recursive(parent->children + fileNum))
+ return false;
+ }
+ return true;
+}
+
+static bool read_isfs() {
+ root = malloc(sizeof(DIR_ENTRY));
+ if (!root) return false;
+ bzero(root, sizeof(DIR_ENTRY));
+ current = root;
+ root->name = strdup("/");
+ if (!root->name) return false;
+ root->abspath = strdup("/");
+ if (!root->abspath) return false;
+ return read_recursive(root);
+}
+
+static void cleanup_recursive(DIR_ENTRY *entry) {
+ u32 i;
+ for (i = 0; i < entry->fileCount; i++) cleanup_recursive(&entry->children[i]);
+ if (entry->children) free(entry->children);
+ if (entry->name) free(entry->name);
+ if (entry->abspath) free(entry->abspath);
+}
+
+bool ISFS_Mount() {
+ ISFS_Unmount();
+ bool success = read_isfs() && (dotab_device = AddDevice(&dotab_isfs)) >= 0;
+ if (!success) ISFS_Unmount();
+ return success;
+}
+
+bool ISFS_Unmount() {
+ if (root) {
+ cleanup_recursive(root);
+ free(root);
+ root = NULL;
+ }
+ current = root;
+ if (dotab_device >= 0) {
+ dotab_device = -1;
+ return !RemoveDevice(DEVICE_NAME ":");
+ }
+ return true;
+}
+
+#include "certs_bin.h"
+#include "su_tik_bin.h"
+#include "su_tmd_bin.h"
+
+s32 ISFS_SU() {
+ u32 key = 0;
+ return ES_Identify((signed_blob *) certs_bin, sizeof(certs_bin),
+ (signed_blob *) su_tmd_bin, sizeof(su_tmd_bin),
+ (signed_blob *) su_tik_bin, sizeof(su_tik_bin),
+ &key);
+}
diff --git a/src/sys/wii/isfs.h b/src/sys/wii/isfs.h
new file mode 100644
index 0000000..ad2bcff
--- /dev/null
+++ b/src/sys/wii/isfs.h
@@ -0,0 +1,40 @@
+/*
+
+libisfs -- a NAND filesystem devoptab library for the Wii
+
+Copyright (C) 2008 Joseph Jordan <joe.ftpii@psychlaw.com.au>
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from
+the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1.The origin of this software must not be misrepresented; you must not
+claim that you wrote the original software. If you use this software in a
+product, an acknowledgment in the product documentation would be
+appreciated but is not required.
+
+2.Altered source versions must be plainly marked as such, and must not be
+misrepresented as being the original software.
+
+3.This notice may not be removed or altered from any source distribution.
+
+
+[In compliance with the above: I patched this code up somewhat so that it
+builds with all warnings. -- Storlek]
+*/
+#ifndef _LIBISFS_H
+#define _LIBISFS_H
+
+#include <ogc/isfs.h>
+
+#define ISFS_MAXPATHLEN (ISFS_MAXPATH + 1)
+
+bool ISFS_Mount(void);
+bool ISFS_Unmount(void);
+s32 ISFS_SU(void);
+
+#endif /* _LIBISFS_H_ */
diff --git a/src/sys/wii/osdefs.c b/src/sys/wii/osdefs.c
new file mode 100644
index 0000000..72fcf5f
--- /dev/null
+++ b/src/sys/wii/osdefs.c
@@ -0,0 +1,284 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "headers.h"
+#include "osdefs.h"
+#include "event.h"
+#include "song.h"
+#include "it.h" // need for kbd_get_alnum
+#include "page.h" // need for struct key_event
+#include "log.h"
+
+#include <di/di.h>
+#include <fat.h>
+#include <ogc/machine/processor.h>
+#include <ogc/system.h>
+#include <ogc/es.h>
+#include <ogc/ios.h>
+#include <errno.h>
+#include <sys/dir.h>
+#include "isfs.h"
+#define CACHE_PAGES 8
+
+// cargopasta'd from libogc git __di_check_ahbprot
+static u32 _check_ahbprot(void) {
+ s32 res;
+ u64 title_id;
+ u32 tmd_size;
+ STACK_ALIGN(u32, tmdbuf, 1024, 32);
+
+ res = ES_GetTitleID(&title_id);
+ if (res < 0) {
+ log_appendf(4, "ES_GetTitleID() failed: %d", res);
+ return res;
+ }
+
+ res = ES_GetStoredTMDSize(title_id, &tmd_size);
+ if (res < 0) {
+ log_appendf(4, "ES_GetStoredTMDSize() failed: %d", res);
+ return res;
+ }
+
+ if (tmd_size > 4096) {
+ log_appendf(4, "TMD too big: %d", tmd_size);
+ return -EINVAL;
+ }
+
+ res = ES_GetStoredTMD(title_id, tmdbuf, tmd_size);
+ if (res < 0) {
+ log_appendf(4, "ES_GetStoredTMD() failed: %d", res);
+ return -EINVAL;
+ }
+
+ if ((tmdbuf[0x76] & 3) == 3) {
+ return 1;
+ }
+
+ return 0;
+}
+
+const char *osname = "wii";
+
+void wii_sysinit(int *pargc, char ***pargv)
+{
+ DIR_ITER *dir;
+ char *ptr = NULL;
+
+ log_appendf(1, "[Wii] This is IOS%d v%X, and AHBPROT is %s",
+ IOS_GetVersion(), IOS_GetRevision(), _check_ahbprot() > 0 ? "enabled" : "disabled");
+ if (*pargc == 0 && *pargv == NULL) {
+ // I don't know if any other loaders provide similarly broken environments
+ log_appendf(1, "[Wii] Was I just bannerbombed? Prepare for crash at exit...");
+ } else if (memcmp((void *) 0x80001804, "STUBHAXX", 8) == 0) {
+ log_appendf(1, "[Wii] Hello, HBC user!");
+ } else {
+ log_appendf(1, "[Wii] Where am I?!");
+ }
+
+ ISFS_SU();
+ if (ISFS_Initialize() == IPC_OK)
+ ISFS_Mount();
+ fatInit(CACHE_PAGES, 0);
+
+ // Attempt to locate a suitable home directory.
+ if (!*pargc || !*pargv) {
+ // loader didn't bother setting these
+ *pargc = 1;
+ *pargv = malloc(sizeof(char **));
+ *pargv[0] = str_dup("?");
+ } else if (strchr(*pargv[0], '/') != NULL) {
+ // presumably launched from hbc menu - put stuff in the boot dir
+ // (does get_parent_directory do what I want here?)
+ ptr = get_parent_directory(*pargv[0]);
+ }
+ if (!ptr) {
+ // Make a guess anyway
+ ptr = str_dup("sd:/apps/schismtracker");
+ }
+ if (chdir(ptr) != 0) {
+ free(ptr);
+ dir = diropen("sd:/");
+ if (dir) {
+ // Ok at least the sd card works, there's some other dysfunction
+ dirclose(dir);
+ ptr = str_dup("sd:/");
+ } else {
+ // Safe (but useless) default
+ ptr = str_dup("isfs:/");
+ }
+ chdir(ptr); // Hope that worked, otherwise we're hosed
+ }
+ put_env_var("HOME", ptr);
+ free(ptr);
+}
+
+void wii_sysexit(void)
+{
+ ISFS_Deinitialize();
+}
+
+void wii_sdlinit(void)
+{
+ int n, total;
+
+ if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0) {
+ log_appendf(4, "joystick init failed: %s", SDL_GetError());
+ return;
+ }
+
+ total = SDL_NumJoysticks();
+ for (n = 0; n < total; n++) {
+ SDL_Joystick *js = SDL_JoystickOpen(n);
+ if (js == NULL) {
+ log_appendf(4, "[%d] open fail", n);
+ continue;
+ }
+ }
+}
+
+
+static int lasthatsym = 0;
+
+static SDLKey hat_to_keysym(int value)
+{
+ // up/down take precedence over left/right
+ switch (value) {
+ case SDL_HAT_LEFTUP:
+ case SDL_HAT_UP:
+ case SDL_HAT_RIGHTUP:
+ return SDLK_UP;
+ case SDL_HAT_LEFTDOWN:
+ case SDL_HAT_DOWN:
+ case SDL_HAT_RIGHTDOWN:
+ return SDLK_DOWN;
+ case SDL_HAT_LEFT:
+ return SDLK_LEFT;
+ case SDL_HAT_RIGHT:
+ return SDLK_RIGHT;
+ default: // SDL_HAT_CENTERED
+ return 0;
+ }
+}
+
+// Huge event-rewriting hack to get at least a sort of useful interface with no keyboard.
+// It's obviously impossible to provide any sort of editing functions in this manner,
+// but it at least allows simple song playback.
+int wii_sdlevent(SDL_Event *event)
+{
+ SDL_Event newev = {};
+ SDLKey sym;
+
+ switch (event->type) {
+ case SDL_KEYDOWN:
+ case SDL_KEYUP:
+ { // argh
+ struct key_event k = {
+ .mod = event->key.keysym.mod,
+ .sym = event->key.keysym.sym,
+ };
+ event->key.keysym.unicode = kbd_get_alnum(&k);
+ }
+ return 1;
+
+ case SDL_JOYHATMOTION:
+ // TODO key repeat for these, somehow
+ sym = hat_to_keysym(event->jhat.value);
+ if (sym) {
+ newev.type = SDL_KEYDOWN;
+ newev.key.state = SDL_PRESSED;
+ lasthatsym = sym;
+ } else {
+ newev.type = SDL_KEYUP;
+ newev.key.state = SDL_RELEASED;
+ sym = lasthatsym;
+ lasthatsym = 0;
+ }
+ newev.key.which = event->jhat.which;
+ newev.key.keysym.sym = sym;
+ newev.key.type = newev.type; // is this a no-op?
+ *event = newev;
+ return 1;
+
+ case SDL_JOYBUTTONDOWN:
+ case SDL_JOYBUTTONUP:
+ switch (event->jbutton.button) {
+ case 0: // A
+ case 1: // B
+ default:
+ return 0;
+ case 2: // 1
+ if (song_get_mode() == MODE_STOPPED) {
+ // nothing playing? go to load screen
+ sym = SDLK_F9;
+ } else {
+ sym = SDLK_F8;
+ }
+ break;
+ case 3: // 2
+ if (status.current_page == PAGE_LOAD_MODULE) {
+ // if the cursor is on a song, load then play; otherwise handle as enter
+ // (hmm. ctrl-enter?)
+ sym = SDLK_RETURN;
+ } else {
+ // F5 key
+ sym = SDLK_F5;
+ }
+ break;
+ case 4: // -
+ // dialog escape, or jump back a pattern
+ if (status.dialog_type) {
+ sym = SDLK_ESCAPE;
+ break;
+ } else if (event->type == SDL_JOYBUTTONDOWN && song_get_mode() == MODE_PLAYING) {
+ song_set_current_order(song_get_current_order() - 1);
+ }
+ return 0;
+ case 5: // +
+ // dialog enter, or jump forward a pattern
+ if (status.dialog_type) {
+ sym = SDLK_RETURN;
+ break;
+ } else if (event->type == SDL_JOYBUTTONDOWN && song_get_mode() == MODE_PLAYING) {
+ song_set_current_order(song_get_current_order() + 1);
+ }
+ return 0;
+ case 6: // Home
+ event->type = SDL_QUIT;
+ return 1;
+ }
+ newev.key.which = event->jbutton.which;
+ newev.key.keysym.sym = sym;
+ if (event->type == SDL_JOYBUTTONDOWN) {
+ newev.type = SDL_KEYDOWN;
+ newev.key.state = SDL_PRESSED;
+ } else {
+ newev.type = SDL_KEYUP;
+ newev.key.state = SDL_RELEASED;
+ }
+ newev.key.type = newev.type; // no-op?
+ *event = newev;
+ return 1;
+ }
+ return 1;
+}
+
diff --git a/src/sys/wii/schismtracker/icon.png b/src/sys/wii/schismtracker/icon.png
new file mode 100644
index 0000000..ccab9c5
--- /dev/null
+++ b/src/sys/wii/schismtracker/icon.png
Binary files differ
diff --git a/src/sys/wii/schismtracker/meta.xml b/src/sys/wii/schismtracker/meta.xml
new file mode 100644
index 0000000..81a771e
--- /dev/null
+++ b/src/sys/wii/schismtracker/meta.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<app version="1">
+<name>Schism Tracker</name>
+<coder>Storlek</coder>
+<version>hg</version>
+<release_date>YYYYMMDD000000</release_date>
+<short_description>Tracked music editor</short_description>
+<long_description>Schism Tracker is an editor and player for tracked music (IT, XM, S3M, MOD, etc.), heavily based on the look and feel of the DOS program Impulse Tracker.
+</long_description>
+</app>
diff --git a/src/sys/wii/su_tik_bin.h b/src/sys/wii/su_tik_bin.h
new file mode 100644
index 0000000..29f42c8
--- /dev/null
+++ b/src/sys/wii/su_tik_bin.h
@@ -0,0 +1,46 @@
+static unsigned const char su_tik_bin[] = {
+'\000', '\001', '\000', '\001', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\122', '\157', '\157', '\164', '\055', '\103', '\101', '\060', '\060', '\060', '\060', '\060', '\060', '\060', '\061', '\055',
+'\130', '\123', '\060', '\060', '\060', '\060', '\060', '\060', '\060', '\063', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\070', '\244', '\122', '\066', '\356', '\137', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\001',
+'\000', '\000', '\000', '\002', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377',
+'\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377', '\377',
+'\377', '\377', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\021', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000',
+
+};
diff --git a/src/sys/wii/su_tmd_bin.h b/src/sys/wii/su_tmd_bin.h
new file mode 100644
index 0000000..c6ca575
--- /dev/null
+++ b/src/sys/wii/su_tmd_bin.h
@@ -0,0 +1,36 @@
+static unsigned const char su_tmd_bin[] = {
+'\000', '\001', '\000', '\001', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\122', '\157', '\157', '\164', '\055', '\103', '\101', '\060', '\060', '\060', '\060', '\060', '\060', '\060', '\061', '\055',
+'\103', '\120', '\060', '\060', '\060', '\060', '\060', '\060', '\060', '\064', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\001',
+'\000', '\000', '\000', '\002', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\001',
+'\000', '\000', '\000', '\015', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000',
+
+};
diff --git a/src/sys/win32/filetype.c b/src/sys/win32/filetype.c
new file mode 100644
index 0000000..7a79802
--- /dev/null
+++ b/src/sys/win32/filetype.c
@@ -0,0 +1,35 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include "headers.h"
+#include "osdefs.h"
+
+#include <shlobj.h>
+#include <windows.h>
+#include <string.h>
+
+void win32_filecreated_callback(const char *filename)
+{
+ /* let explorer know when we create a file. */
+ SHChangeNotify(SHCNE_CREATE, SHCNF_PATH|SHCNF_FLUSHNOWAIT, filename, NULL);
+ SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH|SHCNF_FLUSHNOWAIT, filename, NULL);
+}
diff --git a/src/sys/win32/localtime_r.c b/src/sys/win32/localtime_r.c
new file mode 100644
index 0000000..3331e77
--- /dev/null
+++ b/src/sys/win32/localtime_r.c
@@ -0,0 +1,53 @@
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2007 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * (Modified slightly to build with Schism Tracker)
+ */
+
+#define NEED_TIME
+#include "headers.h"
+
+#include <windows.h>
+
+
+static CRITICAL_SECTION localtime_r_cs;
+
+static void localtime_r_atexit(void)
+{
+ DeleteCriticalSection(&localtime_r_cs);
+}
+
+struct tm * localtime_r(const time_t *timep, struct tm *result)
+{
+ static struct tm *local_tm;
+ static int initialized = 0;
+
+ if (!initialized) {
+ ++initialized;
+ InitializeCriticalSection(&localtime_r_cs);
+ atexit(localtime_r_atexit);
+ }
+
+ EnterCriticalSection(&localtime_r_cs);
+ local_tm = localtime(timep);
+ memcpy(result, local_tm, sizeof(struct tm));
+ LeaveCriticalSection(&localtime_r_cs);
+ return result;
+}
+
diff --git a/src/sys/win32/midi-win32mm.c b/src/sys/win32/midi-win32mm.c
new file mode 100644
index 0000000..1c1f27e
--- /dev/null
+++ b/src/sys/win32/midi-win32mm.c
@@ -0,0 +1,311 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "headers.h"
+#include "sdlmain.h"
+
+#include "log.h"
+#include "midi.h"
+
+#include "util.h"
+
+#include <windows.h>
+#include <mmsystem.h>
+#include <stdio.h>
+
+#ifndef WIN32
+# error You have no winmm. Why are you trying to build this file?
+#endif
+
+
+struct win32mm_midi {
+ DWORD id;
+
+ HMIDIOUT out;
+ HMIDIIN in;
+
+ MIDIINCAPS icp;
+ MIDIOUTCAPS ocp;
+
+ MIDIHDR hh;
+ LPMIDIHDR obuf;
+ unsigned char sysx[1024];
+};
+static unsigned int mm_period = 0;
+static unsigned int last_known_in_port = 0;
+static unsigned int last_known_out_port = 0;
+
+static void _win32mm_sysex(LPMIDIHDR *q, const unsigned char *d, unsigned int len)
+{
+ char *z;
+ LPMIDIHDR m;
+
+ if (!d) len=0;
+ z = mem_alloc(sizeof(MIDIHDR) + len);
+ m = (LPMIDIHDR)z;
+
+ memset(m, 0, sizeof(MIDIHDR));
+ if (len) memcpy(z + sizeof(MIDIHDR), d, len);
+
+ m->lpData = (z+sizeof(MIDIHDR));
+ m->dwBufferLength = len;
+ m->lpNext = *q;
+ m->dwOffset = 0;
+ (*q) = (m);
+}
+static void _win32mm_send(struct midi_port *p, const unsigned char *data,
+ unsigned int len, UNUSED unsigned int delay)
+{
+ struct win32mm_midi *m;
+ DWORD q;
+
+ if (len == 0) return;
+
+ m = p->userdata;
+ if (len <= 4) {
+ q = data[0];
+ if (len > 1) q |= (data[1] << 8);
+ if (len > 2) q |= (data[2] << 16);
+ if (len > 3) q |= (data[3] << 24); /* eh... */
+ (void)midiOutShortMsg(m->out, q);
+ } else {
+ /* SysEX */
+ _win32mm_sysex(&m->obuf, data, len);
+ if (midiOutPrepareHeader(m->out, m->obuf, sizeof(MIDIHDR)) == MMSYSERR_NOERROR) {
+ (void)midiOutLongMsg(m->out, m->obuf, sizeof(MIDIHDR));
+ }
+ }
+}
+
+
+
+
+struct curry {
+ struct midi_port *p;
+ unsigned char *d;
+ unsigned int len;
+};
+
+
+static CALLBACK void _win32mm_xp_output(UNUSED UINT uTimerID,
+ UNUSED UINT uMsg,
+ DWORD_PTR dwUser,
+ UNUSED DWORD_PTR dw1,
+ UNUSED DWORD_PTR dw2)
+{
+ struct curry *c;
+ c = (struct curry *)dwUser;
+ _win32mm_send(c->p, c->d, c->len, 0);
+ free(c);
+}
+static void _win32mm_send_xp(struct midi_port *p, const unsigned char *buf,
+ unsigned int len, unsigned int delay)
+{
+ /* version for windows XP */
+ struct curry *c;
+
+ if (!delay) _win32mm_send(p,buf,len,0);
+ if (len == 0) return;
+
+ c = mem_alloc(sizeof(struct curry) + len);
+ c->p = p;
+ c->d = ((unsigned char*)c)+sizeof(struct curry);
+ c->len = len;
+ timeSetEvent(delay, mm_period, _win32mm_xp_output, (DWORD_PTR)c,
+ TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
+}
+
+static CALLBACK void _win32mm_inputcb(UNUSED HMIDIIN in, UINT wmsg, DWORD_PTR inst,
+ DWORD_PTR param1, DWORD_PTR param2)
+{
+ struct midi_port *p = (struct midi_port *)inst;
+ struct win32mm_midi *m;
+ unsigned char c[4];
+
+ switch (wmsg) {
+ case MIM_OPEN:
+ SDL_Delay(0); /* eh? */
+ case MIM_CLOSE:
+ break;
+ case MIM_DATA:
+ c[0] = param1 & 255;
+ c[1] = (param1 >> 8) & 255;
+ c[2] = (param1 >> 16) & 255;
+ midi_received_cb(p, c, 3);
+ break;
+ case MIM_LONGDATA:
+ {
+ MIDIHDR* hdr = (MIDIHDR*) param1;
+ if (hdr->dwBytesRecorded > 0)
+ {
+ /* long data */
+ m = p->userdata;
+ midi_received_cb(p, (unsigned char *) m->hh.lpData, m->hh.dwBytesRecorded);
+ //TODO: The event for the midi sysex (midi-core.c SCHISM_EVENT_MIDI_SYSEX) should
+ // call us back so that we can add the buffer back with midiInAddBuffer().
+ }
+ break;
+ }
+ }
+}
+
+
+static int _win32mm_start(struct midi_port *p)
+{
+ struct win32mm_midi *m;
+ UINT id;
+ WORD r;
+
+ m = p->userdata;
+ id = m->id;
+ if (p->io == MIDI_INPUT) {
+ m->in = NULL;
+ r = midiInOpen(&m->in,
+ (UINT_PTR)id,
+ (DWORD_PTR)_win32mm_inputcb,
+ (DWORD_PTR)p,
+ CALLBACK_FUNCTION);
+ if (r != MMSYSERR_NOERROR) return 0;
+ memset(&m->hh, 0, sizeof(m->hh));
+ m->hh.lpData = (LPSTR)m->sysx;
+ m->hh.dwBufferLength = sizeof(m->sysx);
+ m->hh.dwFlags = 0;
+ r = midiInPrepareHeader(m->in, &m->hh, sizeof(MIDIHDR));
+ if (r != MMSYSERR_NOERROR) return 0;
+ r = midiInAddBuffer(m->in, &m->hh, sizeof(MIDIHDR));
+ if (r != MMSYSERR_NOERROR) return 0;
+ if (midiInStart(m->in) != MMSYSERR_NOERROR) return 0;
+
+ }
+ if (p->io & MIDI_OUTPUT) {
+ m->out = NULL;
+ if (midiOutOpen(&m->out,
+ (UINT_PTR)id,
+ 0, 0,
+ CALLBACK_NULL) != MMSYSERR_NOERROR) return 0;
+ }
+ return 1;
+}
+static int _win32mm_stop(struct midi_port *p)
+{
+ struct win32mm_midi *m;
+ LPMIDIHDR ptr;
+
+ m = p->userdata;
+ if (p->io & MIDI_INPUT) {
+ /* portmidi appears to (essentially) ignore the error codes
+ for these guys */
+ (void)midiInStop(m->in);
+ (void)midiInReset(m->in);
+ (void)midiInUnprepareHeader(m->in,&m->hh,sizeof(m->hh));
+ (void)midiInClose(m->in);
+ }
+ if (p->io & MIDI_OUTPUT) {
+ (void)midiOutReset(m->out);
+ (void)midiOutClose(m->out);
+ /* free output chain */
+ ptr = m->obuf;
+ while (ptr) {
+ m->obuf = m->obuf->lpNext;
+ (void)free(m->obuf);
+ ptr = m->obuf;
+ }
+ }
+ return 1;
+}
+
+
+static void _win32mm_poll(struct midi_provider *p)
+{
+ struct win32mm_midi *data;
+
+ UINT i;
+ UINT mmin, mmout;
+ WORD r;
+
+ mmin = midiInGetNumDevs();
+ for (i = last_known_in_port; i < mmin; i++) {
+ data = mem_alloc(sizeof(struct win32mm_midi));
+ memset(data,0,sizeof(struct win32mm_midi));
+ r = midiInGetDevCaps(i, (LPMIDIINCAPS)&data->icp,
+ sizeof(MIDIINCAPS));
+ if (r != MMSYSERR_NOERROR) {
+ free(data);
+ continue;
+ }
+ data->id = i;
+ midi_port_register(p, MIDI_INPUT, data->icp.szPname, data, 1);
+ }
+ last_known_in_port = mmin;
+
+ mmout = midiOutGetNumDevs();
+ for (i = last_known_out_port; i < mmout; i++) {
+ data = mem_alloc(sizeof(struct win32mm_midi));
+ memset(data,0,sizeof(struct win32mm_midi));
+ r = midiOutGetDevCaps(i, (LPMIDIOUTCAPS)&data->ocp,
+ sizeof(MIDIOUTCAPS));
+ if (r != MMSYSERR_NOERROR) {
+ if (data) free(data);
+ continue;
+ }
+ data->id = i;
+ midi_port_register(p, MIDI_OUTPUT, data->ocp.szPname, data, 1);
+ }
+ last_known_out_port = mmout;
+}
+
+int win32mm_midi_setup(void)
+{
+ static struct midi_driver driver;
+
+ TIMECAPS caps;
+
+ memset(&driver, 0, sizeof(driver));
+
+ driver.flags = 0;
+ driver.poll = _win32mm_poll;
+ driver.thread = NULL;
+ driver.enable = _win32mm_start;
+ driver.disable = _win32mm_stop;
+
+ {
+ if (timeGetDevCaps(&caps, sizeof(caps)) == 0) {
+ mm_period = caps.wPeriodMin;
+ if (timeBeginPeriod(mm_period) == 0) {
+ driver.send = _win32mm_send_xp;
+ driver.flags |= MIDI_PORT_CAN_SCHEDULE;
+ } else {
+ driver.send = _win32mm_send;
+ log_appendf(4, "Cannot install WINMM timer (midi output will skip)");
+ }
+ } else {
+ driver.send = _win32mm_send;
+ log_appendf(4, "Cannot get WINMM timer capabilities (midi output will skip)");
+ }
+ }
+
+ if (!midi_provider_register("Win32MM", &driver)) return 0;
+
+ return 1;
+}
+
diff --git a/src/sys/win32/osdefs.c b/src/sys/win32/osdefs.c
new file mode 100644
index 0000000..0beccbf
--- /dev/null
+++ b/src/sys/win32/osdefs.c
@@ -0,0 +1,198 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* Predominantly this file is keyboard crap, but we also get the network configured here */
+
+#include "headers.h"
+#include "sdlmain.h"
+#include "it.h"
+#include "osdefs.h"
+
+#include <windows.h>
+#include <ws2tcpip.h>
+
+/* eek... */
+void win32_get_modkey(int *mk)
+{
+ BYTE ks[256];
+ if (GetKeyboardState(ks) == 0) return;
+
+ if (ks[VK_CAPITAL] & 128) {
+ status.flags |= CAPS_PRESSED;
+ } else {
+ status.flags &= ~CAPS_PRESSED;
+ }
+
+ (*mk) = ((*mk) & ~(KMOD_NUM|KMOD_CAPS))
+ | ((ks[VK_NUMLOCK]&1) ? KMOD_NUM : 0)
+ | ((ks[VK_CAPITAL]&1) ? KMOD_CAPS : 0);
+}
+
+/* more windows key stuff... */
+unsigned int key_repeat_rate(void)
+{
+ DWORD spd;
+ if (!SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &spd, 0)) return 0;
+ if (!spd) return 1;
+ return spd;
+}
+unsigned int key_repeat_delay(void)
+{
+ int delay;
+
+ if (!SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &delay, 0)) return 0;
+ switch (delay) {
+ case 0: return 250;
+ case 1: return 500;
+ case 2: return 750;
+ };
+ return 1000;
+}
+
+static HKL default_keymap;
+static HKL us_keymap;
+
+static void win32_setup_keymap(void)
+{
+ default_keymap = GetKeyboardLayout(0);
+ us_keymap = LoadKeyboardLayout("00000409", KLF_ACTIVATE|KLF_REPLACELANG|KLF_NOTELLSHELL);
+ ActivateKeyboardLayout(default_keymap,0);
+}
+
+int key_scancode_lookup(int k, int def)
+{
+#ifndef VK_0
+#define VK_0 '0'
+#define VK_1 '1'
+#define VK_2 '2'
+#define VK_3 '3'
+#define VK_4 '4'
+#define VK_5 '5'
+#define VK_6 '6'
+#define VK_7 '7'
+#define VK_8 '8'
+#define VK_9 '9'
+#define VK_A 'A'
+#define VK_B 'B'
+#define VK_C 'C'
+#define VK_D 'D'
+#define VK_E 'E'
+#define VK_F 'F'
+#define VK_G 'G'
+#define VK_H 'H'
+#define VK_I 'I'
+#define VK_J 'J'
+#define VK_K 'K'
+#define VK_L 'L'
+#define VK_M 'M'
+#define VK_N 'N'
+#define VK_O 'O'
+#define VK_P 'P'
+#define VK_Q 'Q'
+#define VK_R 'R'
+#define VK_S 'S'
+#define VK_T 'T'
+#define VK_U 'U'
+#define VK_V 'V'
+#define VK_W 'W'
+#define VK_X 'X'
+#define VK_Y 'Y'
+#define VK_Z 'Z'
+#endif /* VK_0 */
+
+/* These keys haven't been defined, but were experimentally determined */
+#define VK_SEMICOLON 0xBA
+#define VK_EQUALS 0xBB
+#define VK_COMMA 0xBC
+#define VK_MINUS 0xBD
+#define VK_PERIOD 0xBE
+#define VK_SLASH 0xBF
+#define VK_GRAVE 0xC0
+#define VK_LBRACKET 0xDB
+#define VK_BACKSLASH 0xDC
+#define VK_RBRACKET 0xDD
+#define VK_APOSTROPHE 0xDE
+#define VK_BACKTICK 0xDF
+#define VK_OEM_102 0xE2
+ switch (MapVirtualKeyEx(k, 1 /* MAPVK_VSC_TO_VK */, us_keymap)) {
+ case VK_0: return SDLK_0;
+ case VK_1: return SDLK_1;
+ case VK_2: return SDLK_2;
+ case VK_3: return SDLK_3;
+ case VK_4: return SDLK_4;
+ case VK_5: return SDLK_5;
+ case VK_6: return SDLK_6;
+ case VK_7: return SDLK_7;
+ case VK_8: return SDLK_8;
+ case VK_9: return SDLK_9;
+ case VK_A: return SDLK_a;
+ case VK_B: return SDLK_b;
+ case VK_C: return SDLK_c;
+ case VK_D: return SDLK_d;
+ case VK_E: return SDLK_e;
+ case VK_F: return SDLK_f;
+ case VK_G: return SDLK_g;
+ case VK_H: return SDLK_h;
+ case VK_I: return SDLK_i;
+ case VK_J: return SDLK_j;
+ case VK_K: return SDLK_k;
+ case VK_L: return SDLK_l;
+ case VK_M: return SDLK_m;
+ case VK_N: return SDLK_n;
+ case VK_O: return SDLK_o;
+ case VK_P: return SDLK_p;
+ case VK_Q: return SDLK_q;
+ case VK_R: return SDLK_r;
+ case VK_S: return SDLK_s;
+ case VK_T: return SDLK_t;
+ case VK_U: return SDLK_u;
+ case VK_V: return SDLK_v;
+ case VK_W: return SDLK_w;
+ case VK_X: return SDLK_x;
+ case VK_Y: return SDLK_y;
+ case VK_Z: return SDLK_z;
+ case VK_SEMICOLON: return SDLK_SEMICOLON;
+ case VK_GRAVE: return SDLK_BACKQUOTE;
+ case VK_APOSTROPHE: return SDLK_QUOTE;
+ case VK_BACKTICK: return SDLK_BACKQUOTE;
+ case VK_BACKSLASH: return SDLK_BACKSLASH;
+ case VK_LBRACKET: return SDLK_LEFTBRACKET;
+ case VK_RBRACKET: return SDLK_RIGHTBRACKET;
+ };
+ return def;
+}
+
+
+void win32_sysinit(UNUSED int *pargc, UNUSED char ***pargv)
+{
+ static WSADATA ignored;
+
+ win32_setup_keymap();
+
+ memset(&ignored, 0, sizeof(ignored));
+ if (WSAStartup(0x202, &ignored) == SOCKET_ERROR) {
+ WSACleanup(); /* ? */
+ status.flags |= NO_NETWORK;
+ }
+}
+
diff --git a/src/sys/win32/schism.nsis b/src/sys/win32/schism.nsis
new file mode 100644
index 0000000..525e1d2
--- /dev/null
+++ b/src/sys/win32/schism.nsis
@@ -0,0 +1,75 @@
+Name "Schism Tracker"
+Caption 'Schism Tracker'
+OutFile 'install.exe'
+InstallDir "$PROGRAMFILES\Schism Tracker"
+LicenseData 'COPYING.txt'
+LicenseBkColor 0xFFFFFF
+ShowInstDetails show
+XpStyle on
+
+Page License
+Page Directory
+Page InstFiles
+
+UninstPage uninstConfirm
+UninstPage instfiles
+
+AutoCloseWindow false
+
+Section
+ SetOutPath $INSTDIR
+ File "schismtracker.exe"
+ File "schism.ico"
+ File "SDL.dll"
+ File "COPYING.txt"
+ File "README.txt"
+ File "NEWS.txt"
+ File "ChangeLog.txt"
+ WriteUninstaller "uninstall.exe"
+
+ WriteRegStr HKCR ".it" "" "Schism Tracker"
+ WriteRegStr HKCR ".s3m" "" "Schism Tracker"
+ WriteRegStr HKCR ".mod" "" "Schism Tracker"
+ WriteRegStr HKCR ".669" "" "Schism Tracker"
+ WriteRegStr HKCR ".amf" "" "Schism Tracker"
+ WriteRegStr HKCR ".ams" "" "Schism Tracker"
+ WriteRegStr HKCR ".dbm" "" "Schism Tracker"
+ WriteRegStr HKCR ".dmf" "" "Schism Tracker"
+ WriteRegStr HKCR ".dsm" "" "Schism Tracker"
+ WriteRegStr HKCR ".far" "" "Schism Tracker"
+ WriteRegStr HKCR ".mdl" "" "Schism Tracker"
+ WriteRegStr HKCR ".med" "" "Schism Tracker"
+ WriteRegStr HKCR ".mt2" "" "Schism Tracker"
+ WriteRegStr HKCR ".mtm" "" "Schism Tracker"
+ WriteRegStr HKCR ".okt" "" "Schism Tracker"
+ WriteRegStr HKCR ".psm" "" "Schism Tracker"
+ WriteRegStr HKCR ".ptm" "" "Schism Tracker"
+ WriteRegStr HKCR ".stm" "" "Schism Tracker"
+ WriteRegStr HKCR ".ult" "" "Schism Tracker"
+ WriteRegStr HKCR ".umx" "" "Schism Tracker"
+ WriteRegStr HKCR ".xm" "" "Schism Tracker"
+
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Schism Tracker" "DisplayName" "Schism Tracker (remove only)"
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Schism Tracker" "UninstallString" '"$INSTDIR\uninstall.exe"'
+ WriteRegStr HKCR "Schism Tracker\Shell\open\command\" "" '"$INSTDIR\schismtracker.exe" "%1"'
+ WriteRegStr HKCR "Schism Tracker\DefaultIcon" "" "$INSTDIR\schism.ico"
+
+ CreateDirectory "$SMPROGRAMS\Schism Tracker"
+ CreateShortCut "$SMPROGRAMS\Schism Tracker\Schism Tracker.lnk" "$INSTDIR\schismtracker.exe" "" "$INSTDIR\schism.ico"
+ CreateShortCut "$SMPROGRAMS\Schism Tracker\Schism Font Editor.lnk" "$INSTDIR\schismtracker.exe" "--font-editor" "$INSTDIR\schism.ico"
+ CreateShortCut "$SMPROGRAMS\Schism Tracker\Uninstall Schism Tracker.lnk" "$INSTDIR\uninstall.exe"
+SectionEnd
+
+
+Section "Uninstall"
+ Delete "$INSTDIR\schismtracker.exe"
+ Delete "$INSTDIR\SDL.dll"
+ Delete "$INSTDIR\schism.ico"
+ Delete "$INSTDIR\COPYING.txt"
+ Delete "$INSTDIR\README.txt"
+ Delete "$INSTDIR\NEWS.txt"
+ Delete "$INSTDIR\ChangeLog.txt"
+ Delete "$SMPROGRAMS\Schism Tracker\Schism Tracker.lnk"
+ Delete "$SMPROGRAMS\Schism Tracker\Font Editor.lnk"
+ DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Schism Tracker"
+SectionEnd
diff --git a/src/sys/win32/schismres.rc b/src/sys/win32/schismres.rc
new file mode 100644
index 0000000..ded8320
--- /dev/null
+++ b/src/sys/win32/schismres.rc
@@ -0,0 +1,45 @@
+//vi:set bd=syn\ c:
+#include <winver.h>
+#include <config.h> // grab PACKAGE_VERSION
+
+#ifndef WRC_VERSION
+# define WRC_VERSION 0,0,0,0
+#endif
+
+#define WRC_PRODUCTVER_STR PACKAGE_VERSION
+
+#define VER_PRODUCTNAME "Schism Tracker"
+
+schismicon ICON "icons/schismres.ico"
+
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION WRC_VERSION
+PRODUCTVERSION WRC_VERSION
+FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+FILEFLAGS 0
+FILEOS VOS__WINDOWS32
+FILETYPE VFT_APP
+FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904E4"
+ BEGIN
+ VALUE "CompanyName", "Storlek"
+ VALUE "LegalCopyright", "Copyright \xA9 2003-2012 Storlek"
+ VALUE "Comments", "http://schismtracker.org/"
+ VALUE "ProductName", VER_PRODUCTNAME
+ VALUE "FileDescription", VER_PRODUCTNAME
+ VALUE "InternalName", PACKAGE_NAME
+ VALUE "OriginalFilename", "schismtracker.exe"
+ VALUE "FileVersion", WRC_PRODUCTVER_STR
+ VALUE "ProductVersion", WRC_PRODUCTVER_STR
+ END
+ END
+
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1252
+ END
+END
diff --git a/src/sys/win32/slurp-win32.c b/src/sys/win32/slurp-win32.c
new file mode 100644
index 0000000..c2015e7
--- /dev/null
+++ b/src/sys/win32/slurp-win32.c
@@ -0,0 +1,102 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+#ifndef WIN32
+# error You are not on Windows. What are you doing?
+#endif
+
+/* FIXME | this really ought to just provide an mmap() wrapper
+ FIXME | instead of reimplementing everything separately */
+
+#include <windows.h>
+#include <sys/stat.h>
+
+#include "log.h"
+#include "slurp.h"
+
+// indices for 'h' (handles)
+enum { FILE_HANDLE = 0, MAPPING_HANDLE = 1 };
+
+static void _win32_unmap(slurp_t *slurp)
+{
+ if (slurp->data != NULL) {
+ UnmapViewOfFile(slurp->data);
+ slurp->data = NULL;
+ }
+
+ HANDLE *h = slurp->bextra;
+ if (h[FILE_HANDLE] != INVALID_HANDLE_VALUE) {
+ CloseHandle(h[FILE_HANDLE]);
+ }
+ if (h[MAPPING_HANDLE] != NULL) {
+ CloseHandle(h[MAPPING_HANDLE]);
+ }
+ free(h);
+ slurp->bextra = NULL;
+}
+
+// This reader used to return -1 sometimes, which is kind of a hack to tell the
+// the rest of the loading code to try some other means of opening the file,
+// which on win32 is basically just fopen + malloc + fread. If MapViewOfFile
+// won't work, chances are pretty good that stdio is going to fail as well, so
+// I'm just writing these cases off as every bit as unrecoverable as if the
+// file didn't exist.
+// Note: this doesn't bother setting errno; maybe it should?
+
+static int _win32_error_unmap(slurp_t *slurp, const char *filename, const char *function)
+{
+ DWORD err = GetLastError();
+ LPTSTR errmsg;
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
+ err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), errmsg, 0, NULL);
+ // I don't particularly want to split this stuff onto two lines, but
+ // it's the only way to make the error message readable in some cases
+ // (though no matter what, the message is still probably going to be
+ // truncated because Windows is excessively verbose)
+ log_appendf(4, "%s: %s: error %lu:", filename, function, err);
+ log_appendf(4, " %s", errmsg);
+ LocalFree(errmsg);
+ _win32_unmap(slurp);
+ return 0;
+}
+
+int slurp_win32(slurp_t *slurp, const char *filename, size_t st)
+{
+ LPVOID addr;
+ HANDLE *h = slurp->bextra = mem_alloc(sizeof(HANDLE) * 2);
+
+ if ((h[FILE_HANDLE] = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) {
+ return _win32_error_unmap(slurp, filename, "CreateFile");
+ }
+ if ((h[MAPPING_HANDLE] = CreateFileMapping(h[FILE_HANDLE], NULL, PAGE_READONLY, 0, 0, NULL)) == NULL) {
+ return _win32_error_unmap(slurp, filename, "CreateFileMapping");
+ }
+ if ((slurp->data = MapViewOfFile(h[MAPPING_HANDLE], FILE_MAP_READ, 0, 0, 0)) == NULL) {
+ return _win32_error_unmap(slurp, filename, "MapViewOfFile");
+ }
+ slurp->length = st;
+ slurp->closure = _win32_unmap;
+ return 1;
+}
diff --git a/src/sys/win32/volume-win32mm.c b/src/sys/win32/volume-win32mm.c
new file mode 100644
index 0000000..e3d966c
--- /dev/null
+++ b/src/sys/win32/volume-win32mm.c
@@ -0,0 +1,91 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "headers.h"
+
+#include "util.h"
+#include "osdefs.h"
+
+#ifndef WIN32
+# error Why do you want to build this if you do not intend to use it?
+#endif
+
+#include <windows.h>
+#include <mmsystem.h>
+
+/* Note: [Gargaj]
+
+ WinMM DOES support max volumes up to 65535, but the scroller is
+ so goddamn slow and it only supports 3 digits anyway, that
+ it doesn't make any sense to keep the precision.
+*/
+
+int win32mm_volume_get_max(void)
+{
+ return 0xFF;
+}
+
+static HWAVEOUT open_mixer(void)
+{
+ HWAVEOUT hwo=NULL;
+ WAVEFORMATEX pwfx;
+#if 0
+ pwfx.wFormatTag = WAVE_FORMAT_UNKNOWN;
+ pwfx.nChannels = 0;
+ pwfx.nSamplesPerSec = 0;
+ pwfx.wBitsPerSample = 0;
+ pwfx.nBlockAlign = 0;
+ pwfx.nAvgBytesPerSec = 0;
+ pwfx.cbSize = 0;
+#else
+ pwfx.wFormatTag = WAVE_FORMAT_PCM;
+ pwfx.nChannels = 1;
+ pwfx.nSamplesPerSec = 44100;
+ pwfx.wBitsPerSample = 8;
+ pwfx.nBlockAlign = 4;
+ pwfx.nAvgBytesPerSec = 44100*1*1;
+ pwfx.cbSize = 0;
+#endif
+ if (waveOutOpen(&hwo, WAVE_MAPPER, &pwfx, 0, 0, CALLBACK_NULL)!=MMSYSERR_NOERROR)
+ return NULL;
+ return hwo;
+}
+
+void win32mm_volume_read(int *left, int *right)
+{
+ DWORD vol;
+
+ *left = *right = 0;
+
+ waveOutGetVolume(NULL,&vol);
+
+ *left = (vol & 0xFFFF) >> 8;
+ *right = (vol >> 16) >> 8;
+}
+
+void win32mm_volume_write(int left, int right)
+{
+ DWORD vol = ((left & 0xFF)<<8) | ((right & 0xFF)<<(16+8));
+
+ waveOutSetVolume(NULL,vol);
+}
diff --git a/src/sys/win32/wine-ddraw.h b/src/sys/win32/wine-ddraw.h
new file mode 100644
index 0000000..325dbcf
--- /dev/null
+++ b/src/sys/win32/wine-ddraw.h
@@ -0,0 +1,2679 @@
+/* this was hacked up slightly to build outside of the rest of wine
+ * it works well enough to build schism.
+ */
+
+/*
+ * Copyright (C) the Wine project
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __WINE_DDRAW_H
+#define __WINE_DDRAW_H
+
+#define COM_NO_WINDOWS_H
+#include <objbase.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* defined(__cplusplus) */
+
+#ifndef DIRECTDRAW_VERSION
+#define DIRECTDRAW_VERSION 0x0700
+#endif /* DIRECTDRAW_VERSION */
+
+/*****************************************************************************
+ * Predeclare the interfaces
+ */
+#ifndef __DDRAW_GUID_DEFINED__
+DEFINE_GUID( CLSID_DirectDraw, 0xD7B70EE0,0x4340,0x11CF,0xB0,0x63,0x00,0x20,0xAF,0xC2,0xCD,0x35 );
+DEFINE_GUID( CLSID_DirectDraw7, 0x3C305196,0x50DB,0x11D3,0x9C,0xFE,0x00,0xC0,0x4F,0xD9,0x30,0xC5 );
+DEFINE_GUID( CLSID_DirectDrawClipper, 0x593817A0,0x7DB3,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xb9,0x33,0x56 );
+DEFINE_GUID( IID_IDirectDraw, 0x6C14DB80,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 );
+DEFINE_GUID( IID_IDirectDraw2, 0xB3A6F3E0,0x2B43,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56 );
+DEFINE_GUID( IID_IDirectDraw3, 0x618f8ad4,0x8b7a,0x11d0,0x8f,0xcc,0x0,0xc0,0x4f,0xd9,0x18,0x9d );
+DEFINE_GUID( IID_IDirectDraw4, 0x9c59509a,0x39bd,0x11d1,0x8c,0x4a,0x00,0xc0,0x4f,0xd9,0x30,0xc5 );
+DEFINE_GUID( IID_IDirectDraw7, 0x15e65ec0,0x3b9c,0x11d2,0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b );
+DEFINE_GUID( IID_IDirectDrawSurface, 0x6C14DB81,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 );
+DEFINE_GUID( IID_IDirectDrawSurface2, 0x57805885,0x6eec,0x11cf,0x94,0x41,0xa8,0x23,0x03,0xc1,0x0e,0x27 );
+DEFINE_GUID( IID_IDirectDrawSurface3, 0xDA044E00,0x69B2,0x11D0,0xA1,0xD5,0x00,0xAA,0x00,0xB8,0xDF,0xBB );
+DEFINE_GUID( IID_IDirectDrawSurface4, 0x0B2B8630,0xAD35,0x11D0,0x8E,0xA6,0x00,0x60,0x97,0x97,0xEA,0x5B );
+DEFINE_GUID( IID_IDirectDrawSurface7, 0x06675a80,0x3b9b,0x11d2,0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b );
+DEFINE_GUID( IID_IDirectDrawPalette, 0x6C14DB84,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 );
+DEFINE_GUID( IID_IDirectDrawClipper, 0x6C14DB85,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 );
+DEFINE_GUID( IID_IDirectDrawColorControl,0x4B9F0EE0,0x0D7E,0x11D0,0x9B,0x06,0x00,0xA0,0xC9,0x03,0xA3,0xB8 );
+DEFINE_GUID( IID_IDirectDrawGammaControl,0x69C11C3E,0xB46B,0x11D1,0xAD,0x7A,0x00,0xC0,0x4F,0xC2,0x9B,0x4E );
+#endif
+
+typedef struct IDirectDraw *LPDIRECTDRAW;
+typedef struct IDirectDraw2 *LPDIRECTDRAW2;
+typedef struct IDirectDraw3 *LPDIRECTDRAW3;
+typedef struct IDirectDraw4 *LPDIRECTDRAW4;
+typedef struct IDirectDraw7 *LPDIRECTDRAW7;
+typedef struct IDirectDrawClipper *LPDIRECTDRAWCLIPPER;
+typedef struct IDirectDrawPalette *LPDIRECTDRAWPALETTE;
+typedef struct IDirectDrawSurface *LPDIRECTDRAWSURFACE;
+typedef struct IDirectDrawSurface2 *LPDIRECTDRAWSURFACE2;
+typedef struct IDirectDrawSurface3 *LPDIRECTDRAWSURFACE3;
+typedef struct IDirectDrawSurface4 *LPDIRECTDRAWSURFACE4;
+typedef struct IDirectDrawSurface7 *LPDIRECTDRAWSURFACE7;
+typedef struct IDirectDrawColorControl *LPDIRECTDRAWCOLORCONTROL;
+typedef struct IDirectDrawGammaControl *LPDIRECTDRAWGAMMACONTROL;
+
+
+#define DDENUMRET_CANCEL 0
+#define DDENUMRET_OK 1
+
+#define DD_OK 0
+
+
+#define _FACDD 0x876
+#define MAKE_DDHRESULT( code ) MAKE_HRESULT( 1, _FACDD, code )
+
+#define DDERR_ALREADYINITIALIZED MAKE_DDHRESULT( 5 )
+#define DDERR_CANNOTATTACHSURFACE MAKE_DDHRESULT( 10 )
+#define DDERR_CANNOTDETACHSURFACE MAKE_DDHRESULT( 20 )
+#define DDERR_CURRENTLYNOTAVAIL MAKE_DDHRESULT( 40 )
+#define DDERR_EXCEPTION MAKE_DDHRESULT( 55 )
+#define DDERR_GENERIC E_FAIL
+#define DDERR_HEIGHTALIGN MAKE_DDHRESULT( 90 )
+#define DDERR_INCOMPATIBLEPRIMARY MAKE_DDHRESULT( 95 )
+#define DDERR_INVALIDCAPS MAKE_DDHRESULT( 100 )
+#define DDERR_INVALIDCLIPLIST MAKE_DDHRESULT( 110 )
+#define DDERR_INVALIDMODE MAKE_DDHRESULT( 120 )
+#define DDERR_INVALIDOBJECT MAKE_DDHRESULT( 130 )
+#define DDERR_INVALIDPARAMS E_INVALIDARG
+#define DDERR_INVALIDPIXELFORMAT MAKE_DDHRESULT( 145 )
+#define DDERR_INVALIDRECT MAKE_DDHRESULT( 150 )
+#define DDERR_LOCKEDSURFACES MAKE_DDHRESULT( 160 )
+#define DDERR_NO3D MAKE_DDHRESULT( 170 )
+#define DDERR_NOALPHAHW MAKE_DDHRESULT( 180 )
+#define DDERR_NOSTEREOHARDWARE MAKE_DDHRESULT( 181 )
+#define DDERR_NOSURFACELEFT MAKE_DDHRESULT( 182 )
+#define DDERR_NOCLIPLIST MAKE_DDHRESULT( 205 )
+#define DDERR_NOCOLORCONVHW MAKE_DDHRESULT( 210 )
+#define DDERR_NOCOOPERATIVELEVELSET MAKE_DDHRESULT( 212 )
+#define DDERR_NOCOLORKEY MAKE_DDHRESULT( 215 )
+#define DDERR_NOCOLORKEYHW MAKE_DDHRESULT( 220 )
+#define DDERR_NODIRECTDRAWSUPPORT MAKE_DDHRESULT( 222 )
+#define DDERR_NOEXCLUSIVEMODE MAKE_DDHRESULT( 225 )
+#define DDERR_NOFLIPHW MAKE_DDHRESULT( 230 )
+#define DDERR_NOGDI MAKE_DDHRESULT( 240 )
+#define DDERR_NOMIRRORHW MAKE_DDHRESULT( 250 )
+#define DDERR_NOTFOUND MAKE_DDHRESULT( 255 )
+#define DDERR_NOOVERLAYHW MAKE_DDHRESULT( 260 )
+#define DDERR_OVERLAPPINGRECTS MAKE_DDHRESULT( 270 )
+#define DDERR_NORASTEROPHW MAKE_DDHRESULT( 280 )
+#define DDERR_NOROTATIONHW MAKE_DDHRESULT( 290 )
+#define DDERR_NOSTRETCHHW MAKE_DDHRESULT( 310 )
+#define DDERR_NOT4BITCOLOR MAKE_DDHRESULT( 316 )
+#define DDERR_NOT4BITCOLORINDEX MAKE_DDHRESULT( 317 )
+#define DDERR_NOT8BITCOLOR MAKE_DDHRESULT( 320 )
+#define DDERR_NOTEXTUREHW MAKE_DDHRESULT( 330 )
+#define DDERR_NOVSYNCHW MAKE_DDHRESULT( 335 )
+#define DDERR_NOZBUFFERHW MAKE_DDHRESULT( 340 )
+#define DDERR_NOZOVERLAYHW MAKE_DDHRESULT( 350 )
+#define DDERR_OUTOFCAPS MAKE_DDHRESULT( 360 )
+#define DDERR_OUTOFMEMORY E_OUTOFMEMORY
+#define DDERR_OUTOFVIDEOMEMORY MAKE_DDHRESULT( 380 )
+#define DDERR_OVERLAYCANTCLIP MAKE_DDHRESULT( 382 )
+#define DDERR_OVERLAYCOLORKEYONLYONEACTIVE MAKE_DDHRESULT( 384 )
+#define DDERR_PALETTEBUSY MAKE_DDHRESULT( 387 )
+#define DDERR_COLORKEYNOTSET MAKE_DDHRESULT( 400 )
+#define DDERR_SURFACEALREADYATTACHED MAKE_DDHRESULT( 410 )
+#define DDERR_SURFACEALREADYDEPENDENT MAKE_DDHRESULT( 420 )
+#define DDERR_SURFACEBUSY MAKE_DDHRESULT( 430 )
+#define DDERR_CANTLOCKSURFACE MAKE_DDHRESULT( 435 )
+#define DDERR_SURFACEISOBSCURED MAKE_DDHRESULT( 440 )
+#define DDERR_SURFACELOST MAKE_DDHRESULT( 450 )
+#define DDERR_SURFACENOTATTACHED MAKE_DDHRESULT( 460 )
+#define DDERR_TOOBIGHEIGHT MAKE_DDHRESULT( 470 )
+#define DDERR_TOOBIGSIZE MAKE_DDHRESULT( 480 )
+#define DDERR_TOOBIGWIDTH MAKE_DDHRESULT( 490 )
+#define DDERR_UNSUPPORTED E_NOTIMPL
+#define DDERR_UNSUPPORTEDFORMAT MAKE_DDHRESULT( 510 )
+#define DDERR_UNSUPPORTEDMASK MAKE_DDHRESULT( 520 )
+#define DDERR_INVALIDSTREAM MAKE_DDHRESULT( 521 )
+#define DDERR_VERTICALBLANKINPROGRESS MAKE_DDHRESULT( 537 )
+#define DDERR_WASSTILLDRAWING MAKE_DDHRESULT( 540 )
+#define DDERR_DDSCAPSCOMPLEXREQUIRED MAKE_DDHRESULT( 542 )
+#define DDERR_XALIGN MAKE_DDHRESULT( 560 )
+#define DDERR_INVALIDDIRECTDRAWGUID MAKE_DDHRESULT( 561 )
+#define DDERR_DIRECTDRAWALREADYCREATED MAKE_DDHRESULT( 562 )
+#define DDERR_NODIRECTDRAWHW MAKE_DDHRESULT( 563 )
+#define DDERR_PRIMARYSURFACEALREADYEXISTS MAKE_DDHRESULT( 564 )
+#define DDERR_NOEMULATION MAKE_DDHRESULT( 565 )
+#define DDERR_REGIONTOOSMALL MAKE_DDHRESULT( 566 )
+#define DDERR_CLIPPERISUSINGHWND MAKE_DDHRESULT( 567 )
+#define DDERR_NOCLIPPERATTACHED MAKE_DDHRESULT( 568 )
+#define DDERR_NOHWND MAKE_DDHRESULT( 569 )
+#define DDERR_HWNDSUBCLASSED MAKE_DDHRESULT( 570 )
+#define DDERR_HWNDALREADYSET MAKE_DDHRESULT( 571 )
+#define DDERR_NOPALETTEATTACHED MAKE_DDHRESULT( 572 )
+#define DDERR_NOPALETTEHW MAKE_DDHRESULT( 573 )
+#define DDERR_BLTFASTCANTCLIP MAKE_DDHRESULT( 574 )
+#define DDERR_NOBLTHW MAKE_DDHRESULT( 575 )
+#define DDERR_NODDROPSHW MAKE_DDHRESULT( 576 )
+#define DDERR_OVERLAYNOTVISIBLE MAKE_DDHRESULT( 577 )
+#define DDERR_NOOVERLAYDEST MAKE_DDHRESULT( 578 )
+#define DDERR_INVALIDPOSITION MAKE_DDHRESULT( 579 )
+#define DDERR_NOTAOVERLAYSURFACE MAKE_DDHRESULT( 580 )
+#define DDERR_EXCLUSIVEMODEALREADYSET MAKE_DDHRESULT( 581 )
+#define DDERR_NOTFLIPPABLE MAKE_DDHRESULT( 582 )
+#define DDERR_CANTDUPLICATE MAKE_DDHRESULT( 583 )
+#define DDERR_NOTLOCKED MAKE_DDHRESULT( 584 )
+#define DDERR_CANTCREATEDC MAKE_DDHRESULT( 585 )
+#define DDERR_NODC MAKE_DDHRESULT( 586 )
+#define DDERR_WRONGMODE MAKE_DDHRESULT( 587 )
+#define DDERR_IMPLICITLYCREATED MAKE_DDHRESULT( 588 )
+#define DDERR_NOTPALETTIZED MAKE_DDHRESULT( 589 )
+#define DDERR_UNSUPPORTEDMODE MAKE_DDHRESULT( 590 )
+#define DDERR_NOMIPMAPHW MAKE_DDHRESULT( 591 )
+#define DDERR_INVALIDSURFACETYPE MAKE_DDHRESULT( 592 )
+#define DDERR_NOOPTIMIZEHW MAKE_DDHRESULT( 600 )
+#define DDERR_NOTLOADED MAKE_DDHRESULT( 601 )
+#define DDERR_NOFOCUSWINDOW MAKE_DDHRESULT( 602 )
+#define DDERR_NOTONMIPMAPSUBLEVEL MAKE_DDHRESULT( 603 )
+#define DDERR_DCALREADYCREATED MAKE_DDHRESULT( 620 )
+#define DDERR_NONONLOCALVIDMEM MAKE_DDHRESULT( 630 )
+#define DDERR_CANTPAGELOCK MAKE_DDHRESULT( 640 )
+#define DDERR_CANTPAGEUNLOCK MAKE_DDHRESULT( 660 )
+#define DDERR_NOTPAGELOCKED MAKE_DDHRESULT( 680 )
+#define DDERR_MOREDATA MAKE_DDHRESULT( 690 )
+#define DDERR_EXPIRED MAKE_DDHRESULT( 691 )
+#define DDERR_TESTFINISHED MAKE_DDHRESULT( 692 )
+#define DDERR_NEWMODE MAKE_DDHRESULT( 693 )
+#define DDERR_D3DNOTINITIALIZED MAKE_DDHRESULT( 694 )
+#define DDERR_VIDEONOTACTIVE MAKE_DDHRESULT( 695 )
+#define DDERR_NOMONITORINFORMATION MAKE_DDHRESULT( 696 )
+#define DDERR_NODRIVERSUPPORT MAKE_DDHRESULT( 697 )
+#define DDERR_DEVICEDOESNTOWNSURFACE MAKE_DDHRESULT( 699 )
+#define DDERR_NOTINITIALIZED CO_E_NOTINITIALIZED
+
+/* dwFlags for Blt* */
+#define DDBLT_ALPHADEST 0x00000001
+#define DDBLT_ALPHADESTCONSTOVERRIDE 0x00000002
+#define DDBLT_ALPHADESTNEG 0x00000004
+#define DDBLT_ALPHADESTSURFACEOVERRIDE 0x00000008
+#define DDBLT_ALPHAEDGEBLEND 0x00000010
+#define DDBLT_ALPHASRC 0x00000020
+#define DDBLT_ALPHASRCCONSTOVERRIDE 0x00000040
+#define DDBLT_ALPHASRCNEG 0x00000080
+#define DDBLT_ALPHASRCSURFACEOVERRIDE 0x00000100
+#define DDBLT_ASYNC 0x00000200
+#define DDBLT_COLORFILL 0x00000400
+#define DDBLT_DDFX 0x00000800
+#define DDBLT_DDROPS 0x00001000
+#define DDBLT_KEYDEST 0x00002000
+#define DDBLT_KEYDESTOVERRIDE 0x00004000
+#define DDBLT_KEYSRC 0x00008000
+#define DDBLT_KEYSRCOVERRIDE 0x00010000
+#define DDBLT_ROP 0x00020000
+#define DDBLT_ROTATIONANGLE 0x00040000
+#define DDBLT_ZBUFFER 0x00080000
+#define DDBLT_ZBUFFERDESTCONSTOVERRIDE 0x00100000
+#define DDBLT_ZBUFFERDESTOVERRIDE 0x00200000
+#define DDBLT_ZBUFFERSRCCONSTOVERRIDE 0x00400000
+#define DDBLT_ZBUFFERSRCOVERRIDE 0x00800000
+#define DDBLT_WAIT 0x01000000
+#define DDBLT_DEPTHFILL 0x02000000
+#define DDBLT_DONOTWAIT 0x08000000
+
+/* dwTrans for BltFast */
+#define DDBLTFAST_NOCOLORKEY 0x00000000
+#define DDBLTFAST_SRCCOLORKEY 0x00000001
+#define DDBLTFAST_DESTCOLORKEY 0x00000002
+#define DDBLTFAST_WAIT 0x00000010
+#define DDBLTFAST_DONOTWAIT 0x00000020
+
+/* dwFlags for Flip */
+#define DDFLIP_WAIT 0x00000001
+#define DDFLIP_EVEN 0x00000002 /* only valid for overlay */
+#define DDFLIP_ODD 0x00000004 /* only valid for overlay */
+#define DDFLIP_NOVSYNC 0x00000008
+#define DDFLIP_STEREO 0x00000010
+#define DDFLIP_DONOTWAIT 0x00000020
+#define DDFLIP_INTERVAL2 0x02000000
+#define DDFLIP_INTERVAL3 0x03000000
+#define DDFLIP_INTERVAL4 0x04000000
+
+
+/* dwFlags for GetBltStatus */
+#define DDGBS_CANBLT 0x00000001
+#define DDGBS_ISBLTDONE 0x00000002
+
+/* dwFlags for IDirectDrawSurface7::GetFlipStatus */
+#define DDGFS_CANFLIP 1L
+#define DDGFS_ISFLIPDONE 2L
+
+/* dwFlags for IDirectDrawSurface7::SetPrivateData */
+#define DDSPD_IUNKNOWNPOINTER 1L
+#define DDSPD_VOLATILE 2L
+
+/* DDSCAPS.dwCaps */
+/* reserved1, was 3d capable */
+#define DDSCAPS_RESERVED1 0x00000001
+/* surface contains alpha information */
+#define DDSCAPS_ALPHA 0x00000002
+/* this surface is a backbuffer */
+#define DDSCAPS_BACKBUFFER 0x00000004
+/* complex surface structure */
+#define DDSCAPS_COMPLEX 0x00000008
+/* part of surface flipping structure */
+#define DDSCAPS_FLIP 0x00000010
+/* this surface is the frontbuffer surface */
+#define DDSCAPS_FRONTBUFFER 0x00000020
+/* this is a plain offscreen surface */
+#define DDSCAPS_OFFSCREENPLAIN 0x00000040
+/* overlay */
+#define DDSCAPS_OVERLAY 0x00000080
+/* palette objects can be created and attached to us */
+#define DDSCAPS_PALETTE 0x00000100
+/* primary surface (the one the user looks at currently)(right eye)*/
+#define DDSCAPS_PRIMARYSURFACE 0x00000200
+/* primary surface for left eye */
+#define DDSCAPS_PRIMARYSURFACELEFT 0x00000400
+/* surface exists in systemmemory */
+#define DDSCAPS_SYSTEMMEMORY 0x00000800
+/* surface can be used as a texture */
+#define DDSCAPS_TEXTURE 0x00001000
+/* surface may be destination for 3d rendering */
+#define DDSCAPS_3DDEVICE 0x00002000
+/* surface exists in videomemory */
+#define DDSCAPS_VIDEOMEMORY 0x00004000
+/* surface changes immediately visible */
+#define DDSCAPS_VISIBLE 0x00008000
+/* write only surface */
+#define DDSCAPS_WRITEONLY 0x00010000
+/* zbuffer surface */
+#define DDSCAPS_ZBUFFER 0x00020000
+/* has its own DC */
+#define DDSCAPS_OWNDC 0x00040000
+/* surface should be able to receive live video */
+#define DDSCAPS_LIVEVIDEO 0x00080000
+/* should be able to have a hw codec decompress stuff into it */
+#define DDSCAPS_HWCODEC 0x00100000
+/* mode X (320x200 or 320x240) surface */
+#define DDSCAPS_MODEX 0x00200000
+/* one mipmap surface (1 level) */
+#define DDSCAPS_MIPMAP 0x00400000
+#define DDSCAPS_RESERVED2 0x00800000
+/* memory allocation delayed until Load() */
+#define DDSCAPS_ALLOCONLOAD 0x04000000
+/* Indicates that the surface will receive data from a video port */
+#define DDSCAPS_VIDEOPORT 0x08000000
+/* surface is in local videomemory */
+#define DDSCAPS_LOCALVIDMEM 0x10000000
+/* surface is in nonlocal videomemory */
+#define DDSCAPS_NONLOCALVIDMEM 0x20000000
+/* surface is a standard VGA mode surface (NOT ModeX) */
+#define DDSCAPS_STANDARDVGAMODE 0x40000000
+/* optimized? surface */
+#define DDSCAPS_OPTIMIZED 0x80000000
+
+typedef struct _DDSCAPS {
+ DWORD dwCaps; /* capabilities of surface wanted */
+} DDSCAPS,*LPDDSCAPS;
+
+/* DDSCAPS2.dwCaps2 */
+/* indicates the surface will receive data from a video port using
+ deinterlacing hardware. */
+#define DDSCAPS2_HARDWAREDEINTERLACE 0x00000002
+/* indicates the surface will be locked very frequently. */
+#define DDSCAPS2_HINTDYNAMIC 0x00000004
+/* indicates surface can be re-ordered or retiled on load() */
+#define DDSCAPS2_HINTSTATIC 0x00000008
+/* indicates surface to be managed by directdraw/direct3D */
+#define DDSCAPS2_TEXTUREMANAGE 0x00000010
+/* reserved bits */
+#define DDSCAPS2_RESERVED1 0x00000020
+#define DDSCAPS2_RESERVED2 0x00000040
+/* indicates surface will never be locked again */
+#define DDSCAPS2_OPAQUE 0x00000080
+/* set at CreateSurface() time to indicate antialiasing will be used */
+#define DDSCAPS2_HINTANTIALIASING 0x00000100
+/* set at CreateSurface() time to indicate cubic environment map */
+#define DDSCAPS2_CUBEMAP 0x00000200
+/* face flags for cube maps */
+#define DDSCAPS2_CUBEMAP_POSITIVEX 0x00000400
+#define DDSCAPS2_CUBEMAP_NEGATIVEX 0x00000800
+#define DDSCAPS2_CUBEMAP_POSITIVEY 0x00001000
+#define DDSCAPS2_CUBEMAP_NEGATIVEY 0x00002000
+#define DDSCAPS2_CUBEMAP_POSITIVEZ 0x00004000
+#define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x00008000
+/* specifies all faces of a cube for CreateSurface() */
+#define DDSCAPS2_CUBEMAP_ALLFACES ( DDSCAPS2_CUBEMAP_POSITIVEX |\
+ DDSCAPS2_CUBEMAP_NEGATIVEX |\
+ DDSCAPS2_CUBEMAP_POSITIVEY |\
+ DDSCAPS2_CUBEMAP_NEGATIVEY |\
+ DDSCAPS2_CUBEMAP_POSITIVEZ |\
+ DDSCAPS2_CUBEMAP_NEGATIVEZ )
+/* set for mipmap sublevels on DirectX7 and later. ignored by CreateSurface() */
+#define DDSCAPS2_MIPMAPSUBLEVEL 0x00010000
+/* indicates texture surface to be managed by Direct3D *only* */
+#define DDSCAPS2_D3DTEXTUREMANAGE 0x00020000
+/* indicates managed surface that can safely be lost */
+#define DDSCAPS2_DONOTPERSIST 0x00040000
+/* indicates surface is part of a stereo flipping chain */
+#define DDSCAPS2_STEREOSURFACELEFT 0x00080000
+
+typedef struct _DDSCAPS2 {
+ DWORD dwCaps; /* capabilities of surface wanted */
+ DWORD dwCaps2; /* additional capabilities */
+ DWORD dwCaps3; /* reserved capabilities */
+ DWORD dwCaps4; /* more reserved capabilities */
+} DDSCAPS2,*LPDDSCAPS2;
+
+#define DD_ROP_SPACE (256/32) /* space required to store ROP array */
+
+typedef struct _DDCAPS_DX7 /* DirectX 7 version of caps struct */
+{
+ DWORD dwSize; /* size of the DDDRIVERCAPS structure */
+ DWORD dwCaps; /* driver specific capabilities */
+ DWORD dwCaps2; /* more driver specific capabilities */
+ DWORD dwCKeyCaps; /* color key capabilities of the surface */
+ DWORD dwFXCaps; /* driver specific stretching and effects capabilities */
+ DWORD dwFXAlphaCaps; /* alpha driver specific capabilities */
+ DWORD dwPalCaps; /* palette capabilities */
+ DWORD dwSVCaps; /* stereo vision capabilities */
+ DWORD dwAlphaBltConstBitDepths; /* DDBD_2,4,8 */
+ DWORD dwAlphaBltPixelBitDepths; /* DDBD_1,2,4,8 */
+ DWORD dwAlphaBltSurfaceBitDepths; /* DDBD_1,2,4,8 */
+ DWORD dwAlphaOverlayConstBitDepths; /* DDBD_2,4,8 */
+ DWORD dwAlphaOverlayPixelBitDepths; /* DDBD_1,2,4,8 */
+ DWORD dwAlphaOverlaySurfaceBitDepths; /* DDBD_1,2,4,8 */
+ DWORD dwZBufferBitDepths; /* DDBD_8,16,24,32 */
+ DWORD dwVidMemTotal; /* total amount of video memory */
+ DWORD dwVidMemFree; /* amount of free video memory */
+ DWORD dwMaxVisibleOverlays; /* maximum number of visible overlays */
+ DWORD dwCurrVisibleOverlays; /* current number of visible overlays */
+ DWORD dwNumFourCCCodes; /* number of four cc codes */
+ DWORD dwAlignBoundarySrc; /* source rectangle alignment */
+ DWORD dwAlignSizeSrc; /* source rectangle byte size */
+ DWORD dwAlignBoundaryDest; /* dest rectangle alignment */
+ DWORD dwAlignSizeDest; /* dest rectangle byte size */
+ DWORD dwAlignStrideAlign; /* stride alignment */
+ DWORD dwRops[DD_ROP_SPACE]; /* ROPS supported */
+ DDSCAPS ddsOldCaps; /* old DDSCAPS - superseded for DirectX6+ */
+ DWORD dwMinOverlayStretch; /* minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+ DWORD dwMaxOverlayStretch; /* maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+ DWORD dwMinLiveVideoStretch; /* minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+ DWORD dwMaxLiveVideoStretch; /* maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+ DWORD dwMinHwCodecStretch; /* minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+ DWORD dwMaxHwCodecStretch; /* maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+ DWORD dwReserved1;
+ DWORD dwReserved2;
+ DWORD dwReserved3;
+ DWORD dwSVBCaps; /* driver specific capabilities for System->Vmem blts */
+ DWORD dwSVBCKeyCaps; /* driver color key capabilities for System->Vmem blts */
+ DWORD dwSVBFXCaps; /* driver FX capabilities for System->Vmem blts */
+ DWORD dwSVBRops[DD_ROP_SPACE];/* ROPS supported for System->Vmem blts */
+ DWORD dwVSBCaps; /* driver specific capabilities for Vmem->System blts */
+ DWORD dwVSBCKeyCaps; /* driver color key capabilities for Vmem->System blts */
+ DWORD dwVSBFXCaps; /* driver FX capabilities for Vmem->System blts */
+ DWORD dwVSBRops[DD_ROP_SPACE];/* ROPS supported for Vmem->System blts */
+ DWORD dwSSBCaps; /* driver specific capabilities for System->System blts */
+ DWORD dwSSBCKeyCaps; /* driver color key capabilities for System->System blts */
+ DWORD dwSSBFXCaps; /* driver FX capabilities for System->System blts */
+ DWORD dwSSBRops[DD_ROP_SPACE];/* ROPS supported for System->System blts */
+ DWORD dwMaxVideoPorts; /* maximum number of usable video ports */
+ DWORD dwCurrVideoPorts; /* current number of video ports used */
+ DWORD dwSVBCaps2; /* more driver specific capabilities for System->Vmem blts */
+ DWORD dwNLVBCaps; /* driver specific capabilities for non-local->local vidmem blts */
+ DWORD dwNLVBCaps2; /* more driver specific capabilities non-local->local vidmem blts */
+ DWORD dwNLVBCKeyCaps; /* driver color key capabilities for non-local->local vidmem blts */
+ DWORD dwNLVBFXCaps; /* driver FX capabilities for non-local->local blts */
+ DWORD dwNLVBRops[DD_ROP_SPACE]; /* ROPS supported for non-local->local blts */
+ DDSCAPS2 ddsCaps; /* surface capabilities */
+} DDCAPS_DX7,*LPDDCAPS_DX7;
+
+typedef struct _DDCAPS_DX6 /* DirectX 6 version of caps struct */
+{
+ DWORD dwSize; /* size of the DDDRIVERCAPS structure */
+ DWORD dwCaps; /* driver specific capabilities */
+ DWORD dwCaps2; /* more driver specific capabilities */
+ DWORD dwCKeyCaps; /* color key capabilities of the surface */
+ DWORD dwFXCaps; /* driver specific stretching and effects capabilities */
+ DWORD dwFXAlphaCaps; /* alpha driver specific capabilities */
+ DWORD dwPalCaps; /* palette capabilities */
+ DWORD dwSVCaps; /* stereo vision capabilities */
+ DWORD dwAlphaBltConstBitDepths; /* DDBD_2,4,8 */
+ DWORD dwAlphaBltPixelBitDepths; /* DDBD_1,2,4,8 */
+ DWORD dwAlphaBltSurfaceBitDepths; /* DDBD_1,2,4,8 */
+ DWORD dwAlphaOverlayConstBitDepths; /* DDBD_2,4,8 */
+ DWORD dwAlphaOverlayPixelBitDepths; /* DDBD_1,2,4,8 */
+ DWORD dwAlphaOverlaySurfaceBitDepths; /* DDBD_1,2,4,8 */
+ DWORD dwZBufferBitDepths; /* DDBD_8,16,24,32 */
+ DWORD dwVidMemTotal; /* total amount of video memory */
+ DWORD dwVidMemFree; /* amount of free video memory */
+ DWORD dwMaxVisibleOverlays; /* maximum number of visible overlays */
+ DWORD dwCurrVisibleOverlays; /* current number of visible overlays */
+ DWORD dwNumFourCCCodes; /* number of four cc codes */
+ DWORD dwAlignBoundarySrc; /* source rectangle alignment */
+ DWORD dwAlignSizeSrc; /* source rectangle byte size */
+ DWORD dwAlignBoundaryDest; /* dest rectangle alignment */
+ DWORD dwAlignSizeDest; /* dest rectangle byte size */
+ DWORD dwAlignStrideAlign; /* stride alignment */
+ DWORD dwRops[DD_ROP_SPACE]; /* ROPS supported */
+ DDSCAPS ddsOldCaps; /* old DDSCAPS - superseded for DirectX6+ */
+ DWORD dwMinOverlayStretch; /* minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+ DWORD dwMaxOverlayStretch; /* maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+ DWORD dwMinLiveVideoStretch; /* minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+ DWORD dwMaxLiveVideoStretch; /* maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+ DWORD dwMinHwCodecStretch; /* minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+ DWORD dwMaxHwCodecStretch; /* maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+ DWORD dwReserved1;
+ DWORD dwReserved2;
+ DWORD dwReserved3;
+ DWORD dwSVBCaps; /* driver specific capabilities for System->Vmem blts */
+ DWORD dwSVBCKeyCaps; /* driver color key capabilities for System->Vmem blts */
+ DWORD dwSVBFXCaps; /* driver FX capabilities for System->Vmem blts */
+ DWORD dwSVBRops[DD_ROP_SPACE];/* ROPS supported for System->Vmem blts */
+ DWORD dwVSBCaps; /* driver specific capabilities for Vmem->System blts */
+ DWORD dwVSBCKeyCaps; /* driver color key capabilities for Vmem->System blts */
+ DWORD dwVSBFXCaps; /* driver FX capabilities for Vmem->System blts */
+ DWORD dwVSBRops[DD_ROP_SPACE];/* ROPS supported for Vmem->System blts */
+ DWORD dwSSBCaps; /* driver specific capabilities for System->System blts */
+ DWORD dwSSBCKeyCaps; /* driver color key capabilities for System->System blts */
+ DWORD dwSSBFXCaps; /* driver FX capabilities for System->System blts */
+ DWORD dwSSBRops[DD_ROP_SPACE];/* ROPS supported for System->System blts */
+ DWORD dwMaxVideoPorts; /* maximum number of usable video ports */
+ DWORD dwCurrVideoPorts; /* current number of video ports used */
+ DWORD dwSVBCaps2; /* more driver specific capabilities for System->Vmem blts */
+ DWORD dwNLVBCaps; /* driver specific capabilities for non-local->local vidmem blts */
+ DWORD dwNLVBCaps2; /* more driver specific capabilities non-local->local vidmem blts */
+ DWORD dwNLVBCKeyCaps; /* driver color key capabilities for non-local->local vidmem blts */
+ DWORD dwNLVBFXCaps; /* driver FX capabilities for non-local->local blts */
+ DWORD dwNLVBRops[DD_ROP_SPACE]; /* ROPS supported for non-local->local blts */
+ /* and one new member for DirectX 6 */
+ DDSCAPS2 ddsCaps; /* surface capabilities */
+} DDCAPS_DX6,*LPDDCAPS_DX6;
+
+typedef struct _DDCAPS_DX5 /* DirectX5 version of caps struct */
+{
+ DWORD dwSize; /* size of the DDDRIVERCAPS structure */
+ DWORD dwCaps; /* driver specific capabilities */
+ DWORD dwCaps2; /* more driver specific capabilities */
+ DWORD dwCKeyCaps; /* color key capabilities of the surface */
+ DWORD dwFXCaps; /* driver specific stretching and effects capabilities */
+ DWORD dwFXAlphaCaps; /* alpha driver specific capabilities */
+ DWORD dwPalCaps; /* palette capabilities */
+ DWORD dwSVCaps; /* stereo vision capabilities */
+ DWORD dwAlphaBltConstBitDepths; /* DDBD_2,4,8 */
+ DWORD dwAlphaBltPixelBitDepths; /* DDBD_1,2,4,8 */
+ DWORD dwAlphaBltSurfaceBitDepths; /* DDBD_1,2,4,8 */
+ DWORD dwAlphaOverlayConstBitDepths; /* DDBD_2,4,8 */
+ DWORD dwAlphaOverlayPixelBitDepths; /* DDBD_1,2,4,8 */
+ DWORD dwAlphaOverlaySurfaceBitDepths; /* DDBD_1,2,4,8 */
+ DWORD dwZBufferBitDepths; /* DDBD_8,16,24,32 */
+ DWORD dwVidMemTotal; /* total amount of video memory */
+ DWORD dwVidMemFree; /* amount of free video memory */
+ DWORD dwMaxVisibleOverlays; /* maximum number of visible overlays */
+ DWORD dwCurrVisibleOverlays; /* current number of visible overlays */
+ DWORD dwNumFourCCCodes; /* number of four cc codes */
+ DWORD dwAlignBoundarySrc; /* source rectangle alignment */
+ DWORD dwAlignSizeSrc; /* source rectangle byte size */
+ DWORD dwAlignBoundaryDest; /* dest rectangle alignment */
+ DWORD dwAlignSizeDest; /* dest rectangle byte size */
+ DWORD dwAlignStrideAlign; /* stride alignment */
+ DWORD dwRops[DD_ROP_SPACE]; /* ROPS supported */
+ DDSCAPS ddsCaps; /* DDSCAPS structure has all the general capabilities */
+ DWORD dwMinOverlayStretch; /* minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+ DWORD dwMaxOverlayStretch; /* maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+ DWORD dwMinLiveVideoStretch; /* minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+ DWORD dwMaxLiveVideoStretch; /* maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+ DWORD dwMinHwCodecStretch; /* minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+ DWORD dwMaxHwCodecStretch; /* maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+ DWORD dwReserved1;
+ DWORD dwReserved2;
+ DWORD dwReserved3;
+ DWORD dwSVBCaps; /* driver specific capabilities for System->Vmem blts */
+ DWORD dwSVBCKeyCaps; /* driver color key capabilities for System->Vmem blts */
+ DWORD dwSVBFXCaps; /* driver FX capabilities for System->Vmem blts */
+ DWORD dwSVBRops[DD_ROP_SPACE];/* ROPS supported for System->Vmem blts */
+ DWORD dwVSBCaps; /* driver specific capabilities for Vmem->System blts */
+ DWORD dwVSBCKeyCaps; /* driver color key capabilities for Vmem->System blts */
+ DWORD dwVSBFXCaps; /* driver FX capabilities for Vmem->System blts */
+ DWORD dwVSBRops[DD_ROP_SPACE];/* ROPS supported for Vmem->System blts */
+ DWORD dwSSBCaps; /* driver specific capabilities for System->System blts */
+ DWORD dwSSBCKeyCaps; /* driver color key capabilities for System->System blts */
+ DWORD dwSSBFXCaps; /* driver FX capabilities for System->System blts */
+ DWORD dwSSBRops[DD_ROP_SPACE];/* ROPS supported for System->System blts */
+ /* the following are the new DirectX 5 members */
+ DWORD dwMaxVideoPorts; /* maximum number of usable video ports */
+ DWORD dwCurrVideoPorts; /* current number of video ports used */
+ DWORD dwSVBCaps2; /* more driver specific capabilities for System->Vmem blts */
+ DWORD dwNLVBCaps; /* driver specific capabilities for non-local->local vidmem blts */
+ DWORD dwNLVBCaps2; /* more driver specific capabilities non-local->local vidmem blts */
+ DWORD dwNLVBCKeyCaps; /* driver color key capabilities for non-local->local vidmem blts */
+ DWORD dwNLVBFXCaps; /* driver FX capabilities for non-local->local blts */
+ DWORD dwNLVBRops[DD_ROP_SPACE]; /* ROPS supported for non-local->local blts */
+} DDCAPS_DX5,*LPDDCAPS_DX5;
+
+typedef struct _DDCAPS_DX3 /* DirectX3 version of caps struct */
+{
+ DWORD dwSize; /* size of the DDDRIVERCAPS structure */
+ DWORD dwCaps; /* driver specific capabilities */
+ DWORD dwCaps2; /* more driver specific capabilities */
+ DWORD dwCKeyCaps; /* color key capabilities of the surface */
+ DWORD dwFXCaps; /* driver specific stretching and effects capabilities */
+ DWORD dwFXAlphaCaps; /* alpha driver specific capabilities */
+ DWORD dwPalCaps; /* palette capabilities */
+ DWORD dwSVCaps; /* stereo vision capabilities */
+ DWORD dwAlphaBltConstBitDepths; /* DDBD_2,4,8 */
+ DWORD dwAlphaBltPixelBitDepths; /* DDBD_1,2,4,8 */
+ DWORD dwAlphaBltSurfaceBitDepths; /* DDBD_1,2,4,8 */
+ DWORD dwAlphaOverlayConstBitDepths; /* DDBD_2,4,8 */
+ DWORD dwAlphaOverlayPixelBitDepths; /* DDBD_1,2,4,8 */
+ DWORD dwAlphaOverlaySurfaceBitDepths; /* DDBD_1,2,4,8 */
+ DWORD dwZBufferBitDepths; /* DDBD_8,16,24,32 */
+ DWORD dwVidMemTotal; /* total amount of video memory */
+ DWORD dwVidMemFree; /* amount of free video memory */
+ DWORD dwMaxVisibleOverlays; /* maximum number of visible overlays */
+ DWORD dwCurrVisibleOverlays; /* current number of visible overlays */
+ DWORD dwNumFourCCCodes; /* number of four cc codes */
+ DWORD dwAlignBoundarySrc; /* source rectangle alignment */
+ DWORD dwAlignSizeSrc; /* source rectangle byte size */
+ DWORD dwAlignBoundaryDest; /* dest rectangle alignment */
+ DWORD dwAlignSizeDest; /* dest rectangle byte size */
+ DWORD dwAlignStrideAlign; /* stride alignment */
+ DWORD dwRops[DD_ROP_SPACE]; /* ROPS supported */
+ DDSCAPS ddsCaps; /* DDSCAPS structure has all the general capabilities */
+ DWORD dwMinOverlayStretch; /* minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+ DWORD dwMaxOverlayStretch; /* maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+ DWORD dwMinLiveVideoStretch; /* minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+ DWORD dwMaxLiveVideoStretch; /* maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+ DWORD dwMinHwCodecStretch; /* minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+ DWORD dwMaxHwCodecStretch; /* maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+ DWORD dwReserved1;
+ DWORD dwReserved2;
+ DWORD dwReserved3;
+ DWORD dwSVBCaps; /* driver specific capabilities for System->Vmem blts */
+ DWORD dwSVBCKeyCaps; /* driver color key capabilities for System->Vmem blts */
+ DWORD dwSVBFXCaps; /* driver FX capabilities for System->Vmem blts */
+ DWORD dwSVBRops[DD_ROP_SPACE];/* ROPS supported for System->Vmem blts */
+ DWORD dwVSBCaps; /* driver specific capabilities for Vmem->System blts */
+ DWORD dwVSBCKeyCaps; /* driver color key capabilities for Vmem->System blts */
+ DWORD dwVSBFXCaps; /* driver FX capabilities for Vmem->System blts */
+ DWORD dwVSBRops[DD_ROP_SPACE];/* ROPS supported for Vmem->System blts */
+ DWORD dwSSBCaps; /* driver specific capabilities for System->System blts */
+ DWORD dwSSBCKeyCaps; /* driver color key capabilities for System->System blts */
+ DWORD dwSSBFXCaps; /* driver FX capabilities for System->System blts */
+ DWORD dwSSBRops[DD_ROP_SPACE];/* ROPS supported for System->System blts */
+ DWORD dwReserved4;
+ DWORD dwReserved5;
+ DWORD dwReserved6;
+} DDCAPS_DX3,*LPDDCAPS_DX3;
+
+/* set caps struct according to DIRECTDRAW_VERSION */
+
+#if DIRECTDRAW_VERSION <= 0x300
+typedef DDCAPS_DX3 DDCAPS;
+#elif DIRECTDRAW_VERSION <= 0x500
+typedef DDCAPS_DX5 DDCAPS;
+#elif DIRECTDRAW_VERSION <= 0x600
+typedef DDCAPS_DX6 DDCAPS;
+#else
+typedef DDCAPS_DX7 DDCAPS;
+#endif
+
+typedef DDCAPS *LPDDCAPS;
+
+/* DDCAPS.dwCaps */
+#define DDCAPS_3D 0x00000001
+#define DDCAPS_ALIGNBOUNDARYDEST 0x00000002
+#define DDCAPS_ALIGNSIZEDEST 0x00000004
+#define DDCAPS_ALIGNBOUNDARYSRC 0x00000008
+#define DDCAPS_ALIGNSIZESRC 0x00000010
+#define DDCAPS_ALIGNSTRIDE 0x00000020
+#define DDCAPS_BLT 0x00000040
+#define DDCAPS_BLTQUEUE 0x00000080
+#define DDCAPS_BLTFOURCC 0x00000100
+#define DDCAPS_BLTSTRETCH 0x00000200
+#define DDCAPS_GDI 0x00000400
+#define DDCAPS_OVERLAY 0x00000800
+#define DDCAPS_OVERLAYCANTCLIP 0x00001000
+#define DDCAPS_OVERLAYFOURCC 0x00002000
+#define DDCAPS_OVERLAYSTRETCH 0x00004000
+#define DDCAPS_PALETTE 0x00008000
+#define DDCAPS_PALETTEVSYNC 0x00010000
+#define DDCAPS_READSCANLINE 0x00020000
+#define DDCAPS_STEREOVIEW 0x00040000
+#define DDCAPS_VBI 0x00080000
+#define DDCAPS_ZBLTS 0x00100000
+#define DDCAPS_ZOVERLAYS 0x00200000
+#define DDCAPS_COLORKEY 0x00400000
+#define DDCAPS_ALPHA 0x00800000
+#define DDCAPS_COLORKEYHWASSIST 0x01000000
+#define DDCAPS_NOHARDWARE 0x02000000
+#define DDCAPS_BLTCOLORFILL 0x04000000
+#define DDCAPS_BANKSWITCHED 0x08000000
+#define DDCAPS_BLTDEPTHFILL 0x10000000
+#define DDCAPS_CANCLIP 0x20000000
+#define DDCAPS_CANCLIPSTRETCHED 0x40000000
+#define DDCAPS_CANBLTSYSMEM 0x80000000
+
+/* DDCAPS.dwCaps2 */
+#define DDCAPS2_CERTIFIED 0x00000001
+#define DDCAPS2_NO2DDURING3DSCENE 0x00000002
+#define DDCAPS2_VIDEOPORT 0x00000004
+#define DDCAPS2_AUTOFLIPOVERLAY 0x00000008
+#define DDCAPS2_CANBOBINTERLEAVED 0x00000010
+#define DDCAPS2_CANBOBNONINTERLEAVED 0x00000020
+#define DDCAPS2_COLORCONTROLOVERLAY 0x00000040
+#define DDCAPS2_COLORCONTROLPRIMARY 0x00000080
+#define DDCAPS2_CANDROPZ16BIT 0x00000100
+#define DDCAPS2_NONLOCALVIDMEM 0x00000200
+#define DDCAPS2_NONLOCALVIDMEMCAPS 0x00000400
+#define DDCAPS2_NOPAGELOCKREQUIRED 0x00000800
+#define DDCAPS2_WIDESURFACES 0x00001000
+#define DDCAPS2_CANFLIPODDEVEN 0x00002000
+#define DDCAPS2_CANBOBHARDWARE 0x00004000
+#define DDCAPS2_COPYFOURCC 0x00008000
+#define DDCAPS2_PRIMARYGAMMA 0x00020000
+#define DDCAPS2_CANRENDERWINDOWED 0x00080000
+#define DDCAPS2_CANCALIBRATEGAMMA 0x00100000
+#define DDCAPS2_FLIPINTERVAL 0x00200000
+#define DDCAPS2_FLIPNOVSYNC 0x00400000
+#define DDCAPS2_CANMANAGETEXTURE 0x00800000
+#define DDCAPS2_TEXMANINNONLOCALVIDMEM 0x01000000
+#define DDCAPS2_STEREO 0x02000000
+#define DDCAPS2_SYSTONONLOCAL_AS_SYSTOLOCAL 0x04000000
+
+
+/* Set/Get Colour Key Flags */
+#define DDCKEY_COLORSPACE 0x00000001 /* Struct is single colour space */
+#define DDCKEY_DESTBLT 0x00000002 /* To be used as dest for blt */
+#define DDCKEY_DESTOVERLAY 0x00000004 /* To be used as dest for CK overlays */
+#define DDCKEY_SRCBLT 0x00000008 /* To be used as src for blt */
+#define DDCKEY_SRCOVERLAY 0x00000010 /* To be used as src for CK overlays */
+
+typedef struct _DDCOLORKEY
+{
+ DWORD dwColorSpaceLowValue;/* low boundary of color space that is to
+ * be treated as Color Key, inclusive
+ */
+ DWORD dwColorSpaceHighValue;/* high boundary of color space that is
+ * to be treated as Color Key, inclusive
+ */
+} DDCOLORKEY,*LPDDCOLORKEY;
+
+/* ddCKEYCAPS bits */
+#define DDCKEYCAPS_DESTBLT 0x00000001
+#define DDCKEYCAPS_DESTBLTCLRSPACE 0x00000002
+#define DDCKEYCAPS_DESTBLTCLRSPACEYUV 0x00000004
+#define DDCKEYCAPS_DESTBLTYUV 0x00000008
+#define DDCKEYCAPS_DESTOVERLAY 0x00000010
+#define DDCKEYCAPS_DESTOVERLAYCLRSPACE 0x00000020
+#define DDCKEYCAPS_DESTOVERLAYCLRSPACEYUV 0x00000040
+#define DDCKEYCAPS_DESTOVERLAYONEACTIVE 0x00000080
+#define DDCKEYCAPS_DESTOVERLAYYUV 0x00000100
+#define DDCKEYCAPS_SRCBLT 0x00000200
+#define DDCKEYCAPS_SRCBLTCLRSPACE 0x00000400
+#define DDCKEYCAPS_SRCBLTCLRSPACEYUV 0x00000800
+#define DDCKEYCAPS_SRCBLTYUV 0x00001000
+#define DDCKEYCAPS_SRCOVERLAY 0x00002000
+#define DDCKEYCAPS_SRCOVERLAYCLRSPACE 0x00004000
+#define DDCKEYCAPS_SRCOVERLAYCLRSPACEYUV 0x00008000
+#define DDCKEYCAPS_SRCOVERLAYONEACTIVE 0x00010000
+#define DDCKEYCAPS_SRCOVERLAYYUV 0x00020000
+#define DDCKEYCAPS_NOCOSTOVERLAY 0x00040000
+
+typedef struct _DDPIXELFORMAT {
+ DWORD dwSize; /* 0: size of structure */
+ DWORD dwFlags; /* 4: pixel format flags */
+ DWORD dwFourCC; /* 8: (FOURCC code) */
+ union {
+ DWORD dwRGBBitCount; /* C: how many bits per pixel */
+ DWORD dwYUVBitCount; /* C: how many bits per pixel */
+ DWORD dwZBufferBitDepth; /* C: how many bits for z buffers */
+ DWORD dwAlphaBitDepth; /* C: how many bits for alpha channels*/
+ DWORD dwLuminanceBitCount;
+ DWORD dwBumpBitCount;
+ } DUMMYUNIONNAME1;
+ union {
+ DWORD dwRBitMask; /* 10: mask for red bit*/
+ DWORD dwYBitMask; /* 10: mask for Y bits*/
+ DWORD dwStencilBitDepth;
+ DWORD dwLuminanceBitMask;
+ DWORD dwBumpDuBitMask;
+ } DUMMYUNIONNAME2;
+ union {
+ DWORD dwGBitMask; /* 14: mask for green bits*/
+ DWORD dwUBitMask; /* 14: mask for U bits*/
+ DWORD dwZBitMask;
+ DWORD dwBumpDvBitMask;
+ } DUMMYUNIONNAME3;
+ union {
+ DWORD dwBBitMask; /* 18: mask for blue bits*/
+ DWORD dwVBitMask; /* 18: mask for V bits*/
+ DWORD dwStencilBitMask;
+ DWORD dwBumpLuminanceBitMask;
+ } DUMMYUNIONNAME4;
+ union {
+ DWORD dwRGBAlphaBitMask; /* 1C: mask for alpha channel */
+ DWORD dwYUVAlphaBitMask; /* 1C: mask for alpha channel */
+ DWORD dwLuminanceAlphaBitMask;
+ DWORD dwRGBZBitMask; /* 1C: mask for Z channel */
+ DWORD dwYUVZBitMask; /* 1C: mask for Z channel */
+ } DUMMYUNIONNAME5;
+ /* 20: next structure */
+} DDPIXELFORMAT,*LPDDPIXELFORMAT;
+
+#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
+ ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
+ ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ))
+
+/* DDCAPS.dwFXCaps */
+#define DDFXCAPS_BLTALPHA 0x00000001
+#define DDFXCAPS_OVERLAYALPHA 0x00000004
+#define DDFXCAPS_BLTARITHSTRETCHYN 0x00000010
+#define DDFXCAPS_BLTARITHSTRETCHY 0x00000020
+#define DDFXCAPS_BLTMIRRORLEFTRIGHT 0x00000040
+#define DDFXCAPS_BLTMIRRORUPDOWN 0x00000080
+#define DDFXCAPS_BLTROTATION 0x00000100
+#define DDFXCAPS_BLTROTATION90 0x00000200
+#define DDFXCAPS_BLTSHRINKX 0x00000400
+#define DDFXCAPS_BLTSHRINKXN 0x00000800
+#define DDFXCAPS_BLTSHRINKY 0x00001000
+#define DDFXCAPS_BLTSHRINKYN 0x00002000
+#define DDFXCAPS_BLTSTRETCHX 0x00004000
+#define DDFXCAPS_BLTSTRETCHXN 0x00008000
+#define DDFXCAPS_BLTSTRETCHY 0x00010000
+#define DDFXCAPS_BLTSTRETCHYN 0x00020000
+#define DDFXCAPS_OVERLAYARITHSTRETCHY 0x00040000
+#define DDFXCAPS_OVERLAYARITHSTRETCHYN 0x00000008
+#define DDFXCAPS_OVERLAYSHRINKX 0x00080000
+#define DDFXCAPS_OVERLAYSHRINKXN 0x00100000
+#define DDFXCAPS_OVERLAYSHRINKY 0x00200000
+#define DDFXCAPS_OVERLAYSHRINKYN 0x00400000
+#define DDFXCAPS_OVERLAYSTRETCHX 0x00800000
+#define DDFXCAPS_OVERLAYSTRETCHXN 0x01000000
+#define DDFXCAPS_OVERLAYSTRETCHY 0x02000000
+#define DDFXCAPS_OVERLAYSTRETCHYN 0x04000000
+#define DDFXCAPS_OVERLAYMIRRORLEFTRIGHT 0x08000000
+#define DDFXCAPS_OVERLAYMIRRORUPDOWN 0x10000000
+
+#define DDFXCAPS_OVERLAYFILTER DDFXCAPS_OVERLAYARITHSTRETCHY
+
+/* DDCAPS.dwFXAlphaCaps */
+#define DDFXALPHACAPS_BLTALPHAEDGEBLEND 0x00000001
+#define DDFXALPHACAPS_BLTALPHAPIXELS 0x00000002
+#define DDFXALPHACAPS_BLTALPHAPIXELSNEG 0x00000004
+#define DDFXALPHACAPS_BLTALPHASURFACES 0x00000008
+#define DDFXALPHACAPS_BLTALPHASURFACESNEG 0x00000010
+#define DDFXALPHACAPS_OVERLAYALPHAEDGEBLEND 0x00000020
+#define DDFXALPHACAPS_OVERLAYALPHAPIXELS 0x00000040
+#define DDFXALPHACAPS_OVERLAYALPHAPIXELSNEG 0x00000080
+#define DDFXALPHACAPS_OVERLAYALPHASURFACES 0x00000100
+#define DDFXALPHACAPS_OVERLAYALPHASURFACESNEG 0x00000200
+
+/* DDCAPS.dwPalCaps */
+#define DDPCAPS_4BIT 0x00000001
+#define DDPCAPS_8BITENTRIES 0x00000002
+#define DDPCAPS_8BIT 0x00000004
+#define DDPCAPS_INITIALIZE 0x00000008
+#define DDPCAPS_PRIMARYSURFACE 0x00000010
+#define DDPCAPS_PRIMARYSURFACELEFT 0x00000020
+#define DDPCAPS_ALLOW256 0x00000040
+#define DDPCAPS_VSYNC 0x00000080
+#define DDPCAPS_1BIT 0x00000100
+#define DDPCAPS_2BIT 0x00000200
+#define DDPCAPS_ALPHA 0x00000400
+
+/* DDCAPS.dwSVCaps */
+/* the first 4 of these are now obsolete */
+#if DIRECTDRAW_VERSION >= 0x700 /* FIXME: I'm not sure when this switch occurred */
+#define DDSVCAPS_RESERVED1 0x00000001
+#define DDSVCAPS_RESERVED2 0x00000002
+#define DDSVCAPS_RESERVED3 0x00000004
+#define DDSVCAPS_RESERVED4 0x00000008
+#else
+#define DDSVCAPS_ENIGMA 0x00000001
+#define DDSVCAPS_FLICKER 0x00000002
+#define DDSVCAPS_REDBLUE 0x00000004
+#define DDSVCAPS_SPLIT 0x00000008
+#endif
+#define DDSVCAPS_STEREOSEQUENTIAL 0x00000010
+
+/* BitDepths */
+#define DDBD_1 0x00004000
+#define DDBD_2 0x00002000
+#define DDBD_4 0x00001000
+#define DDBD_8 0x00000800
+#define DDBD_16 0x00000400
+#define DDBD_24 0x00000200
+#define DDBD_32 0x00000100
+
+/* DDOVERLAYFX.dwDDFX */
+#define DDOVERFX_ARITHSTRETCHY 0x00000001
+#define DDOVERFX_MIRRORLEFTRIGHT 0x00000002
+#define DDOVERFX_MIRRORUPDOWN 0x00000004
+
+/* UpdateOverlay flags */
+#define DDOVER_ALPHADEST 0x00000001
+#define DDOVER_ALPHADESTCONSTOVERRIDE 0x00000002
+#define DDOVER_ALPHADESTNEG 0x00000004
+#define DDOVER_ALPHADESTSURFACEOVERRIDE 0x00000008
+#define DDOVER_ALPHAEDGEBLEND 0x00000010
+#define DDOVER_ALPHASRC 0x00000020
+#define DDOVER_ALPHASRCCONSTOVERRIDE 0x00000040
+#define DDOVER_ALPHASRCNEG 0x00000080
+#define DDOVER_ALPHASRCSURFACEOVERRIDE 0x00000100
+#define DDOVER_HIDE 0x00000200
+#define DDOVER_KEYDEST 0x00000400
+#define DDOVER_KEYDESTOVERRIDE 0x00000800
+#define DDOVER_KEYSRC 0x00001000
+#define DDOVER_KEYSRCOVERRIDE 0x00002000
+#define DDOVER_SHOW 0x00004000
+#define DDOVER_ADDDIRTYRECT 0x00008000
+#define DDOVER_REFRESHDIRTYRECTS 0x00010000
+#define DDOVER_REFRESHALL 0x00020000
+#define DDOVER_DDFX 0x00080000
+#define DDOVER_AUTOFLIP 0x00100000
+#define DDOVER_BOB 0x00200000
+#define DDOVER_OVERRIDEBOBWEAVE 0x00400000
+#define DDOVER_INTERLEAVED 0x00800000
+
+/* DDCOLORKEY.dwFlags */
+#define DDPF_ALPHAPIXELS 0x00000001
+#define DDPF_ALPHA 0x00000002
+#define DDPF_FOURCC 0x00000004
+#define DDPF_PALETTEINDEXED4 0x00000008
+#define DDPF_PALETTEINDEXEDTO8 0x00000010
+#define DDPF_PALETTEINDEXED8 0x00000020
+#define DDPF_RGB 0x00000040
+#define DDPF_COMPRESSED 0x00000080
+#define DDPF_RGBTOYUV 0x00000100
+#define DDPF_YUV 0x00000200
+#define DDPF_ZBUFFER 0x00000400
+#define DDPF_PALETTEINDEXED1 0x00000800
+#define DDPF_PALETTEINDEXED2 0x00001000
+#define DDPF_ZPIXELS 0x00002000
+#define DDPF_STENCILBUFFER 0x00004000
+#define DDPF_ALPHAPREMULT 0x00008000
+#define DDPF_LUMINANCE 0x00020000
+#define DDPF_BUMPLUMINANCE 0x00040000
+#define DDPF_BUMPDUDV 0x00080000
+
+/* SetCooperativeLevel dwFlags */
+#define DDSCL_FULLSCREEN 0x00000001
+#define DDSCL_ALLOWREBOOT 0x00000002
+#define DDSCL_NOWINDOWCHANGES 0x00000004
+#define DDSCL_NORMAL 0x00000008
+#define DDSCL_EXCLUSIVE 0x00000010
+#define DDSCL_ALLOWMODEX 0x00000040
+#define DDSCL_SETFOCUSWINDOW 0x00000080
+#define DDSCL_SETDEVICEWINDOW 0x00000100
+#define DDSCL_CREATEDEVICEWINDOW 0x00000200
+#define DDSCL_MULTITHREADED 0x00000400
+#define DDSCL_FPUSETUP 0x00000800
+#define DDSCL_FPUPRESERVE 0x00001000
+
+
+/* DDSURFACEDESC.dwFlags */
+#define DDSD_CAPS 0x00000001
+#define DDSD_HEIGHT 0x00000002
+#define DDSD_WIDTH 0x00000004
+#define DDSD_PITCH 0x00000008
+#define DDSD_BACKBUFFERCOUNT 0x00000020
+#define DDSD_ZBUFFERBITDEPTH 0x00000040
+#define DDSD_ALPHABITDEPTH 0x00000080
+#define DDSD_LPSURFACE 0x00000800
+#define DDSD_PIXELFORMAT 0x00001000
+#define DDSD_CKDESTOVERLAY 0x00002000
+#define DDSD_CKDESTBLT 0x00004000
+#define DDSD_CKSRCOVERLAY 0x00008000
+#define DDSD_CKSRCBLT 0x00010000
+#define DDSD_MIPMAPCOUNT 0x00020000
+#define DDSD_REFRESHRATE 0x00040000
+#define DDSD_LINEARSIZE 0x00080000
+#define DDSD_TEXTURESTAGE 0x00100000
+#define DDSD_FVF 0x00200000
+#define DDSD_SRCVBHANDLE 0x00400000
+#define DDSD_ALL 0x007ff9ee
+
+/* EnumSurfaces flags */
+#define DDENUMSURFACES_ALL 0x00000001
+#define DDENUMSURFACES_MATCH 0x00000002
+#define DDENUMSURFACES_NOMATCH 0x00000004
+#define DDENUMSURFACES_CANBECREATED 0x00000008
+#define DDENUMSURFACES_DOESEXIST 0x00000010
+
+/* SetDisplayMode flags */
+#define DDSDM_STANDARDVGAMODE 0x00000001
+
+/* EnumDisplayModes flags */
+#define DDEDM_REFRESHRATES 0x00000001
+#define DDEDM_STANDARDVGAMODES 0x00000002
+
+/* WaitForVerticalDisplay flags */
+
+#define DDWAITVB_BLOCKBEGIN 0x00000001
+#define DDWAITVB_BLOCKBEGINEVENT 0x00000002
+#define DDWAITVB_BLOCKEND 0x00000004
+
+typedef struct _DDSURFACEDESC
+{
+ DWORD dwSize; /* 0: size of the DDSURFACEDESC structure*/
+ DWORD dwFlags; /* 4: determines what fields are valid*/
+ DWORD dwHeight; /* 8: height of surface to be created*/
+ DWORD dwWidth; /* C: width of input surface*/
+ union {
+ LONG lPitch; /* 10: distance to start of next line (return value only)*/
+ DWORD dwLinearSize;
+ } DUMMYUNIONNAME1;
+ DWORD dwBackBufferCount;/* 14: number of back buffers requested*/
+ union {
+ DWORD dwMipMapCount;/* 18:number of mip-map levels requested*/
+ DWORD dwZBufferBitDepth;/*18: depth of Z buffer requested*/
+ DWORD dwRefreshRate;/* 18:refresh rate (used when display mode is described)*/
+ } DUMMYUNIONNAME2;
+ DWORD dwAlphaBitDepth;/* 1C:depth of alpha buffer requested*/
+ DWORD dwReserved; /* 20:reserved*/
+ LPVOID lpSurface; /* 24:pointer to the associated surface memory*/
+ DDCOLORKEY ddckCKDestOverlay;/* 28: CK for dest overlay use*/
+ DDCOLORKEY ddckCKDestBlt; /* 30: CK for destination blt use*/
+ DDCOLORKEY ddckCKSrcOverlay;/* 38: CK for source overlay use*/
+ DDCOLORKEY ddckCKSrcBlt; /* 40: CK for source blt use*/
+ DDPIXELFORMAT ddpfPixelFormat;/* 48: pixel format description of the surface*/
+ DDSCAPS ddsCaps; /* 68: direct draw surface caps */
+} DDSURFACEDESC,*LPDDSURFACEDESC;
+
+typedef struct _DDSURFACEDESC2
+{
+ DWORD dwSize; /* 0: size of the DDSURFACEDESC2 structure*/
+ DWORD dwFlags; /* 4: determines what fields are valid*/
+ DWORD dwHeight; /* 8: height of surface to be created*/
+ DWORD dwWidth; /* C: width of input surface*/
+ union {
+ LONG lPitch; /*10: distance to start of next line (return value only)*/
+ DWORD dwLinearSize; /*10: formless late-allocated optimized surface size */
+ } DUMMYUNIONNAME1;
+ DWORD dwBackBufferCount;/* 14: number of back buffers requested*/
+ union {
+ DWORD dwMipMapCount;/* 18:number of mip-map levels requested*/
+ DWORD dwRefreshRate;/* 18:refresh rate (used when display mode is described)*/
+ DWORD dwSrcVBHandle;/* 18:source used in VB::Optimize */
+ } DUMMYUNIONNAME2;
+ DWORD dwAlphaBitDepth;/* 1C:depth of alpha buffer requested*/
+ DWORD dwReserved; /* 20:reserved*/
+ LPVOID lpSurface; /* 24:pointer to the associated surface memory*/
+ union {
+ DDCOLORKEY ddckCKDestOverlay; /* 28: CK for dest overlay use*/
+ DWORD dwEmptyFaceColor; /* 28: color for empty cubemap faces */
+ } DUMMYUNIONNAME3;
+ DDCOLORKEY ddckCKDestBlt; /* 30: CK for destination blt use*/
+ DDCOLORKEY ddckCKSrcOverlay;/* 38: CK for source overlay use*/
+ DDCOLORKEY ddckCKSrcBlt; /* 40: CK for source blt use*/
+
+ union {
+ DDPIXELFORMAT ddpfPixelFormat;/* 48: pixel format description of the surface*/
+ DWORD dwFVF; /* 48: vertex format description of vertex buffers */
+ } DUMMYUNIONNAME4;
+ DDSCAPS2 ddsCaps; /* 68: DDraw surface caps */
+ DWORD dwTextureStage; /* 78: stage in multitexture cascade */
+} DDSURFACEDESC2,*LPDDSURFACEDESC2;
+
+/* DDCOLORCONTROL.dwFlags */
+#define DDCOLOR_BRIGHTNESS 0x00000001
+#define DDCOLOR_CONTRAST 0x00000002
+#define DDCOLOR_HUE 0x00000004
+#define DDCOLOR_SATURATION 0x00000008
+#define DDCOLOR_SHARPNESS 0x00000010
+#define DDCOLOR_GAMMA 0x00000020
+#define DDCOLOR_COLORENABLE 0x00000040
+
+typedef struct {
+ DWORD dwSize;
+ DWORD dwFlags;
+ LONG lBrightness;
+ LONG lContrast;
+ LONG lHue;
+ LONG lSaturation;
+ LONG lSharpness;
+ LONG lGamma;
+ LONG lColorEnable;
+ DWORD dwReserved1;
+} DDCOLORCONTROL,*LPDDCOLORCONTROL;
+
+typedef struct {
+ WORD red[256];
+ WORD green[256];
+ WORD blue[256];
+} DDGAMMARAMP,*LPDDGAMMARAMP;
+
+typedef BOOL (CALLBACK *LPDDENUMCALLBACKA)(GUID *, LPSTR, LPSTR, LPVOID);
+typedef BOOL (CALLBACK *LPDDENUMCALLBACKW)(GUID *, LPWSTR, LPWSTR, LPVOID);
+
+typedef HRESULT (CALLBACK *LPDDENUMMODESCALLBACK)(LPDDSURFACEDESC, LPVOID);
+typedef HRESULT (CALLBACK *LPDDENUMMODESCALLBACK2)(LPDDSURFACEDESC2, LPVOID);
+typedef HRESULT (CALLBACK *LPDDENUMSURFACESCALLBACK)(LPDIRECTDRAWSURFACE, LPDDSURFACEDESC, LPVOID);
+typedef HRESULT (CALLBACK *LPDDENUMSURFACESCALLBACK2)(LPDIRECTDRAWSURFACE4, LPDDSURFACEDESC2, LPVOID);
+typedef HRESULT (CALLBACK *LPDDENUMSURFACESCALLBACK7)(LPDIRECTDRAWSURFACE7, LPDDSURFACEDESC2, LPVOID);
+
+typedef BOOL (CALLBACK *LPDDENUMCALLBACKEXA)(GUID *, LPSTR, LPSTR, LPVOID, HMONITOR);
+typedef BOOL (CALLBACK *LPDDENUMCALLBACKEXW)(GUID *, LPWSTR, LPWSTR, LPVOID, HMONITOR);
+
+HRESULT WINAPI DirectDrawEnumerateA(LPDDENUMCALLBACKA,LPVOID);
+HRESULT WINAPI DirectDrawEnumerateW(LPDDENUMCALLBACKW,LPVOID);
+#define DirectDrawEnumerate WINELIB_NAME_AW(DirectDrawEnumerate)
+
+HRESULT WINAPI DirectDrawEnumerateExA( LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags);
+HRESULT WINAPI DirectDrawEnumerateExW( LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags);
+#define DirectDrawEnumerateEx WINELIB_NAME_AW(DirectDrawEnumerateEx)
+
+typedef HRESULT (WINAPI * LPDIRECTDRAWENUMERATEEXA)( LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags);
+typedef HRESULT (WINAPI * LPDIRECTDRAWENUMERATEEXW)( LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags);
+
+/* flags for DirectDrawEnumerateEx */
+#define DDENUM_ATTACHEDSECONDARYDEVICES 0x00000001
+#define DDENUM_DETACHEDSECONDARYDEVICES 0x00000002
+#define DDENUM_NONDISPLAYDEVICES 0x00000004
+
+/* flags for DirectDrawCreate or IDirectDraw::Initialize */
+#define DDCREATE_HARDWAREONLY 1L
+#define DDCREATE_EMULATIONONLY 2L
+
+typedef struct _DDBLTFX
+{
+ DWORD dwSize; /* size of structure */
+ DWORD dwDDFX; /* FX operations */
+ DWORD dwROP; /* Win32 raster operations */
+ DWORD dwDDROP; /* Raster operations new for DirectDraw */
+ DWORD dwRotationAngle; /* Rotation angle for blt */
+ DWORD dwZBufferOpCode; /* ZBuffer compares */
+ DWORD dwZBufferLow; /* Low limit of Z buffer */
+ DWORD dwZBufferHigh; /* High limit of Z buffer */
+ DWORD dwZBufferBaseDest; /* Destination base value */
+ DWORD dwZDestConstBitDepth; /* Bit depth used to specify Z constant for destination */
+ union
+ {
+ DWORD dwZDestConst; /* Constant to use as Z buffer for dest */
+ LPDIRECTDRAWSURFACE lpDDSZBufferDest; /* Surface to use as Z buffer for dest */
+ } DUMMYUNIONNAME1;
+ DWORD dwZSrcConstBitDepth; /* Bit depth used to specify Z constant for source */
+ union
+ {
+ DWORD dwZSrcConst; /* Constant to use as Z buffer for src */
+ LPDIRECTDRAWSURFACE lpDDSZBufferSrc; /* Surface to use as Z buffer for src */
+ } DUMMYUNIONNAME2;
+ DWORD dwAlphaEdgeBlendBitDepth; /* Bit depth used to specify constant for alpha edge blend */
+ DWORD dwAlphaEdgeBlend; /* Alpha for edge blending */
+ DWORD dwReserved;
+ DWORD dwAlphaDestConstBitDepth; /* Bit depth used to specify alpha constant for destination */
+ union
+ {
+ DWORD dwAlphaDestConst; /* Constant to use as Alpha Channel */
+ LPDIRECTDRAWSURFACE lpDDSAlphaDest; /* Surface to use as Alpha Channel */
+ } DUMMYUNIONNAME3;
+ DWORD dwAlphaSrcConstBitDepth; /* Bit depth used to specify alpha constant for source */
+ union
+ {
+ DWORD dwAlphaSrcConst; /* Constant to use as Alpha Channel */
+ LPDIRECTDRAWSURFACE lpDDSAlphaSrc; /* Surface to use as Alpha Channel */
+ } DUMMYUNIONNAME4;
+ union
+ {
+ DWORD dwFillColor; /* color in RGB or Palettized */
+ DWORD dwFillDepth; /* depth value for z-buffer */
+ DWORD dwFillPixel; /* pixel val for RGBA or RGBZ */
+ LPDIRECTDRAWSURFACE lpDDSPattern; /* Surface to use as pattern */
+ } DUMMYUNIONNAME5;
+ DDCOLORKEY ddckDestColorkey; /* DestColorkey override */
+ DDCOLORKEY ddckSrcColorkey; /* SrcColorkey override */
+} DDBLTFX,*LPDDBLTFX;
+
+/* dwDDFX */
+/* arithmetic stretching along y axis */
+#define DDBLTFX_ARITHSTRETCHY 0x00000001
+/* mirror on y axis */
+#define DDBLTFX_MIRRORLEFTRIGHT 0x00000002
+/* mirror on x axis */
+#define DDBLTFX_MIRRORUPDOWN 0x00000004
+/* do not tear */
+#define DDBLTFX_NOTEARING 0x00000008
+/* 180 degrees clockwise rotation */
+#define DDBLTFX_ROTATE180 0x00000010
+/* 270 degrees clockwise rotation */
+#define DDBLTFX_ROTATE270 0x00000020
+/* 90 degrees clockwise rotation */
+#define DDBLTFX_ROTATE90 0x00000040
+/* dwZBufferLow and dwZBufferHigh specify limits to the copied Z values */
+#define DDBLTFX_ZBUFFERRANGE 0x00000080
+/* add dwZBufferBaseDest to every source z value before compare */
+#define DDBLTFX_ZBUFFERBASEDEST 0x00000100
+
+typedef struct _DDOVERLAYFX
+{
+ DWORD dwSize; /* size of structure */
+ DWORD dwAlphaEdgeBlendBitDepth; /* Bit depth used to specify constant for alpha edge blend */
+ DWORD dwAlphaEdgeBlend; /* Constant to use as alpha for edge blend */
+ DWORD dwReserved;
+ DWORD dwAlphaDestConstBitDepth; /* Bit depth used to specify alpha constant for destination */
+ union
+ {
+ DWORD dwAlphaDestConst; /* Constant to use as alpha channel for dest */
+ LPDIRECTDRAWSURFACE lpDDSAlphaDest; /* Surface to use as alpha channel for dest */
+ } DUMMYUNIONNAME1;
+ DWORD dwAlphaSrcConstBitDepth; /* Bit depth used to specify alpha constant for source */
+ union
+ {
+ DWORD dwAlphaSrcConst; /* Constant to use as alpha channel for src */
+ LPDIRECTDRAWSURFACE lpDDSAlphaSrc; /* Surface to use as alpha channel for src */
+ } DUMMYUNIONNAME2;
+ DDCOLORKEY dckDestColorkey; /* DestColorkey override */
+ DDCOLORKEY dckSrcColorkey; /* DestColorkey override */
+ DWORD dwDDFX; /* Overlay FX */
+ DWORD dwFlags; /* flags */
+} DDOVERLAYFX,*LPDDOVERLAYFX;
+
+typedef struct _DDBLTBATCH
+{
+ LPRECT lprDest;
+ LPDIRECTDRAWSURFACE lpDDSSrc;
+ LPRECT lprSrc;
+ DWORD dwFlags;
+ LPDDBLTFX lpDDBltFx;
+} DDBLTBATCH,*LPDDBLTBATCH;
+
+#define MAX_DDDEVICEID_STRING 512
+
+#define DDGDI_GETHOSTIDENTIFIER 1
+
+typedef struct tagDDDEVICEIDENTIFIER {
+ char szDriver[MAX_DDDEVICEID_STRING];
+ char szDescription[MAX_DDDEVICEID_STRING];
+ LARGE_INTEGER liDriverVersion;
+ DWORD dwVendorId;
+ DWORD dwDeviceId;
+ DWORD dwSubSysId;
+ DWORD dwRevision;
+ GUID guidDeviceIdentifier;
+} DDDEVICEIDENTIFIER, * LPDDDEVICEIDENTIFIER;
+
+typedef struct tagDDDEVICEIDENTIFIER2 {
+ char szDriver[MAX_DDDEVICEID_STRING]; /* user readable driver name */
+ char szDescription[MAX_DDDEVICEID_STRING]; /* user readable description */
+ LARGE_INTEGER liDriverVersion; /* driver version */
+ DWORD dwVendorId; /* vendor ID, zero if unknown */
+ DWORD dwDeviceId; /* chipset ID, zero if unknown */
+ DWORD dwSubSysId; /* board ID, zero if unknown */
+ DWORD dwRevision; /* chipset version, zero if unknown */
+ GUID guidDeviceIdentifier; /* unique ID for this driver/chipset combination */
+ DWORD dwWHQLLevel; /* Windows Hardware Quality Lab certification level */
+} DDDEVICEIDENTIFIER2, * LPDDDEVICEIDENTIFIER2;
+
+/*****************************************************************************
+ * IDirectDrawPalette interface
+ */
+#define INTERFACE IDirectDrawPalette
+DECLARE_INTERFACE_(IDirectDrawPalette,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectDrawPalette methods ***/
+ STDMETHOD(GetCaps)(THIS_ LPDWORD lpdwCaps) PURE;
+ STDMETHOD(GetEntries)(THIS_ DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries) PURE;
+ STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, DWORD dwFlags, LPPALETTEENTRY lpDDColorTable) PURE;
+ STDMETHOD(SetEntries)(THIS_ DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDrawPalette_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDrawPalette_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectDrawPalette_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectDrawPalette methods ***/
+#define IDirectDrawPalette_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a)
+#define IDirectDrawPalette_GetEntries(p,a,b,c,d) (p)->lpVtbl->GetEntries(p,a,b,c,d)
+#define IDirectDrawPalette_Initialize(p,a,b,c) (p)->lpVtbl->Initialize(p,a,b,c)
+#define IDirectDrawPalette_SetEntries(p,a,b,c,d) (p)->lpVtbl->SetEntries(p,a,b,c,d)
+#else
+/*** IUnknown methods ***/
+#define IDirectDrawPalette_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDrawPalette_AddRef(p) (p)->AddRef()
+#define IDirectDrawPalette_Release(p) (p)->Release()
+/*** IDirectDrawPalette methods ***/
+#define IDirectDrawPalette_GetCaps(p,a) (p)->GetCaps(a)
+#define IDirectDrawPalette_GetEntries(p,a,b,c,d) (p)->GetEntries(a,b,c,d)
+#define IDirectDrawPalette_Initialize(p,a,b,c) (p)->Initialize(a,b,c)
+#define IDirectDrawPalette_SetEntries(p,a,b,c,d) (p)->SetEntries(a,b,c,d)
+#endif
+
+
+/*****************************************************************************
+ * IDirectDrawClipper interface
+ */
+#define INTERFACE IDirectDrawClipper
+DECLARE_INTERFACE_(IDirectDrawClipper,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectDrawClipper methods ***/
+ STDMETHOD(GetClipList)(THIS_ LPRECT lpRect, LPRGNDATA lpClipList, LPDWORD lpdwSize) PURE;
+ STDMETHOD(GetHWnd)(THIS_ HWND *lphWnd) PURE;
+ STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, DWORD dwFlags) PURE;
+ STDMETHOD(IsClipListChanged)(THIS_ BOOL *lpbChanged) PURE;
+ STDMETHOD(SetClipList)(THIS_ LPRGNDATA lpClipList, DWORD dwFlags) PURE;
+ STDMETHOD(SetHWnd)(THIS_ DWORD dwFlags, HWND hWnd) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDrawClipper_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDrawClipper_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectDrawClipper_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectDrawClipper methods ***/
+#define IDirectDrawClipper_GetClipList(p,a,b,c) (p)->lpVtbl->GetClipList(p,a,b,c)
+#define IDirectDrawClipper_GetHWnd(p,a) (p)->lpVtbl->GetHWnd(p,a)
+#define IDirectDrawClipper_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b)
+#define IDirectDrawClipper_IsClipListChanged(p,a) (p)->lpVtbl->IsClipListChanged(p,a)
+#define IDirectDrawClipper_SetClipList(p,a,b) (p)->lpVtbl->SetClipList(p,a,b)
+#define IDirectDrawClipper_SetHWnd(p,a,b) (p)->lpVtbl->SetHWnd(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirectDrawClipper_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDrawClipper_AddRef(p) (p)->AddRef()
+#define IDirectDrawClipper_Release(p) (p)->Release()
+/*** IDirectDrawClipper methods ***/
+#define IDirectDrawClipper_GetClipList(p,a,b,c) (p)->GetClipList(a,b,c)
+#define IDirectDrawClipper_GetHWnd(p,a) (p)->GetHWnd(a)
+#define IDirectDrawClipper_Initialize(p,a,b) (p)->Initialize(a,b)
+#define IDirectDrawClipper_IsClipListChanged(p,a) (p)->IsClipListChanged(a)
+#define IDirectDrawClipper_SetClipList(p,a,b) (p)->SetClipList(a,b)
+#define IDirectDrawClipper_SetHWnd(p,a,b) (p)->SetHWnd(a,b)
+#endif
+
+
+/*****************************************************************************
+ * IDirectDraw interface
+ */
+#define INTERFACE IDirectDraw
+DECLARE_INTERFACE_(IDirectDraw,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectDraw methods ***/
+ STDMETHOD(Compact)(THIS) PURE;
+ STDMETHOD(CreateClipper)(THIS_ DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, IUnknown *pUnkOuter) PURE;
+ STDMETHOD(CreatePalette)(THIS_ DWORD dwFlags, LPPALETTEENTRY lpColorTable, LPDIRECTDRAWPALETTE *lplpDDPalette, IUnknown *pUnkOuter) PURE;
+ STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE *lplpDDSurface, IUnknown *pUnkOuter) PURE;
+ STDMETHOD(DuplicateSurface)(THIS_ LPDIRECTDRAWSURFACE lpDDSurface, LPDIRECTDRAWSURFACE *lplpDupDDSurface) PURE;
+ STDMETHOD(EnumDisplayModes)(THIS_ DWORD dwFlags, LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK lpEnumModesCallback) PURE;
+ STDMETHOD(EnumSurfaces)(THIS_ DWORD dwFlags, LPDDSURFACEDESC lpDDSD, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE;
+ STDMETHOD(FlipToGDISurface)(THIS) PURE;
+ STDMETHOD(GetCaps)(THIS_ LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) PURE;
+ STDMETHOD(GetDisplayMode)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc) PURE;
+ STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD lpNumCodes, LPDWORD lpCodes) PURE;
+ STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE *lplpGDIDDSurface) PURE;
+ STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD lpdwFrequency) PURE;
+ STDMETHOD(GetScanLine)(THIS_ LPDWORD lpdwScanLine) PURE;
+ STDMETHOD(GetVerticalBlankStatus)(THIS_ BOOL *lpbIsInVB) PURE;
+ STDMETHOD(Initialize)(THIS_ GUID *lpGUID) PURE;
+ STDMETHOD(RestoreDisplayMode)(THIS) PURE;
+ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hWnd, DWORD dwFlags) PURE;
+ STDMETHOD(SetDisplayMode)(THIS_ DWORD dwWidth, DWORD dwHeight, DWORD dwBPP) PURE;
+ STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD dwFlags, HANDLE hEvent) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDraw_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDraw_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectDraw_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectDraw methods ***/
+#define IDirectDraw_Compact(p) (p)->lpVtbl->Compact(p)
+#define IDirectDraw_CreateClipper(p,a,b,c) (p)->lpVtbl->CreateClipper(p,a,b,c)
+#define IDirectDraw_CreatePalette(p,a,b,c,d) (p)->lpVtbl->CreatePalette(p,a,b,c,d)
+#define IDirectDraw_CreateSurface(p,a,b,c) (p)->lpVtbl->CreateSurface(p,a,b,c)
+#define IDirectDraw_DuplicateSurface(p,a,b) (p)->lpVtbl->DuplicateSurface(p,a,b)
+#define IDirectDraw_EnumDisplayModes(p,a,b,c,d) (p)->lpVtbl->EnumDisplayModes(p,a,b,c,d)
+#define IDirectDraw_EnumSurfaces(p,a,b,c,d) (p)->lpVtbl->EnumSurfaces(p,a,b,c,d)
+#define IDirectDraw_FlipToGDISurface(p) (p)->lpVtbl->FlipToGDISurface(p)
+#define IDirectDraw_GetCaps(p,a,b) (p)->lpVtbl->GetCaps(p,a,b)
+#define IDirectDraw_GetDisplayMode(p,a) (p)->lpVtbl->GetDisplayMode(p,a)
+#define IDirectDraw_GetFourCCCodes(p,a,b) (p)->lpVtbl->GetFourCCCodes(p,a,b)
+#define IDirectDraw_GetGDISurface(p,a) (p)->lpVtbl->GetGDISurface(p,a)
+#define IDirectDraw_GetMonitorFrequency(p,a) (p)->lpVtbl->GetMonitorFrequency(p,a)
+#define IDirectDraw_GetScanLine(p,a) (p)->lpVtbl->GetScanLine(p,a)
+#define IDirectDraw_GetVerticalBlankStatus(p,a) (p)->lpVtbl->GetVerticalBlankStatus(p,a)
+#define IDirectDraw_Initialize(p,a) (p)->lpVtbl->Initialize(p,a)
+#define IDirectDraw_RestoreDisplayMode(p) (p)->lpVtbl->RestoreDisplayMode(p)
+#define IDirectDraw_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b)
+#define IDirectDraw_SetDisplayMode(p,a,b,c) (p)->lpVtbl->SetDisplayMode(p,a,b,c)
+#define IDirectDraw_WaitForVerticalBlank(p,a,b) (p)->lpVtbl->WaitForVerticalBlank(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirectDraw_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDraw_AddRef(p) (p)->AddRef()
+#define IDirectDraw_Release(p) (p)->Release()
+/*** IDirectDraw methods ***/
+#define IDirectDraw_Compact(p) (p)->Compact()
+#define IDirectDraw_CreateClipper(p,a,b,c) (p)->CreateClipper(a,b,c)
+#define IDirectDraw_CreatePalette(p,a,b,c,d) (p)->CreatePalette(a,b,c,d)
+#define IDirectDraw_CreateSurface(p,a,b,c) (p)->CreateSurface(a,b,c)
+#define IDirectDraw_DuplicateSurface(p,a,b) (p)->DuplicateSurface(a,b)
+#define IDirectDraw_EnumDisplayModes(p,a,b,c,d) (p)->EnumDisplayModes(a,b,c,d)
+#define IDirectDraw_EnumSurfaces(p,a,b,c,d) (p)->EnumSurfaces(a,b,c,d)
+#define IDirectDraw_FlipToGDISurface(p) (p)->FlipToGDISurface()
+#define IDirectDraw_GetCaps(p,a,b) (p)->GetCaps(a,b)
+#define IDirectDraw_GetDisplayMode(p,a) (p)->GetDisplayMode(a)
+#define IDirectDraw_GetFourCCCodes(p,a,b) (p)->GetFourCCCodes(a,b)
+#define IDirectDraw_GetGDISurface(p,a) (p)->GetGDISurface(a)
+#define IDirectDraw_GetMonitorFrequency(p,a) (p)->GetMonitorFrequency(a)
+#define IDirectDraw_GetScanLine(p,a) (p)->GetScanLine(a)
+#define IDirectDraw_GetVerticalBlankStatus(p,a) (p)->GetVerticalBlankStatus(a)
+#define IDirectDraw_Initialize(p,a) (p)->Initialize(a)
+#define IDirectDraw_RestoreDisplayMode(p) (p)->RestoreDisplayMode()
+#define IDirectDraw_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b)
+#define IDirectDraw_SetDisplayMode(p,a,b,c) (p)->SetDisplayMode(a,b,c)
+#define IDirectDraw_WaitForVerticalBlank(p,a,b) (p)->WaitForVerticalBlank(a,b)
+#endif
+
+
+/* flags for Lock() */
+#define DDLOCK_SURFACEMEMORYPTR 0x00000000
+#define DDLOCK_WAIT 0x00000001
+#define DDLOCK_EVENT 0x00000002
+#define DDLOCK_READONLY 0x00000010
+#define DDLOCK_WRITEONLY 0x00000020
+#define DDLOCK_NOSYSLOCK 0x00000800
+#define DDLOCK_NOOVERWRITE 0x00001000
+#define DDLOCK_DISCARDCONTENTS 0x00002000
+
+
+/*****************************************************************************
+ * IDirectDraw2 interface
+ */
+/* Note: IDirectDraw2 cannot derive from IDirectDraw because the number of
+ * arguments of SetDisplayMode has changed !
+ */
+#define INTERFACE IDirectDraw2
+DECLARE_INTERFACE_(IDirectDraw2,IUnknown)
+{
+ /*** IUnknown methods ***/
+/*00*/ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+/*04*/ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+/*08*/ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectDraw2 methods ***/
+/*0c*/ STDMETHOD(Compact)(THIS) PURE;
+/*10*/ STDMETHOD(CreateClipper)(THIS_ DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, IUnknown *pUnkOuter) PURE;
+/*14*/ STDMETHOD(CreatePalette)(THIS_ DWORD dwFlags, LPPALETTEENTRY lpColorTable, LPDIRECTDRAWPALETTE *lplpDDPalette, IUnknown *pUnkOuter) PURE;
+/*18*/ STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE *lplpDDSurface, IUnknown *pUnkOuter) PURE;
+/*1c*/ STDMETHOD(DuplicateSurface)(THIS_ LPDIRECTDRAWSURFACE lpDDSurface, LPDIRECTDRAWSURFACE *lplpDupDDSurface) PURE;
+/*20*/ STDMETHOD(EnumDisplayModes)(THIS_ DWORD dwFlags, LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK lpEnumModesCallback) PURE;
+/*24*/ STDMETHOD(EnumSurfaces)(THIS_ DWORD dwFlags, LPDDSURFACEDESC lpDDSD, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE;
+/*28*/ STDMETHOD(FlipToGDISurface)(THIS) PURE;
+/*2c*/ STDMETHOD(GetCaps)(THIS_ LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) PURE;
+/*30*/ STDMETHOD(GetDisplayMode)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc) PURE;
+/*34*/ STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD lpNumCodes, LPDWORD lpCodes) PURE;
+/*38*/ STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE *lplpGDIDDSurface) PURE;
+/*3c*/ STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD lpdwFrequency) PURE;
+/*40*/ STDMETHOD(GetScanLine)(THIS_ LPDWORD lpdwScanLine) PURE;
+/*44*/ STDMETHOD(GetVerticalBlankStatus)(THIS_ BOOL *lpbIsInVB) PURE;
+/*48*/ STDMETHOD(Initialize)(THIS_ GUID *lpGUID) PURE;
+/*4c*/ STDMETHOD(RestoreDisplayMode)(THIS) PURE;
+/*50*/ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hWnd, DWORD dwFlags) PURE;
+/*54*/ STDMETHOD(SetDisplayMode)(THIS_ DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags) PURE;
+/*58*/ STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD dwFlags, HANDLE hEvent) PURE;
+ /* added in v2 */
+/*5c*/ STDMETHOD(GetAvailableVidMem)(THIS_ LPDDSCAPS lpDDCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDraw2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDraw2_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectDraw2_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectDraw methods ***/
+#define IDirectDraw2_Compact(p) (p)->lpVtbl->Compact(p)
+#define IDirectDraw2_CreateClipper(p,a,b,c) (p)->lpVtbl->CreateClipper(p,a,b,c)
+#define IDirectDraw2_CreatePalette(p,a,b,c,d) (p)->lpVtbl->CreatePalette(p,a,b,c,d)
+#define IDirectDraw2_CreateSurface(p,a,b,c) (p)->lpVtbl->CreateSurface(p,a,b,c)
+#define IDirectDraw2_DuplicateSurface(p,a,b) (p)->lpVtbl->DuplicateSurface(p,a,b)
+#define IDirectDraw2_EnumDisplayModes(p,a,b,c,d) (p)->lpVtbl->EnumDisplayModes(p,a,b,c,d)
+#define IDirectDraw2_EnumSurfaces(p,a,b,c,d) (p)->lpVtbl->EnumSurfaces(p,a,b,c,d)
+#define IDirectDraw2_FlipToGDISurface(p) (p)->lpVtbl->FlipToGDISurface(p)
+#define IDirectDraw2_GetCaps(p,a,b) (p)->lpVtbl->GetCaps(p,a,b)
+#define IDirectDraw2_GetDisplayMode(p,a) (p)->lpVtbl->GetDisplayMode(p,a)
+#define IDirectDraw2_GetFourCCCodes(p,a,b) (p)->lpVtbl->GetFourCCCodes(p,a,b)
+#define IDirectDraw2_GetGDISurface(p,a) (p)->lpVtbl->GetGDISurface(p,a)
+#define IDirectDraw2_GetMonitorFrequency(p,a) (p)->lpVtbl->GetMonitorFrequency(p,a)
+#define IDirectDraw2_GetScanLine(p,a) (p)->lpVtbl->GetScanLine(p,a)
+#define IDirectDraw2_GetVerticalBlankStatus(p,a) (p)->lpVtbl->GetVerticalBlankStatus(p,a)
+#define IDirectDraw2_Initialize(p,a) (p)->lpVtbl->Initialize(p,a)
+#define IDirectDraw2_RestoreDisplayMode(p) (p)->lpVtbl->RestoreDisplayMode(p)
+#define IDirectDraw2_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b)
+#define IDirectDraw2_SetDisplayMode(p,a,b,c,d,e) (p)->lpVtbl->SetDisplayMode(p,a,b,c,d,e)
+#define IDirectDraw2_WaitForVerticalBlank(p,a,b) (p)->lpVtbl->WaitForVerticalBlank(p,a,b)
+/*** IDirectDraw2 methods ***/
+#define IDirectDraw2_GetAvailableVidMem(p,a,b,c) (p)->lpVtbl->GetAvailableVidMem(p,a,b,c)
+#else
+/*** IUnknown methods ***/
+#define IDirectDraw2_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDraw2_AddRef(p) (p)->AddRef()
+#define IDirectDraw2_Release(p) (p)->Release()
+/*** IDirectDraw methods ***/
+#define IDirectDraw2_Compact(p) (p)->Compact()
+#define IDirectDraw2_CreateClipper(p,a,b,c) (p)->CreateClipper(a,b,c)
+#define IDirectDraw2_CreatePalette(p,a,b,c,d) (p)->CreatePalette(a,b,c,d)
+#define IDirectDraw2_CreateSurface(p,a,b,c) (p)->CreateSurface(a,b,c)
+#define IDirectDraw2_DuplicateSurface(p,a,b) (p)->DuplicateSurface(a,b)
+#define IDirectDraw2_EnumDisplayModes(p,a,b,c,d) (p)->EnumDisplayModes(a,b,c,d)
+#define IDirectDraw2_EnumSurfaces(p,a,b,c,d) (p)->EnumSurfaces(a,b,c,d)
+#define IDirectDraw2_FlipToGDISurface(p) (p)->FlipToGDISurface()
+#define IDirectDraw2_GetCaps(p,a,b) (p)->GetCaps(a,b)
+#define IDirectDraw2_GetDisplayMode(p,a) (p)->GetDisplayMode(a)
+#define IDirectDraw2_GetFourCCCodes(p,a,b) (p)->GetFourCCCodes(a,b)
+#define IDirectDraw2_GetGDISurface(p,a) (p)->GetGDISurface(a)
+#define IDirectDraw2_GetMonitorFrequency(p,a) (p)->GetMonitorFrequency(a)
+#define IDirectDraw2_GetScanLine(p,a) (p)->GetScanLine(a)
+#define IDirectDraw2_GetVerticalBlankStatus(p,a) (p)->GetVerticalBlankStatus(a)
+#define IDirectDraw2_Initialize(p,a) (p)->Initialize(a)
+#define IDirectDraw2_RestoreDisplayMode(p) (p)->RestoreDisplayMode()
+#define IDirectDraw2_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b)
+#define IDirectDraw2_SetDisplayMode(p,a,b,c,d,e) (p)->SetDisplayMode(a,b,c,d,e)
+#define IDirectDraw2_WaitForVerticalBlank(p,a,b) (p)->WaitForVerticalBlank(a,b)
+/*** IDirectDraw2 methods ***/
+#define IDirectDraw2_GetAvailableVidMem(p,a,b,c) (p)->GetAvailableVidMem(a,b,c)
+#endif
+
+
+/*****************************************************************************
+ * IDirectDraw3 interface
+ */
+#define INTERFACE IDirectDraw3
+DECLARE_INTERFACE_(IDirectDraw3,IUnknown)
+{
+ /*** IUnknown methods ***/
+/*00*/ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+/*04*/ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+/*08*/ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectDraw2 methods ***/
+/*0c*/ STDMETHOD(Compact)(THIS) PURE;
+/*10*/ STDMETHOD(CreateClipper)(THIS_ DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, IUnknown *pUnkOuter) PURE;
+/*14*/ STDMETHOD(CreatePalette)(THIS_ DWORD dwFlags, LPPALETTEENTRY lpColorTable, LPDIRECTDRAWPALETTE *lplpDDPalette, IUnknown *pUnkOuter) PURE;
+/*18*/ STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE *lplpDDSurface, IUnknown *pUnkOuter) PURE;
+/*1c*/ STDMETHOD(DuplicateSurface)(THIS_ LPDIRECTDRAWSURFACE lpDDSurface, LPDIRECTDRAWSURFACE *lplpDupDDSurface) PURE;
+/*20*/ STDMETHOD(EnumDisplayModes)(THIS_ DWORD dwFlags, LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK lpEnumModesCallback) PURE;
+/*24*/ STDMETHOD(EnumSurfaces)(THIS_ DWORD dwFlags, LPDDSURFACEDESC lpDDSD, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE;
+/*28*/ STDMETHOD(FlipToGDISurface)(THIS) PURE;
+/*2c*/ STDMETHOD(GetCaps)(THIS_ LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) PURE;
+/*30*/ STDMETHOD(GetDisplayMode)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc) PURE;
+/*34*/ STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD lpNumCodes, LPDWORD lpCodes) PURE;
+/*38*/ STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE *lplpGDIDDSurface) PURE;
+/*3c*/ STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD lpdwFrequency) PURE;
+/*40*/ STDMETHOD(GetScanLine)(THIS_ LPDWORD lpdwScanLine) PURE;
+/*44*/ STDMETHOD(GetVerticalBlankStatus)(THIS_ BOOL *lpbIsInVB) PURE;
+/*48*/ STDMETHOD(Initialize)(THIS_ GUID *lpGUID) PURE;
+/*4c*/ STDMETHOD(RestoreDisplayMode)(THIS) PURE;
+/*50*/ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hWnd, DWORD dwFlags) PURE;
+/*54*/ STDMETHOD(SetDisplayMode)(THIS_ DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags) PURE;
+/*58*/ STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD dwFlags, HANDLE hEvent) PURE;
+ /* added in v2 */
+/*5c*/ STDMETHOD(GetAvailableVidMem)(THIS_ LPDDSCAPS lpDDCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree) PURE;
+ /* added in v3 */
+/*60*/ STDMETHOD(GetSurfaceFromDC)(THIS_ HDC hdc, LPDIRECTDRAWSURFACE *pSurf) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDraw3_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDraw3_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectDraw3_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectDraw methods ***/
+#define IDirectDraw3_Compact(p) (p)->lpVtbl->Compact(p)
+#define IDirectDraw3_CreateClipper(p,a,b,c) (p)->lpVtbl->CreateClipper(p,a,b,c)
+#define IDirectDraw3_CreatePalette(p,a,b,c,d) (p)->lpVtbl->CreatePalette(p,a,b,c,d)
+#define IDirectDraw3_CreateSurface(p,a,b,c) (p)->lpVtbl->CreateSurface(p,a,b,c)
+#define IDirectDraw3_DuplicateSurface(p,a,b) (p)->lpVtbl->DuplicateSurface(p,a,b)
+#define IDirectDraw3_EnumDisplayModes(p,a,b,c,d) (p)->lpVtbl->EnumDisplayModes(p,a,b,c,d)
+#define IDirectDraw3_EnumSurfaces(p,a,b,c,d) (p)->lpVtbl->EnumSurfaces(p,a,b,c,d)
+#define IDirectDraw3_FlipToGDISurface(p) (p)->lpVtbl->FlipToGDISurface(p)
+#define IDirectDraw3_GetCaps(p,a,b) (p)->lpVtbl->GetCaps(p,a,b)
+#define IDirectDraw3_GetDisplayMode(p,a) (p)->lpVtbl->GetDisplayMode(p,a)
+#define IDirectDraw3_GetFourCCCodes(p,a,b) (p)->lpVtbl->GetFourCCCodes(p,a,b)
+#define IDirectDraw3_GetGDISurface(p,a) (p)->lpVtbl->GetGDISurface(p,a)
+#define IDirectDraw3_GetMonitorFrequency(p,a) (p)->lpVtbl->GetMonitorFrequency(p,a)
+#define IDirectDraw3_GetScanLine(p,a) (p)->lpVtbl->GetScanLine(p,a)
+#define IDirectDraw3_GetVerticalBlankStatus(p,a) (p)->lpVtbl->GetVerticalBlankStatus(p,a)
+#define IDirectDraw3_Initialize(p,a) (p)->lpVtbl->Initialize(p,a)
+#define IDirectDraw3_RestoreDisplayMode(p) (p)->lpVtbl->RestoreDisplayMode(p)
+#define IDirectDraw3_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b)
+#define IDirectDraw3_SetDisplayMode(p,a,b,c,d,e) (p)->lpVtbl->SetDisplayMode(p,a,b,c,d,e)
+#define IDirectDraw3_WaitForVerticalBlank(p,a,b) (p)->lpVtbl->WaitForVerticalBlank(p,a,b)
+/*** IDirectDraw2 methods ***/
+#define IDirectDraw3_GetAvailableVidMem(p,a,b,c) (p)->lpVtbl->GetAvailableVidMem(p,a,b,c)
+/*** IDirectDraw3 methods ***/
+#define IDirectDraw3_GetSurfaceFromDC(p,a,b) (p)->lpVtbl->GetSurfaceFromDC(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirectDraw3_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDraw3_AddRef(p) (p)->AddRef()
+#define IDirectDraw3_Release(p) (p)->Release()
+/*** IDirectDraw methods ***/
+#define IDirectDraw3_Compact(p) (p)->Compact()
+#define IDirectDraw3_CreateClipper(p,a,b,c) (p)->CreateClipper(a,b,c)
+#define IDirectDraw3_CreatePalette(p,a,b,c,d) (p)->CreatePalette(a,b,c,d)
+#define IDirectDraw3_CreateSurface(p,a,b,c) (p)->CreateSurface(a,b,c)
+#define IDirectDraw3_DuplicateSurface(p,a,b) (p)->DuplicateSurface(a,b)
+#define IDirectDraw3_EnumDisplayModes(p,a,b,c,d) (p)->EnumDisplayModes(a,b,c,d)
+#define IDirectDraw3_EnumSurfaces(p,a,b,c,d) (p)->EnumSurfaces(a,b,c,d)
+#define IDirectDraw3_FlipToGDISurface(p) (p)->FlipToGDISurface()
+#define IDirectDraw3_GetCaps(p,a,b) (p)->GetCaps(a,b)
+#define IDirectDraw3_GetDisplayMode(p,a) (p)->GetDisplayMode(a)
+#define IDirectDraw3_GetFourCCCodes(p,a,b) (p)->GetFourCCCodes(a,b)
+#define IDirectDraw3_GetGDISurface(p,a) (p)->GetGDISurface(a)
+#define IDirectDraw3_GetMonitorFrequency(p,a) (p)->GetMonitorFrequency(a)
+#define IDirectDraw3_GetScanLine(p,a) (p)->GetScanLine(a)
+#define IDirectDraw3_GetVerticalBlankStatus(p,a) (p)->GetVerticalBlankStatus(a)
+#define IDirectDraw3_Initialize(p,a) (p)->Initialize(a)
+#define IDirectDraw3_RestoreDisplayMode(p) (p)->RestoreDisplayMode()
+#define IDirectDraw3_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b)
+#define IDirectDraw3_SetDisplayMode(p,a,b,c,d,e) (p)->SetDisplayMode(a,b,c,d,e)
+#define IDirectDraw3_WaitForVerticalBlank(p,a,b) (p)->WaitForVerticalBlank(a,b)
+/*** IDirectDraw2 methods ***/
+#define IDirectDraw3_GetAvailableVidMem(p,a,b,c) (p)->GetAvailableVidMem(a,b,c)
+/*** IDirectDraw3 methods ***/
+#define IDirectDraw3_GetSurfaceFromDC(p,a,b) (p)->GetSurfaceFromDC(a,b)
+#endif
+
+
+/*****************************************************************************
+ * IDirectDraw4 interface
+ */
+#define INTERFACE IDirectDraw4
+DECLARE_INTERFACE_(IDirectDraw4,IUnknown)
+{
+ /*** IUnknown methods ***/
+/*00*/ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+/*04*/ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+/*08*/ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectDraw4 methods ***/
+/*0c*/ STDMETHOD(Compact)(THIS) PURE;
+/*10*/ STDMETHOD(CreateClipper)(THIS_ DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, IUnknown *pUnkOuter) PURE;
+/*14*/ STDMETHOD(CreatePalette)(THIS_ DWORD dwFlags, LPPALETTEENTRY lpColorTable, LPDIRECTDRAWPALETTE *lplpDDPalette, IUnknown *pUnkOuter) PURE;
+/*18*/ STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC2 lpDDSurfaceDesc, LPDIRECTDRAWSURFACE4 *lplpDDSurface, IUnknown *pUnkOuter) PURE;
+/*1c*/ STDMETHOD(DuplicateSurface)(THIS_ LPDIRECTDRAWSURFACE4 lpDDSurface, LPDIRECTDRAWSURFACE4 *lplpDupDDSurface) PURE;
+/*20*/ STDMETHOD(EnumDisplayModes)(THIS_ DWORD dwFlags, LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK2 lpEnumModesCallback) PURE;
+/*24*/ STDMETHOD(EnumSurfaces)(THIS_ DWORD dwFlags, LPDDSURFACEDESC2 lpDDSD, LPVOID lpContext, LPDDENUMSURFACESCALLBACK2 lpEnumSurfacesCallback) PURE;
+/*28*/ STDMETHOD(FlipToGDISurface)(THIS) PURE;
+/*2c*/ STDMETHOD(GetCaps)(THIS_ LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) PURE;
+/*30*/ STDMETHOD(GetDisplayMode)(THIS_ LPDDSURFACEDESC2 lpDDSurfaceDesc) PURE;
+/*34*/ STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD lpNumCodes, LPDWORD lpCodes) PURE;
+/*38*/ STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE4 *lplpGDIDDSurface) PURE;
+/*3c*/ STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD lpdwFrequency) PURE;
+/*40*/ STDMETHOD(GetScanLine)(THIS_ LPDWORD lpdwScanLine) PURE;
+/*44*/ STDMETHOD(GetVerticalBlankStatus)(THIS_ BOOL *lpbIsInVB) PURE;
+/*48*/ STDMETHOD(Initialize)(THIS_ GUID *lpGUID) PURE;
+/*4c*/ STDMETHOD(RestoreDisplayMode)(THIS) PURE;
+/*50*/ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hWnd, DWORD dwFlags) PURE;
+/*54*/ STDMETHOD(SetDisplayMode)(THIS_ DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags) PURE;
+/*58*/ STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD dwFlags, HANDLE hEvent) PURE;
+ /* added in v2 */
+/*5c*/ STDMETHOD(GetAvailableVidMem)(THIS_ LPDDSCAPS2 lpDDCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree) PURE;
+ /* added in v4 */
+/*60*/ STDMETHOD(GetSurfaceFromDC)(THIS_ HDC hdc, LPDIRECTDRAWSURFACE4 *pSurf) PURE;
+/*64*/ STDMETHOD(RestoreAllSurfaces)(THIS) PURE;
+/*68*/ STDMETHOD(TestCooperativeLevel)(THIS) PURE;
+/*6c*/ STDMETHOD(GetDeviceIdentifier)(THIS_ LPDDDEVICEIDENTIFIER pDDDI, DWORD dwFlags) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDraw4_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDraw4_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectDraw4_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectDraw methods ***/
+#define IDirectDraw4_Compact(p) (p)->lpVtbl->Compact(p)
+#define IDirectDraw4_CreateClipper(p,a,b,c) (p)->lpVtbl->CreateClipper(p,a,b,c)
+#define IDirectDraw4_CreatePalette(p,a,b,c,d) (p)->lpVtbl->CreatePalette(p,a,b,c,d)
+#define IDirectDraw4_CreateSurface(p,a,b,c) (p)->lpVtbl->CreateSurface(p,a,b,c)
+#define IDirectDraw4_DuplicateSurface(p,a,b) (p)->lpVtbl->DuplicateSurface(p,a,b)
+#define IDirectDraw4_EnumDisplayModes(p,a,b,c,d) (p)->lpVtbl->EnumDisplayModes(p,a,b,c,d)
+#define IDirectDraw4_EnumSurfaces(p,a,b,c,d) (p)->lpVtbl->EnumSurfaces(p,a,b,c,d)
+#define IDirectDraw4_FlipToGDISurface(p) (p)->lpVtbl->FlipToGDISurface(p)
+#define IDirectDraw4_GetCaps(p,a,b) (p)->lpVtbl->GetCaps(p,a,b)
+#define IDirectDraw4_GetDisplayMode(p,a) (p)->lpVtbl->GetDisplayMode(p,a)
+#define IDirectDraw4_GetFourCCCodes(p,a,b) (p)->lpVtbl->GetFourCCCodes(p,a,b)
+#define IDirectDraw4_GetGDISurface(p,a) (p)->lpVtbl->GetGDISurface(p,a)
+#define IDirectDraw4_GetMonitorFrequency(p,a) (p)->lpVtbl->GetMonitorFrequency(p,a)
+#define IDirectDraw4_GetScanLine(p,a) (p)->lpVtbl->GetScanLine(p,a)
+#define IDirectDraw4_GetVerticalBlankStatus(p,a) (p)->lpVtbl->GetVerticalBlankStatus(p,a)
+#define IDirectDraw4_Initialize(p,a) (p)->lpVtbl->Initialize(p,a)
+#define IDirectDraw4_RestoreDisplayMode(p) (p)->lpVtbl->RestoreDisplayMode(p)
+#define IDirectDraw4_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b)
+#define IDirectDraw4_SetDisplayMode(p,a,b,c,d,e) (p)->lpVtbl->SetDisplayMode(p,a,b,c,d,e)
+#define IDirectDraw4_WaitForVerticalBlank(p,a,b) (p)->lpVtbl->WaitForVerticalBlank(p,a,b)
+/*** IDirectDraw2 methods ***/
+#define IDirectDraw4_GetAvailableVidMem(p,a,b,c) (p)->lpVtbl->GetAvailableVidMem(p,a,b,c)
+/*** IDirectDraw4 methods ***/
+#define IDirectDraw4_GetSurfaceFromDC(p,a,b) (p)->lpVtbl->GetSurfaceFromDC(p,a,b)
+#define IDirectDraw4_RestoreAllSurfaces(pc) (p)->lpVtbl->RestoreAllSurfaces(p)
+#define IDirectDraw4_TestCooperativeLevel(p) (p)->lpVtbl->TestCooperativeLevel(p)
+#define IDirectDraw4_GetDeviceIdentifier(p,a,b) (p)->lpVtbl->GetDeviceIdentifier(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirectDraw4_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDraw4_AddRef(p) (p)->AddRef()
+#define IDirectDraw4_Release(p) (p)->Release()
+/*** IDirectDraw methods ***/
+#define IDirectDraw4_Compact(p) (p)->Compact()
+#define IDirectDraw4_CreateClipper(p,a,b,c) (p)->CreateClipper(a,b,c)
+#define IDirectDraw4_CreatePalette(p,a,b,c,d) (p)->CreatePalette(a,b,c,d)
+#define IDirectDraw4_CreateSurface(p,a,b,c) (p)->CreateSurface(a,b,c)
+#define IDirectDraw4_DuplicateSurface(p,a,b) (p)->DuplicateSurface(a,b)
+#define IDirectDraw4_EnumDisplayModes(p,a,b,c,d) (p)->EnumDisplayModes(a,b,c,d)
+#define IDirectDraw4_EnumSurfaces(p,a,b,c,d) (p)->EnumSurfaces(a,b,c,d)
+#define IDirectDraw4_FlipToGDISurface(p) (p)->FlipToGDISurface()
+#define IDirectDraw4_GetCaps(p,a,b) (p)->GetCaps(a,b)
+#define IDirectDraw4_GetDisplayMode(p,a) (p)->GetDisplayMode(a)
+#define IDirectDraw4_GetFourCCCodes(p,a,b) (p)->GetFourCCCodes(a,b)
+#define IDirectDraw4_GetGDISurface(p,a) (p)->GetGDISurface(a)
+#define IDirectDraw4_GetMonitorFrequency(p,a) (p)->GetMonitorFrequency(a)
+#define IDirectDraw4_GetScanLine(p,a) (p)->GetScanLine(a)
+#define IDirectDraw4_GetVerticalBlankStatus(p,a) (p)->GetVerticalBlankStatus(a)
+#define IDirectDraw4_Initialize(p,a) (p)->Initialize(a)
+#define IDirectDraw4_RestoreDisplayMode(p) (p)->RestoreDisplayMode()
+#define IDirectDraw4_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b)
+#define IDirectDraw4_SetDisplayMode(p,a,b,c,d,e) (p)->SetDisplayMode(a,b,c,d,e)
+#define IDirectDraw4_WaitForVerticalBlank(p,a,b) (p)->WaitForVerticalBlank(a,b)
+/*** IDirectDraw2 methods ***/
+#define IDirectDraw4_GetAvailableVidMem(p,a,b,c) (p)->GetAvailableVidMem(a,b,c)
+/*** IDirectDraw4 methods ***/
+#define IDirectDraw4_GetSurfaceFromDC(p,a,b) (p)->GetSurfaceFromDC(a,b)
+#define IDirectDraw4_RestoreAllSurfaces(pc) (p)->RestoreAllSurfaces()
+#define IDirectDraw4_TestCooperativeLevel(p) (p)->TestCooperativeLevel()
+#define IDirectDraw4_GetDeviceIdentifier(p,a,b) (p)->GetDeviceIdentifier(a,b)
+#endif
+
+
+/*****************************************************************************
+ * IDirectDraw7 interface
+ */
+/* Note: IDirectDraw7 cannot derive from IDirectDraw4; it is even documented
+ * as not interchangeable with earlier DirectDraw interfaces.
+ */
+#define INTERFACE IDirectDraw7
+DECLARE_INTERFACE_(IDirectDraw7,IUnknown)
+{
+ /*** IUnknown methods ***/
+/*00*/ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+/*04*/ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+/*08*/ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectDraw7 methods ***/
+/*0c*/ STDMETHOD(Compact)(THIS) PURE;
+/*10*/ STDMETHOD(CreateClipper)(THIS_ DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, IUnknown *pUnkOuter) PURE;
+/*14*/ STDMETHOD(CreatePalette)(THIS_ DWORD dwFlags, LPPALETTEENTRY lpColorTable, LPDIRECTDRAWPALETTE *lplpDDPalette, IUnknown *pUnkOuter) PURE;
+/*18*/ STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC2 lpDDSurfaceDesc, LPDIRECTDRAWSURFACE7 *lplpDDSurface, IUnknown *pUnkOuter) PURE;
+/*1c*/ STDMETHOD(DuplicateSurface)(THIS_ LPDIRECTDRAWSURFACE7 lpDDSurface, LPDIRECTDRAWSURFACE7 *lplpDupDDSurface) PURE;
+/*20*/ STDMETHOD(EnumDisplayModes)(THIS_ DWORD dwFlags, LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK2 lpEnumModesCallback) PURE;
+/*24*/ STDMETHOD(EnumSurfaces)(THIS_ DWORD dwFlags, LPDDSURFACEDESC2 lpDDSD, LPVOID lpContext, LPDDENUMSURFACESCALLBACK7 lpEnumSurfacesCallback) PURE;
+/*28*/ STDMETHOD(FlipToGDISurface)(THIS) PURE;
+/*2c*/ STDMETHOD(GetCaps)(THIS_ LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) PURE;
+/*30*/ STDMETHOD(GetDisplayMode)(THIS_ LPDDSURFACEDESC2 lpDDSurfaceDesc) PURE;
+/*34*/ STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD lpNumCodes, LPDWORD lpCodes) PURE;
+/*38*/ STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE7 *lplpGDIDDSurface) PURE;
+/*3c*/ STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD lpdwFrequency) PURE;
+/*40*/ STDMETHOD(GetScanLine)(THIS_ LPDWORD lpdwScanLine) PURE;
+/*44*/ STDMETHOD(GetVerticalBlankStatus)(THIS_ BOOL *lpbIsInVB) PURE;
+/*48*/ STDMETHOD(Initialize)(THIS_ GUID *lpGUID) PURE;
+/*4c*/ STDMETHOD(RestoreDisplayMode)(THIS) PURE;
+/*50*/ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hWnd, DWORD dwFlags) PURE;
+/*54*/ STDMETHOD(SetDisplayMode)(THIS_ DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags) PURE;
+/*58*/ STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD dwFlags, HANDLE hEvent) PURE;
+ /* added in v2 */
+/*5c*/ STDMETHOD(GetAvailableVidMem)(THIS_ LPDDSCAPS2 lpDDCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree) PURE;
+ /* added in v4 */
+/*60*/ STDMETHOD(GetSurfaceFromDC)(THIS_ HDC hdc, LPDIRECTDRAWSURFACE7 *pSurf) PURE;
+/*64*/ STDMETHOD(RestoreAllSurfaces)(THIS) PURE;
+/*68*/ STDMETHOD(TestCooperativeLevel)(THIS) PURE;
+/*6c*/ STDMETHOD(GetDeviceIdentifier)(THIS_ LPDDDEVICEIDENTIFIER2 pDDDI, DWORD dwFlags) PURE;
+ /* added in v7 */
+/*70*/ STDMETHOD(StartModeTest)(THIS_ LPSIZE pModes, DWORD dwNumModes, DWORD dwFlags) PURE;
+/*74*/ STDMETHOD(EvaluateMode)(THIS_ DWORD dwFlags, DWORD *pTimeout) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDraw7_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDraw7_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectDraw7_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectDraw methods ***/
+#define IDirectDraw7_Compact(p) (p)->lpVtbl->Compact(p)
+#define IDirectDraw7_CreateClipper(p,a,b,c) (p)->lpVtbl->CreateClipper(p,a,b,c)
+#define IDirectDraw7_CreatePalette(p,a,b,c,d) (p)->lpVtbl->CreatePalette(p,a,b,c,d)
+#define IDirectDraw7_CreateSurface(p,a,b,c) (p)->lpVtbl->CreateSurface(p,a,b,c)
+#define IDirectDraw7_DuplicateSurface(p,a,b) (p)->lpVtbl->DuplicateSurface(p,a,b)
+#define IDirectDraw7_EnumDisplayModes(p,a,b,c,d) (p)->lpVtbl->EnumDisplayModes(p,a,b,c,d)
+#define IDirectDraw7_EnumSurfaces(p,a,b,c,d) (p)->lpVtbl->EnumSurfaces(p,a,b,c,d)
+#define IDirectDraw7_FlipToGDISurface(p) (p)->lpVtbl->FlipToGDISurface(p)
+#define IDirectDraw7_GetCaps(p,a,b) (p)->lpVtbl->GetCaps(p,a,b)
+#define IDirectDraw7_GetDisplayMode(p,a) (p)->lpVtbl->GetDisplayMode(p,a)
+#define IDirectDraw7_GetFourCCCodes(p,a,b) (p)->lpVtbl->GetFourCCCodes(p,a,b)
+#define IDirectDraw7_GetGDISurface(p,a) (p)->lpVtbl->GetGDISurface(p,a)
+#define IDirectDraw7_GetMonitorFrequency(p,a) (p)->lpVtbl->GetMonitorFrequency(p,a)
+#define IDirectDraw7_GetScanLine(p,a) (p)->lpVtbl->GetScanLine(p,a)
+#define IDirectDraw7_GetVerticalBlankStatus(p,a) (p)->lpVtbl->GetVerticalBlankStatus(p,a)
+#define IDirectDraw7_Initialize(p,a) (p)->lpVtbl->Initialize(p,a)
+#define IDirectDraw7_RestoreDisplayMode(p) (p)->lpVtbl->RestoreDisplayMode(p)
+#define IDirectDraw7_SetCooperativeLevel(p,a,b) (p)->lpVtbl->SetCooperativeLevel(p,a,b)
+#define IDirectDraw7_SetDisplayMode(p,a,b,c,d,e) (p)->lpVtbl->SetDisplayMode(p,a,b,c,d,e)
+#define IDirectDraw7_WaitForVerticalBlank(p,a,b) (p)->lpVtbl->WaitForVerticalBlank(p,a,b)
+/*** added in IDirectDraw2 ***/
+#define IDirectDraw7_GetAvailableVidMem(p,a,b,c) (p)->lpVtbl->GetAvailableVidMem(p,a,b,c)
+/*** added in IDirectDraw4 ***/
+#define IDirectDraw7_GetSurfaceFromDC(p,a,b) (p)->lpVtbl->GetSurfaceFromDC(p,a,b)
+#define IDirectDraw7_RestoreAllSurfaces(p) (p)->lpVtbl->RestoreAllSurfaces(p)
+#define IDirectDraw7_TestCooperativeLevel(p) (p)->lpVtbl->TestCooperativeLevel(p)
+#define IDirectDraw7_GetDeviceIdentifier(p,a,b) (p)->lpVtbl->GetDeviceIdentifier(p,a,b)
+/*** added in IDirectDraw 7 ***/
+#define IDirectDraw7_StartModeTest(p,a,b,c) (p)->lpVtbl->StartModeTest(p,a,b,c)
+#define IDirectDraw7_EvaluateMode(p,a,b) (p)->lpVtbl->EvaluateMode(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirectDraw7_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDraw7_AddRef(p) (p)->AddRef()
+#define IDirectDraw7_Release(p) (p)->Release()
+/*** IDirectDraw methods ***/
+#define IDirectDraw7_Compact(p) (p)->Compact()
+#define IDirectDraw7_CreateClipper(p,a,b,c) (p)->CreateClipper(a,b,c)
+#define IDirectDraw7_CreatePalette(p,a,b,c,d) (p)->CreatePalette(a,b,c,d)
+#define IDirectDraw7_CreateSurface(p,a,b,c) (p)->CreateSurface(a,b,c)
+#define IDirectDraw7_DuplicateSurface(p,a,b) (p)->DuplicateSurface(a,b)
+#define IDirectDraw7_EnumDisplayModes(p,a,b,c,d) (p)->EnumDisplayModes(a,b,c,d)
+#define IDirectDraw7_EnumSurfaces(p,a,b,c,d) (p)->EnumSurfaces(a,b,c,d)
+#define IDirectDraw7_FlipToGDISurface(p) (p)->FlipToGDISurface()
+#define IDirectDraw7_GetCaps(p,a,b) (p)->GetCaps(a,b)
+#define IDirectDraw7_GetDisplayMode(p,a) (p)->GetDisplayMode(a)
+#define IDirectDraw7_GetFourCCCodes(p,a,b) (p)->GetFourCCCodes(a,b)
+#define IDirectDraw7_GetGDISurface(p,a) (p)->GetGDISurface(a)
+#define IDirectDraw7_GetMonitorFrequency(p,a) (p)->GetMonitorFrequency(a)
+#define IDirectDraw7_GetScanLine(p,a) (p)->GetScanLine(a)
+#define IDirectDraw7_GetVerticalBlankStatus(p,a) (p)->GetVerticalBlankStatus(a)
+#define IDirectDraw7_Initialize(p,a) (p)->Initialize(a)
+#define IDirectDraw7_RestoreDisplayMode(p) (p)->RestoreDisplayMode()
+#define IDirectDraw7_SetCooperativeLevel(p,a,b) (p)->SetCooperativeLevel(a,b)
+#define IDirectDraw7_SetDisplayMode(p,a,b,c,d,e) (p)->SetDisplayMode(a,b,c,d,e)
+#define IDirectDraw7_WaitForVerticalBlank(p,a,b) (p)->WaitForVerticalBlank(a,b)
+/*** added in IDirectDraw2 ***/
+#define IDirectDraw7_GetAvailableVidMem(p,a,b,c) (p)->GetAvailableVidMem(a,b,c)
+/*** added in IDirectDraw4 ***/
+#define IDirectDraw7_GetSurfaceFromDC(p,a,b) (p)->GetSurfaceFromDC(a,b)
+#define IDirectDraw7_RestoreAllSurfaces(p) (p)->RestoreAllSurfaces()
+#define IDirectDraw7_TestCooperativeLevel(p) (p)->TestCooperativeLevel()
+#define IDirectDraw7_GetDeviceIdentifier(p,a,b) (p)->GetDeviceIdentifier(a,b)
+/*** added in IDirectDraw 7 ***/
+#define IDirectDraw7_StartModeTest(p,a,b,c) (p)->StartModeTest(a,b,c)
+#define IDirectDraw7_EvaluateMode(p,a,b) (p)->EvaluateMode(a,b)
+#endif
+
+
+/*****************************************************************************
+ * IDirectDrawSurface interface
+ */
+#define INTERFACE IDirectDrawSurface
+DECLARE_INTERFACE_(IDirectDrawSurface,IUnknown)
+{
+ /*** IUnknown methods ***/
+/*00*/ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+/*04*/ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+/*08*/ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectDrawSurface methods ***/
+/*0c*/ STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE lpDDSAttachedSurface) PURE;
+/*10*/ STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT lpRect) PURE;
+/*14*/ STDMETHOD(Blt)(THIS_ LPRECT lpDestRect, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) PURE;
+/*18*/ STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags) PURE;
+/*1c*/ STDMETHOD(BltFast)(THIS_ DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) PURE;
+/*20*/ STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDSAttachedSurface) PURE;
+/*24*/ STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE;
+/*28*/ STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback) PURE;
+/*2c*/ STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DWORD dwFlags) PURE;
+/*30*/ STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE *lplpDDAttachedSurface) PURE;
+/*34*/ STDMETHOD(GetBltStatus)(THIS_ DWORD dwFlags) PURE;
+/*38*/ STDMETHOD(GetCaps)(THIS_ LPDDSCAPS lpDDSCaps) PURE;
+/*3c*/ STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER *lplpDDClipper) PURE;
+/*40*/ STDMETHOD(GetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE;
+/*44*/ STDMETHOD(GetDC)(THIS_ HDC *lphDC) PURE;
+/*48*/ STDMETHOD(GetFlipStatus)(THIS_ DWORD dwFlags) PURE;
+/*4c*/ STDMETHOD(GetOverlayPosition)(THIS_ LPLONG lplX, LPLONG lplY) PURE;
+/*50*/ STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE *lplpDDPalette) PURE;
+/*54*/ STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT lpDDPixelFormat) PURE;
+/*58*/ STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc) PURE;
+/*5c*/ STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, LPDDSURFACEDESC lpDDSurfaceDesc) PURE;
+/*60*/ STDMETHOD(IsLost)(THIS) PURE;
+/*64*/ STDMETHOD(Lock)(THIS_ LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent) PURE;
+/*68*/ STDMETHOD(ReleaseDC)(THIS_ HDC hDC) PURE;
+/*6c*/ STDMETHOD(Restore)(THIS) PURE;
+/*70*/ STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER lpDDClipper) PURE;
+/*74*/ STDMETHOD(SetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE;
+/*78*/ STDMETHOD(SetOverlayPosition)(THIS_ LONG lX, LONG lY) PURE;
+/*7c*/ STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE lpDDPalette) PURE;
+/*80*/ STDMETHOD(Unlock)(THIS_ LPVOID lpSurfaceData) PURE;
+/*84*/ STDMETHOD(UpdateOverlay)(THIS_ LPRECT lpSrcRect, LPDIRECTDRAWSURFACE lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpDDOverlayFx) PURE;
+/*88*/ STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD dwFlags) PURE;
+/*8c*/ STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDSReference) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDrawSurface_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDrawSurface_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectDrawSurface_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectDrawSurface methods ***/
+#define IDirectDrawSurface_AddAttachedSurface(p,a) (p)->lpVtbl->AddAttachedSurface(p,a)
+#define IDirectDrawSurface_AddOverlayDirtyRect(p,a) (p)->lpVtbl->AddOverlayDirtyRect(p,a)
+#define IDirectDrawSurface_Blt(p,a,b,c,d,e) (p)->lpVtbl->Blt(p,a,b,c,d,e)
+#define IDirectDrawSurface_BltBatch(p,a,b,c) (p)->lpVtbl->BltBatch(p,a,b,c)
+#define IDirectDrawSurface_BltFast(p,a,b,c,d,e) (p)->lpVtbl->BltFast(p,a,b,c,d,e)
+#define IDirectDrawSurface_DeleteAttachedSurface(p,a,b) (p)->lpVtbl->DeleteAttachedSurface(p,a,b)
+#define IDirectDrawSurface_EnumAttachedSurfaces(p,a,b) (p)->lpVtbl->EnumAttachedSurfaces(p,a,b)
+#define IDirectDrawSurface_EnumOverlayZOrders(p,a,b,c) (p)->lpVtbl->EnumOverlayZOrders(p,a,b,c)
+#define IDirectDrawSurface_Flip(p,a,b) (p)->lpVtbl->Flip(p,a,b)
+#define IDirectDrawSurface_GetAttachedSurface(p,a,b) (p)->lpVtbl->GetAttachedSurface(p,a,b)
+#define IDirectDrawSurface_GetBltStatus(p,a) (p)->lpVtbl->GetBltStatus(p,a)
+#define IDirectDrawSurface_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a)
+#define IDirectDrawSurface_GetClipper(p,a) (p)->lpVtbl->GetClipper(p,a)
+#define IDirectDrawSurface_GetColorKey(p,a,b) (p)->lpVtbl->GetColorKey(p,a,b)
+#define IDirectDrawSurface_GetDC(p,a) (p)->lpVtbl->GetDC(p,a)
+#define IDirectDrawSurface_GetFlipStatus(p,a) (p)->lpVtbl->GetFlipStatus(p,a)
+#define IDirectDrawSurface_GetOverlayPosition(p,a,b) (p)->lpVtbl->GetOverlayPosition(p,a,b)
+#define IDirectDrawSurface_GetPalette(p,a) (p)->lpVtbl->GetPalette(p,a)
+#define IDirectDrawSurface_GetPixelFormat(p,a) (p)->lpVtbl->GetPixelFormat(p,a)
+#define IDirectDrawSurface_GetSurfaceDesc(p,a) (p)->lpVtbl->GetSurfaceDesc(p,a)
+#define IDirectDrawSurface_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b)
+#define IDirectDrawSurface_IsLost(p) (p)->lpVtbl->IsLost(p)
+#define IDirectDrawSurface_Lock(p,a,b,c,d) (p)->lpVtbl->Lock(p,a,b,c,d)
+#define IDirectDrawSurface_ReleaseDC(p,a) (p)->lpVtbl->ReleaseDC(p,a)
+#define IDirectDrawSurface_Restore(p) (p)->lpVtbl->Restore(p)
+#define IDirectDrawSurface_SetClipper(p,a) (p)->lpVtbl->SetClipper(p,a)
+#define IDirectDrawSurface_SetColorKey(p,a,b) (p)->lpVtbl->SetColorKey(p,a,b)
+#define IDirectDrawSurface_SetOverlayPosition(p,a,b) (p)->lpVtbl->SetOverlayPosition(p,a,b)
+#define IDirectDrawSurface_SetPalette(p,a) (p)->lpVtbl->SetPalette(p,a)
+#define IDirectDrawSurface_Unlock(p,a) (p)->lpVtbl->Unlock(p,a)
+#define IDirectDrawSurface_UpdateOverlay(p,a,b,c,d,e) (p)->lpVtbl->UpdateOverlay(p,a,b,c,d,e)
+#define IDirectDrawSurface_UpdateOverlayDisplay(p,a) (p)->lpVtbl->UpdateOverlayDisplay(p,a)
+#define IDirectDrawSurface_UpdateOverlayZOrder(p,a,b) (p)->lpVtbl->UpdateOverlayZOrder(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirectDrawSurface_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDrawSurface_AddRef(p) (p)->AddRef()
+#define IDirectDrawSurface_Release(p) (p)->Release()
+/*** IDirectDrawSurface methods ***/
+#define IDirectDrawSurface_AddAttachedSurface(p,a) (p)->AddAttachedSurface(a)
+#define IDirectDrawSurface_AddOverlayDirtyRect(p,a) (p)->AddOverlayDirtyRect(a)
+#define IDirectDrawSurface_Blt(p,a,b,c,d,e) (p)->Blt(a,b,c,d,e)
+#define IDirectDrawSurface_BltBatch(p,a,b,c) (p)->BltBatch(a,b,c)
+#define IDirectDrawSurface_BltFast(p,a,b,c,d,e) (p)->BltFast(a,b,c,d,e)
+#define IDirectDrawSurface_DeleteAttachedSurface(p,a,b) (p)->DeleteAttachedSurface(a,b)
+#define IDirectDrawSurface_EnumAttachedSurfaces(p,a,b) (p)->EnumAttachedSurfaces(a,b)
+#define IDirectDrawSurface_EnumOverlayZOrders(p,a,b,c) (p)->EnumOverlayZOrders(a,b,c)
+#define IDirectDrawSurface_Flip(p,a,b) (p)->Flip(a,b)
+#define IDirectDrawSurface_GetAttachedSurface(p,a,b) (p)->GetAttachedSurface(a,b)
+#define IDirectDrawSurface_GetBltStatus(p,a) (p)->GetBltStatus(a)
+#define IDirectDrawSurface_GetCaps(p,a) (p)->GetCaps(a)
+#define IDirectDrawSurface_GetClipper(p,a) (p)->GetClipper(a)
+#define IDirectDrawSurface_GetColorKey(p,a,b) (p)->GetColorKey(a,b)
+#define IDirectDrawSurface_GetDC(p,a) (p)->GetDC(a)
+#define IDirectDrawSurface_GetFlipStatus(p,a) (p)->GetFlipStatus(a)
+#define IDirectDrawSurface_GetOverlayPosition(p,a,b) (p)->GetOverlayPosition(a,b)
+#define IDirectDrawSurface_GetPalette(p,a) (p)->GetPalette(a)
+#define IDirectDrawSurface_GetPixelFormat(p,a) (p)->GetPixelFormat(a)
+#define IDirectDrawSurface_GetSurfaceDesc(p,a) (p)->GetSurfaceDesc(a)
+#define IDirectDrawSurface_Initialize(p,a,b) (p)->Initialize(a,b)
+#define IDirectDrawSurface_IsLost(p) (p)->IsLost()
+#define IDirectDrawSurface_Lock(p,a,b,c,d) (p)->Lock(a,b,c,d)
+#define IDirectDrawSurface_ReleaseDC(p,a) (p)->ReleaseDC(a)
+#define IDirectDrawSurface_Restore(p) (p)->Restore()
+#define IDirectDrawSurface_SetClipper(p,a) (p)->SetClipper(a)
+#define IDirectDrawSurface_SetColorKey(p,a,b) (p)->SetColorKey(a,b)
+#define IDirectDrawSurface_SetOverlayPosition(p,a,b) (p)->SetOverlayPosition(a,b)
+#define IDirectDrawSurface_SetPalette(p,a) (p)->SetPalette(a)
+#define IDirectDrawSurface_Unlock(p,a) (p)->Unlock(a)
+#define IDirectDrawSurface_UpdateOverlay(p,a,b,c,d,e) (p)->UpdateOverlay(a,b,c,d,e)
+#define IDirectDrawSurface_UpdateOverlayDisplay(p,a) (p)->UpdateOverlayDisplay(a)
+#define IDirectDrawSurface_UpdateOverlayZOrder(p,a,b) (p)->UpdateOverlayZOrder(a,b)
+#endif
+
+
+/*****************************************************************************
+ * IDirectDrawSurface2 interface
+ */
+/* Cannot inherit from IDirectDrawSurface because the LPDIRECTDRAWSURFACE parameters
+ * have been converted to LPDIRECTDRAWSURFACE2.
+ */
+#define INTERFACE IDirectDrawSurface2
+DECLARE_INTERFACE_(IDirectDrawSurface2,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectDrawSurface2 methods ***/
+ STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE2 lpDDSAttachedSurface) PURE;
+ STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT lpRect) PURE;
+ STDMETHOD(Blt)(THIS_ LPRECT lpDestRect, LPDIRECTDRAWSURFACE2 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) PURE;
+ STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags) PURE;
+ STDMETHOD(BltFast)(THIS_ DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE2 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) PURE;
+ STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE2 lpDDSAttachedSurface) PURE;
+ STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE;
+ STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback) PURE;
+ STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE2 lpDDSurfaceTargetOverride, DWORD dwFlags) PURE;
+ STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE2 *lplpDDAttachedSurface) PURE;
+ STDMETHOD(GetBltStatus)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(GetCaps)(THIS_ LPDDSCAPS lpDDSCaps) PURE;
+ STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER *lplpDDClipper) PURE;
+ STDMETHOD(GetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE;
+ STDMETHOD(GetDC)(THIS_ HDC *lphDC) PURE;
+ STDMETHOD(GetFlipStatus)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(GetOverlayPosition)(THIS_ LPLONG lplX, LPLONG lplY) PURE;
+ STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE *lplpDDPalette) PURE;
+ STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT lpDDPixelFormat) PURE;
+ STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc) PURE;
+ STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, LPDDSURFACEDESC lpDDSurfaceDesc) PURE;
+ STDMETHOD(IsLost)(THIS) PURE;
+ STDMETHOD(Lock)(THIS_ LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent) PURE;
+ STDMETHOD(ReleaseDC)(THIS_ HDC hDC) PURE;
+ STDMETHOD(Restore)(THIS) PURE;
+ STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER lpDDClipper) PURE;
+ STDMETHOD(SetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE;
+ STDMETHOD(SetOverlayPosition)(THIS_ LONG lX, LONG lY) PURE;
+ STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE lpDDPalette) PURE;
+ STDMETHOD(Unlock)(THIS_ LPVOID lpSurfaceData) PURE;
+ STDMETHOD(UpdateOverlay)(THIS_ LPRECT lpSrcRect, LPDIRECTDRAWSURFACE2 lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpDDOverlayFx) PURE;
+ STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE2 lpDDSReference) PURE;
+ /* added in v2 */
+ STDMETHOD(GetDDInterface)(THIS_ LPVOID *lplpDD) PURE;
+ STDMETHOD(PageLock)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(PageUnlock)(THIS_ DWORD dwFlags) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDrawSurface2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDrawSurface2_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectDrawSurface2_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectDrawSurface methods (almost) ***/
+#define IDirectDrawSurface2_AddAttachedSurface(p,a) (p)->lpVtbl->AddAttachedSurface(p,a)
+#define IDirectDrawSurface2_AddOverlayDirtyRect(p,a) (p)->lpVtbl->AddOverlayDirtyRect(p,a)
+#define IDirectDrawSurface2_Blt(p,a,b,c,d,e) (p)->lpVtbl->Blt(p,a,b,c,d,e)
+#define IDirectDrawSurface2_BltBatch(p,a,b,c) (p)->lpVtbl->BltBatch(p,a,b,c)
+#define IDirectDrawSurface2_BltFast(p,a,b,c,d,e) (p)->lpVtbl->BltFast(p,a,b,c,d,e)
+#define IDirectDrawSurface2_DeleteAttachedSurface(p,a,b) (p)->lpVtbl->DeleteAttachedSurface(p,a,b)
+#define IDirectDrawSurface2_EnumAttachedSurfaces(p,a,b) (p)->lpVtbl->EnumAttachedSurfaces(p,a,b)
+#define IDirectDrawSurface2_EnumOverlayZOrders(p,a,b,c) (p)->lpVtbl->EnumOverlayZOrders(p,a,b,c)
+#define IDirectDrawSurface2_Flip(p,a,b) (p)->lpVtbl->Flip(p,a,b)
+#define IDirectDrawSurface2_GetAttachedSurface(p,a,b) (p)->lpVtbl->GetAttachedSurface(p,a,b)
+#define IDirectDrawSurface2_GetBltStatus(p,a) (p)->lpVtbl->GetBltStatus(p,a)
+#define IDirectDrawSurface2_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a)
+#define IDirectDrawSurface2_GetClipper(p,a) (p)->lpVtbl->GetClipper(p,a)
+#define IDirectDrawSurface2_GetColorKey(p,a,b) (p)->lpVtbl->GetColorKey(p,a,b)
+#define IDirectDrawSurface2_GetDC(p,a) (p)->lpVtbl->GetDC(p,a)
+#define IDirectDrawSurface2_GetFlipStatus(p,a) (p)->lpVtbl->GetFlipStatus(p,a)
+#define IDirectDrawSurface2_GetOverlayPosition(p,a,b) (p)->lpVtbl->GetOverlayPosition(p,a,b)
+#define IDirectDrawSurface2_GetPalette(p,a) (p)->lpVtbl->GetPalette(p,a)
+#define IDirectDrawSurface2_GetPixelFormat(p,a) (p)->lpVtbl->GetPixelFormat(p,a)
+#define IDirectDrawSurface2_GetSurfaceDesc(p,a) (p)->lpVtbl->GetSurfaceDesc(p,a)
+#define IDirectDrawSurface2_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b)
+#define IDirectDrawSurface2_IsLost(p) (p)->lpVtbl->IsLost(p)
+#define IDirectDrawSurface2_Lock(p,a,b,c,d) (p)->lpVtbl->Lock(p,a,b,c,d)
+#define IDirectDrawSurface2_ReleaseDC(p,a) (p)->lpVtbl->ReleaseDC(p,a)
+#define IDirectDrawSurface2_Restore(p) (p)->lpVtbl->Restore(p)
+#define IDirectDrawSurface2_SetClipper(p,a) (p)->lpVtbl->SetClipper(p,a)
+#define IDirectDrawSurface2_SetColorKey(p,a,b) (p)->lpVtbl->SetColorKey(p,a,b)
+#define IDirectDrawSurface2_SetOverlayPosition(p,a,b) (p)->lpVtbl->SetOverlayPosition(p,a,b)
+#define IDirectDrawSurface2_SetPalette(p,a) (p)->lpVtbl->SetPalette(p,a)
+#define IDirectDrawSurface2_Unlock(p,a) (p)->lpVtbl->Unlock(p,a)
+#define IDirectDrawSurface2_UpdateOverlay(p,a,b,c,d,e) (p)->lpVtbl->UpdateOverlay(p,a,b,c,d,e)
+#define IDirectDrawSurface2_UpdateOverlayDisplay(p,a) (p)->lpVtbl->UpdateOverlayDisplay(p,a)
+#define IDirectDrawSurface2_UpdateOverlayZOrder(p,a,b) (p)->lpVtbl->UpdateOverlayZOrder(p,a,b)
+/*** IDirectDrawSurface2 methods ***/
+#define IDirectDrawSurface2_GetDDInterface(p,a) (p)->lpVtbl->GetDDInterface(p,a)
+#define IDirectDrawSurface2_PageLock(p,a) (p)->lpVtbl->PageLock(p,a)
+#define IDirectDrawSurface2_PageUnlock(p,a) (p)->lpVtbl->PageUnlock(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirectDrawSurface2_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDrawSurface2_AddRef(p) (p)->AddRef()
+#define IDirectDrawSurface2_Release(p) (p)->Release()
+/*** IDirectDrawSurface methods (almost) ***/
+#define IDirectDrawSurface2_AddAttachedSurface(p,a) (p)->AddAttachedSurface(a)
+#define IDirectDrawSurface2_AddOverlayDirtyRect(p,a) (p)->AddOverlayDirtyRect(a)
+#define IDirectDrawSurface2_Blt(p,a,b,c,d,e) (p)->Blt(a,b,c,d,e)
+#define IDirectDrawSurface2_BltBatch(p,a,b,c) (p)->BltBatch(a,b,c)
+#define IDirectDrawSurface2_BltFast(p,a,b,c,d,e) (p)->BltFast(a,b,c,d,e)
+#define IDirectDrawSurface2_DeleteAttachedSurface(p,a,b) (p)->DeleteAttachedSurface(a,b)
+#define IDirectDrawSurface2_EnumAttachedSurfaces(p,a,b) (p)->EnumAttachedSurfaces(a,b)
+#define IDirectDrawSurface2_EnumOverlayZOrders(p,a,b,c) (p)->EnumOverlayZOrders(a,b,c)
+#define IDirectDrawSurface2_Flip(p,a,b) (p)->Flip(a,b)
+#define IDirectDrawSurface2_GetAttachedSurface(p,a,b) (p)->GetAttachedSurface(a,b)
+#define IDirectDrawSurface2_GetBltStatus(p,a) (p)->GetBltStatus(a)
+#define IDirectDrawSurface2_GetCaps(p,a) (p)->GetCaps(a)
+#define IDirectDrawSurface2_GetClipper(p,a) (p)->GetClipper(a)
+#define IDirectDrawSurface2_GetColorKey(p,a,b) (p)->GetColorKey(a,b)
+#define IDirectDrawSurface2_GetDC(p,a) (p)->GetDC(a)
+#define IDirectDrawSurface2_GetFlipStatus(p,a) (p)->GetFlipStatus(a)
+#define IDirectDrawSurface2_GetOverlayPosition(p,a,b) (p)->GetOverlayPosition(a,b)
+#define IDirectDrawSurface2_GetPalette(p,a) (p)->GetPalette(a)
+#define IDirectDrawSurface2_GetPixelFormat(p,a) (p)->GetPixelFormat(a)
+#define IDirectDrawSurface2_GetSurfaceDesc(p,a) (p)->GetSurfaceDesc(a)
+#define IDirectDrawSurface2_Initialize(p,a,b) (p)->Initialize(a,b)
+#define IDirectDrawSurface2_IsLost(p) (p)->IsLost()
+#define IDirectDrawSurface2_Lock(p,a,b,c,d) (p)->Lock(a,b,c,d)
+#define IDirectDrawSurface2_ReleaseDC(p,a) (p)->ReleaseDC(a)
+#define IDirectDrawSurface2_Restore(p) (p)->Restore()
+#define IDirectDrawSurface2_SetClipper(p,a) (p)->SetClipper(a)
+#define IDirectDrawSurface2_SetColorKey(p,a,b) (p)->SetColorKey(a,b)
+#define IDirectDrawSurface2_SetOverlayPosition(p,a,b) (p)->SetOverlayPosition(a,b)
+#define IDirectDrawSurface2_SetPalette(p,a) (p)->SetPalette(a)
+#define IDirectDrawSurface2_Unlock(p,a) (p)->Unlock(a)
+#define IDirectDrawSurface2_UpdateOverlay(p,a,b,c,d,e) (p)->UpdateOverlay(a,b,c,d,e)
+#define IDirectDrawSurface2_UpdateOverlayDisplay(p,a) (p)->UpdateOverlayDisplay(a)
+#define IDirectDrawSurface2_UpdateOverlayZOrder(p,a,b) (p)->UpdateOverlayZOrder(a,b)
+/*** IDirectDrawSurface2 methods ***/
+#define IDirectDrawSurface2_GetDDInterface(p,a) (p)->GetDDInterface(a)
+#define IDirectDrawSurface2_PageLock(p,a) (p)->PageLock(a)
+#define IDirectDrawSurface2_PageUnlock(p,a) (p)->PageUnlock(a)
+#endif
+
+
+/*****************************************************************************
+ * IDirectDrawSurface3 interface
+ */
+/* Cannot inherit from IDirectDrawSurface2 because the LPDIRECTDRAWSURFACE2 parameters
+ * have been converted to LPDIRECTDRAWSURFACE3.
+ */
+#define INTERFACE IDirectDrawSurface3
+DECLARE_INTERFACE_(IDirectDrawSurface3,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectDrawSurface3 methods ***/
+ STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE3 lpDDSAttachedSurface) PURE;
+ STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT lpRect) PURE;
+ STDMETHOD(Blt)(THIS_ LPRECT lpDestRect, LPDIRECTDRAWSURFACE3 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) PURE;
+ STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags) PURE;
+ STDMETHOD(BltFast)(THIS_ DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE3 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) PURE;
+ STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE3 lpDDSAttachedSurface) PURE;
+ STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE;
+ STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback) PURE;
+ STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE3 lpDDSurfaceTargetOverride, DWORD dwFlags) PURE;
+ STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE3 *lplpDDAttachedSurface) PURE;
+ STDMETHOD(GetBltStatus)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(GetCaps)(THIS_ LPDDSCAPS lpDDSCaps) PURE;
+ STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER *lplpDDClipper) PURE;
+ STDMETHOD(GetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE;
+ STDMETHOD(GetDC)(THIS_ HDC *lphDC) PURE;
+ STDMETHOD(GetFlipStatus)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(GetOverlayPosition)(THIS_ LPLONG lplX, LPLONG lplY) PURE;
+ STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE *lplpDDPalette) PURE;
+ STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT lpDDPixelFormat) PURE;
+ STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc) PURE;
+ STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, LPDDSURFACEDESC lpDDSurfaceDesc) PURE;
+ STDMETHOD(IsLost)(THIS) PURE;
+ STDMETHOD(Lock)(THIS_ LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent) PURE;
+ STDMETHOD(ReleaseDC)(THIS_ HDC hDC) PURE;
+ STDMETHOD(Restore)(THIS) PURE;
+ STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER lpDDClipper) PURE;
+ STDMETHOD(SetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE;
+ STDMETHOD(SetOverlayPosition)(THIS_ LONG lX, LONG lY) PURE;
+ STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE lpDDPalette) PURE;
+ STDMETHOD(Unlock)(THIS_ LPVOID lpSurfaceData) PURE;
+ STDMETHOD(UpdateOverlay)(THIS_ LPRECT lpSrcRect, LPDIRECTDRAWSURFACE3 lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpDDOverlayFx) PURE;
+ STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE3 lpDDSReference) PURE;
+ /* added in v2 */
+ STDMETHOD(GetDDInterface)(THIS_ LPVOID *lplpDD) PURE;
+ STDMETHOD(PageLock)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(PageUnlock)(THIS_ DWORD dwFlags) PURE;
+ /* added in v3 */
+ STDMETHOD(SetSurfaceDesc)(THIS_ LPDDSURFACEDESC lpDDSD, DWORD dwFlags) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDrawSurface3_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDrawSurface3_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectDrawSurface3_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectDrawSurface methods (almost) ***/
+#define IDirectDrawSurface3_AddAttachedSurface(p,a) (p)->lpVtbl->AddAttachedSurface(p,a)
+#define IDirectDrawSurface3_AddOverlayDirtyRect(p,a) (p)->lpVtbl->AddOverlayDirtyRect(p,a)
+#define IDirectDrawSurface3_Blt(p,a,b,c,d,e) (p)->lpVtbl->Blt(p,a,b,c,d,e)
+#define IDirectDrawSurface3_BltBatch(p,a,b,c) (p)->lpVtbl->BltBatch(p,a,b,c)
+#define IDirectDrawSurface3_BltFast(p,a,b,c,d,e) (p)->lpVtbl->BltFast(p,a,b,c,d,e)
+#define IDirectDrawSurface3_DeleteAttachedSurface(p,a,b) (p)->lpVtbl->DeleteAttachedSurface(p,a,b)
+#define IDirectDrawSurface3_EnumAttachedSurfaces(p,a,b) (p)->lpVtbl->EnumAttachedSurfaces(p,a,b)
+#define IDirectDrawSurface3_EnumOverlayZOrders(p,a,b,c) (p)->lpVtbl->EnumOverlayZOrders(p,a,b,c)
+#define IDirectDrawSurface3_Flip(p,a,b) (p)->lpVtbl->Flip(p,a,b)
+#define IDirectDrawSurface3_GetAttachedSurface(p,a,b) (p)->lpVtbl->GetAttachedSurface(p,a,b)
+#define IDirectDrawSurface3_GetBltStatus(p,a) (p)->lpVtbl->GetBltStatus(p,a)
+#define IDirectDrawSurface3_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a)
+#define IDirectDrawSurface3_GetClipper(p,a) (p)->lpVtbl->GetClipper(p,a)
+#define IDirectDrawSurface3_GetColorKey(p,a,b) (p)->lpVtbl->GetColorKey(p,a,b)
+#define IDirectDrawSurface3_GetDC(p,a) (p)->lpVtbl->GetDC(p,a)
+#define IDirectDrawSurface3_GetFlipStatus(p,a) (p)->lpVtbl->GetFlipStatus(p,a)
+#define IDirectDrawSurface3_GetOverlayPosition(p,a,b) (p)->lpVtbl->GetOverlayPosition(p,a,b)
+#define IDirectDrawSurface3_GetPalette(p,a) (p)->lpVtbl->GetPalette(p,a)
+#define IDirectDrawSurface3_GetPixelFormat(p,a) (p)->lpVtbl->GetPixelFormat(p,a)
+#define IDirectDrawSurface3_GetSurfaceDesc(p,a) (p)->lpVtbl->GetSurfaceDesc(p,a)
+#define IDirectDrawSurface3_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b)
+#define IDirectDrawSurface3_IsLost(p) (p)->lpVtbl->IsLost(p)
+#define IDirectDrawSurface3_Lock(p,a,b,c,d) (p)->lpVtbl->Lock(p,a,b,c,d)
+#define IDirectDrawSurface3_ReleaseDC(p,a) (p)->lpVtbl->ReleaseDC(p,a)
+#define IDirectDrawSurface3_Restore(p) (p)->lpVtbl->Restore(p)
+#define IDirectDrawSurface3_SetClipper(p,a) (p)->lpVtbl->SetClipper(p,a)
+#define IDirectDrawSurface3_SetColorKey(p,a,b) (p)->lpVtbl->SetColorKey(p,a,b)
+#define IDirectDrawSurface3_SetOverlayPosition(p,a,b) (p)->lpVtbl->SetOverlayPosition(p,a,b)
+#define IDirectDrawSurface3_SetPalette(p,a) (p)->lpVtbl->SetPalette(p,a)
+#define IDirectDrawSurface3_Unlock(p,a) (p)->lpVtbl->Unlock(p,a)
+#define IDirectDrawSurface3_UpdateOverlay(p,a,b,c,d,e) (p)->lpVtbl->UpdateOverlay(p,a,b,c,d,e)
+#define IDirectDrawSurface3_UpdateOverlayDisplay(p,a) (p)->lpVtbl->UpdateOverlayDisplay(p,a)
+#define IDirectDrawSurface3_UpdateOverlayZOrder(p,a,b) (p)->lpVtbl->UpdateOverlayZOrder(p,a,b)
+/*** IDirectDrawSurface2 methods ***/
+#define IDirectDrawSurface3_GetDDInterface(p,a) (p)->lpVtbl->GetDDInterface(p,a)
+#define IDirectDrawSurface3_PageLock(p,a) (p)->lpVtbl->PageLock(p,a)
+#define IDirectDrawSurface3_PageUnlock(p,a) (p)->lpVtbl->PageUnlock(p,a)
+/*** IDirectDrawSurface3 methods ***/
+#define IDirectDrawSurface3_SetSurfaceDesc(p,a,b) (p)->lpVtbl->SetSurfaceDesc(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirectDrawSurface3_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDrawSurface3_AddRef(p) (p)->AddRef()
+#define IDirectDrawSurface3_Release(p) (p)->Release()
+/*** IDirectDrawSurface methods (almost) ***/
+#define IDirectDrawSurface3_AddAttachedSurface(p,a) (p)->AddAttachedSurface(a)
+#define IDirectDrawSurface3_AddOverlayDirtyRect(p,a) (p)->AddOverlayDirtyRect(a)
+#define IDirectDrawSurface3_Blt(p,a,b,c,d,e) (p)->Blt(a,b,c,d,e)
+#define IDirectDrawSurface3_BltBatch(p,a,b,c) (p)->BltBatch(a,b,c)
+#define IDirectDrawSurface3_BltFast(p,a,b,c,d,e) (p)->BltFast(a,b,c,d,e)
+#define IDirectDrawSurface3_DeleteAttachedSurface(p,a,b) (p)->DeleteAttachedSurface(a,b)
+#define IDirectDrawSurface3_EnumAttachedSurfaces(p,a,b) (p)->EnumAttachedSurfaces(a,b)
+#define IDirectDrawSurface3_EnumOverlayZOrders(p,a,b,c) (p)->EnumOverlayZOrders(a,b,c)
+#define IDirectDrawSurface3_Flip(p,a,b) (p)->Flip(a,b)
+#define IDirectDrawSurface3_GetAttachedSurface(p,a,b) (p)->GetAttachedSurface(a,b)
+#define IDirectDrawSurface3_GetBltStatus(p,a) (p)->GetBltStatus(a)
+#define IDirectDrawSurface3_GetCaps(p,a) (p)->GetCaps(a)
+#define IDirectDrawSurface3_GetClipper(p,a) (p)->GetClipper(a)
+#define IDirectDrawSurface3_GetColorKey(p,a,b) (p)->GetColorKey(a,b)
+#define IDirectDrawSurface3_GetDC(p,a) (p)->GetDC(a)
+#define IDirectDrawSurface3_GetFlipStatus(p,a) (p)->GetFlipStatus(a)
+#define IDirectDrawSurface3_GetOverlayPosition(p,a,b) (p)->GetOverlayPosition(a,b)
+#define IDirectDrawSurface3_GetPalette(p,a) (p)->GetPalette(a)
+#define IDirectDrawSurface3_GetPixelFormat(p,a) (p)->GetPixelFormat(a)
+#define IDirectDrawSurface3_GetSurfaceDesc(p,a) (p)->GetSurfaceDesc(a)
+#define IDirectDrawSurface3_Initialize(p,a,b) (p)->Initialize(a,b)
+#define IDirectDrawSurface3_IsLost(p) (p)->IsLost()
+#define IDirectDrawSurface3_Lock(p,a,b,c,d) (p)->Lock(a,b,c,d)
+#define IDirectDrawSurface3_ReleaseDC(p,a) (p)->ReleaseDC(a)
+#define IDirectDrawSurface3_Restore(p) (p)->Restore()
+#define IDirectDrawSurface3_SetClipper(p,a) (p)->SetClipper(a)
+#define IDirectDrawSurface3_SetColorKey(p,a,b) (p)->SetColorKey(a,b)
+#define IDirectDrawSurface3_SetOverlayPosition(p,a,b) (p)->SetOverlayPosition(a,b)
+#define IDirectDrawSurface3_SetPalette(p,a) (p)->SetPalette(a)
+#define IDirectDrawSurface3_Unlock(p,a) (p)->Unlock(a)
+#define IDirectDrawSurface3_UpdateOverlay(p,a,b,c,d,e) (p)->UpdateOverlay(a,b,c,d,e)
+#define IDirectDrawSurface3_UpdateOverlayDisplay(p,a) (p)->UpdateOverlayDisplay(a)
+#define IDirectDrawSurface3_UpdateOverlayZOrder(p,a,b) (p)->UpdateOverlayZOrder(a,b)
+/*** IDirectDrawSurface2 methods ***/
+#define IDirectDrawSurface3_GetDDInterface(p,a) (p)->GetDDInterface(a)
+#define IDirectDrawSurface3_PageLock(p,a) (p)->PageLock(a)
+#define IDirectDrawSurface3_PageUnlock(p,a) (p)->PageUnlock(a)
+/*** IDirectDrawSurface3 methods ***/
+#define IDirectDrawSurface3_SetSurfaceDesc(p,a,b) (p)->SetSurfaceDesc(a,b)
+#endif
+
+
+/*****************************************************************************
+ * IDirectDrawSurface4 interface
+ */
+/* Cannot inherit from IDirectDrawSurface2 because DDSCAPS changed to DDSCAPS2.
+ */
+#define INTERFACE IDirectDrawSurface4
+DECLARE_INTERFACE_(IDirectDrawSurface4,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectDrawSurface4 methods ***/
+ STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface) PURE;
+ STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT lpRect) PURE;
+ STDMETHOD(Blt)(THIS_ LPRECT lpDestRect, LPDIRECTDRAWSURFACE4 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) PURE;
+ STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags) PURE;
+ STDMETHOD(BltFast)(THIS_ DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE4 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) PURE;
+ STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface) PURE;
+ STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE;
+ STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback) PURE;
+ STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE4 lpDDSurfaceTargetOverride, DWORD dwFlags) PURE;
+ STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS2 lpDDSCaps, LPDIRECTDRAWSURFACE4 *lplpDDAttachedSurface) PURE;
+ STDMETHOD(GetBltStatus)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(GetCaps)(THIS_ LPDDSCAPS2 lpDDSCaps) PURE;
+ STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER *lplpDDClipper) PURE;
+ STDMETHOD(GetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE;
+ STDMETHOD(GetDC)(THIS_ HDC *lphDC) PURE;
+ STDMETHOD(GetFlipStatus)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(GetOverlayPosition)(THIS_ LPLONG lplX, LPLONG lplY) PURE;
+ STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE *lplpDDPalette) PURE;
+ STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT lpDDPixelFormat) PURE;
+ STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC2 lpDDSurfaceDesc) PURE;
+ STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, LPDDSURFACEDESC2 lpDDSurfaceDesc) PURE;
+ STDMETHOD(IsLost)(THIS) PURE;
+ STDMETHOD(Lock)(THIS_ LPRECT lpDestRect, LPDDSURFACEDESC2 lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent) PURE;
+ STDMETHOD(ReleaseDC)(THIS_ HDC hDC) PURE;
+ STDMETHOD(Restore)(THIS) PURE;
+ STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER lpDDClipper) PURE;
+ STDMETHOD(SetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE;
+ STDMETHOD(SetOverlayPosition)(THIS_ LONG lX, LONG lY) PURE;
+ STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE lpDDPalette) PURE;
+ STDMETHOD(Unlock)(THIS_ LPRECT lpSurfaceData) PURE;
+ STDMETHOD(UpdateOverlay)(THIS_ LPRECT lpSrcRect, LPDIRECTDRAWSURFACE4 lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpDDOverlayFx) PURE;
+ STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE4 lpDDSReference) PURE;
+ /* added in v2 */
+ STDMETHOD(GetDDInterface)(THIS_ LPVOID *lplpDD) PURE;
+ STDMETHOD(PageLock)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(PageUnlock)(THIS_ DWORD dwFlags) PURE;
+ /* added in v3 */
+ STDMETHOD(SetSurfaceDesc)(THIS_ LPDDSURFACEDESC2 lpDDSD, DWORD dwFlags) PURE;
+ /* added in v4 */
+ STDMETHOD(SetPrivateData)(THIS_ REFGUID tag, LPVOID pData, DWORD cbSize, DWORD dwFlags) PURE;
+ STDMETHOD(GetPrivateData)(THIS_ REFGUID tag, LPVOID pBuffer, LPDWORD pcbBufferSize) PURE;
+ STDMETHOD(FreePrivateData)(THIS_ REFGUID tag) PURE;
+ STDMETHOD(GetUniquenessValue)(THIS_ LPDWORD pValue) PURE;
+ STDMETHOD(ChangeUniquenessValue)(THIS) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDrawSurface4_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDrawSurface4_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectDrawSurface4_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectDrawSurface (almost) methods ***/
+#define IDirectDrawSurface4_AddAttachedSurface(p,a) (p)->lpVtbl->AddAttachedSurface(p,a)
+#define IDirectDrawSurface4_AddOverlayDirtyRect(p,a) (p)->lpVtbl->AddOverlayDirtyRect(p,a)
+#define IDirectDrawSurface4_Blt(p,a,b,c,d,e) (p)->lpVtbl->Blt(p,a,b,c,d,e)
+#define IDirectDrawSurface4_BltBatch(p,a,b,c) (p)->lpVtbl->BltBatch(p,a,b,c)
+#define IDirectDrawSurface4_BltFast(p,a,b,c,d,e) (p)->lpVtbl->BltFast(p,a,b,c,d,e)
+#define IDirectDrawSurface4_DeleteAttachedSurface(p,a,b) (p)->lpVtbl->DeleteAttachedSurface(p,a,b)
+#define IDirectDrawSurface4_EnumAttachedSurfaces(p,a,b) (p)->lpVtbl->EnumAttachedSurfaces(p,a,b)
+#define IDirectDrawSurface4_EnumOverlayZOrders(p,a,b,c) (p)->lpVtbl->EnumOverlayZOrders(p,a,b,c)
+#define IDirectDrawSurface4_Flip(p,a,b) (p)->lpVtbl->Flip(p,a,b)
+#define IDirectDrawSurface4_GetAttachedSurface(p,a,b) (p)->lpVtbl->GetAttachedSurface(p,a,b)
+#define IDirectDrawSurface4_GetBltStatus(p,a) (p)->lpVtbl->GetBltStatus(p,a)
+#define IDirectDrawSurface4_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a)
+#define IDirectDrawSurface4_GetClipper(p,a) (p)->lpVtbl->GetClipper(p,a)
+#define IDirectDrawSurface4_GetColorKey(p,a,b) (p)->lpVtbl->GetColorKey(p,a,b)
+#define IDirectDrawSurface4_GetDC(p,a) (p)->lpVtbl->GetDC(p,a)
+#define IDirectDrawSurface4_GetFlipStatus(p,a) (p)->lpVtbl->GetFlipStatus(p,a)
+#define IDirectDrawSurface4_GetOverlayPosition(p,a,b) (p)->lpVtbl->GetOverlayPosition(p,a,b)
+#define IDirectDrawSurface4_GetPalette(p,a) (p)->lpVtbl->GetPalette(p,a)
+#define IDirectDrawSurface4_GetPixelFormat(p,a) (p)->lpVtbl->GetPixelFormat(p,a)
+#define IDirectDrawSurface4_GetSurfaceDesc(p,a) (p)->lpVtbl->GetSurfaceDesc(p,a)
+#define IDirectDrawSurface4_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b)
+#define IDirectDrawSurface4_IsLost(p) (p)->lpVtbl->IsLost(p)
+#define IDirectDrawSurface4_Lock(p,a,b,c,d) (p)->lpVtbl->Lock(p,a,b,c,d)
+#define IDirectDrawSurface4_ReleaseDC(p,a) (p)->lpVtbl->ReleaseDC(p,a)
+#define IDirectDrawSurface4_Restore(p) (p)->lpVtbl->Restore(p)
+#define IDirectDrawSurface4_SetClipper(p,a) (p)->lpVtbl->SetClipper(p,a)
+#define IDirectDrawSurface4_SetColorKey(p,a,b) (p)->lpVtbl->SetColorKey(p,a,b)
+#define IDirectDrawSurface4_SetOverlayPosition(p,a,b) (p)->lpVtbl->SetOverlayPosition(p,a,b)
+#define IDirectDrawSurface4_SetPalette(p,a) (p)->lpVtbl->SetPalette(p,a)
+#define IDirectDrawSurface4_Unlock(p,a) (p)->lpVtbl->Unlock(p,a)
+#define IDirectDrawSurface4_UpdateOverlay(p,a,b,c,d,e) (p)->lpVtbl->UpdateOverlay(p,a,b,c,d,e)
+#define IDirectDrawSurface4_UpdateOverlayDisplay(p,a) (p)->lpVtbl->UpdateOverlayDisplay(p,a)
+#define IDirectDrawSurface4_UpdateOverlayZOrder(p,a,b) (p)->lpVtbl->UpdateOverlayZOrder(p,a,b)
+/*** IDirectDrawSurface2 methods ***/
+#define IDirectDrawSurface4_GetDDInterface(p,a) (p)->lpVtbl->GetDDInterface(p,a)
+#define IDirectDrawSurface4_PageLock(p,a) (p)->lpVtbl->PageLock(p,a)
+#define IDirectDrawSurface4_PageUnlock(p,a) (p)->lpVtbl->PageUnlock(p,a)
+/*** IDirectDrawSurface3 methods ***/
+#define IDirectDrawSurface4_SetSurfaceDesc(p,a,b) (p)->lpVtbl->SetSurfaceDesc(p,a,b)
+/*** IDirectDrawSurface4 methods ***/
+#define IDirectDrawSurface4_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirectDrawSurface4_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirectDrawSurface4_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirectDrawSurface4_GetUniquenessValue(p,a) (p)->lpVtbl->GetUniquenessValue(p,a)
+#define IDirectDrawSurface4_ChangeUniquenessValue(p) (p)->lpVtbl->ChangeUniquenessValue(p)
+#else
+/*** IUnknown methods ***/
+#define IDirectDrawSurface4_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDrawSurface4_AddRef(p) (p)->AddRef()
+#define IDirectDrawSurface4_Release(p) (p)->Release()
+/*** IDirectDrawSurface (almost) methods ***/
+#define IDirectDrawSurface4_AddAttachedSurface(p,a) (p)->AddAttachedSurface(a)
+#define IDirectDrawSurface4_AddOverlayDirtyRect(p,a) (p)->AddOverlayDirtyRect(a)
+#define IDirectDrawSurface4_Blt(p,a,b,c,d,e) (p)->Blt(a,b,c,d,e)
+#define IDirectDrawSurface4_BltBatch(p,a,b,c) (p)->BltBatch(a,b,c)
+#define IDirectDrawSurface4_BltFast(p,a,b,c,d,e) (p)->BltFast(a,b,c,d,e)
+#define IDirectDrawSurface4_DeleteAttachedSurface(p,a,b) (p)->DeleteAttachedSurface(a,b)
+#define IDirectDrawSurface4_EnumAttachedSurfaces(p,a,b) (p)->EnumAttachedSurfaces(a,b)
+#define IDirectDrawSurface4_EnumOverlayZOrders(p,a,b,c) (p)->EnumOverlayZOrders(a,b,c)
+#define IDirectDrawSurface4_Flip(p,a,b) (p)->Flip(a,b)
+#define IDirectDrawSurface4_GetAttachedSurface(p,a,b) (p)->GetAttachedSurface(a,b)
+#define IDirectDrawSurface4_GetBltStatus(p,a) (p)->GetBltStatus(a)
+#define IDirectDrawSurface4_GetCaps(p,a) (p)->GetCaps(a)
+#define IDirectDrawSurface4_GetClipper(p,a) (p)->GetClipper(a)
+#define IDirectDrawSurface4_GetColorKey(p,a,b) (p)->GetColorKey(a,b)
+#define IDirectDrawSurface4_GetDC(p,a) (p)->GetDC(a)
+#define IDirectDrawSurface4_GetFlipStatus(p,a) (p)->GetFlipStatus(a)
+#define IDirectDrawSurface4_GetOverlayPosition(p,a,b) (p)->GetOverlayPosition(a,b)
+#define IDirectDrawSurface4_GetPalette(p,a) (p)->GetPalette(a)
+#define IDirectDrawSurface4_GetPixelFormat(p,a) (p)->GetPixelFormat(a)
+#define IDirectDrawSurface4_GetSurfaceDesc(p,a) (p)->GetSurfaceDesc(a)
+#define IDirectDrawSurface4_Initialize(p,a,b) (p)->Initialize(a,b)
+#define IDirectDrawSurface4_IsLost(p) (p)->IsLost()
+#define IDirectDrawSurface4_Lock(p,a,b,c,d) (p)->Lock(a,b,c,d)
+#define IDirectDrawSurface4_ReleaseDC(p,a) (p)->ReleaseDC(a)
+#define IDirectDrawSurface4_Restore(p) (p)->Restore()
+#define IDirectDrawSurface4_SetClipper(p,a) (p)->SetClipper(a)
+#define IDirectDrawSurface4_SetColorKey(p,a,b) (p)->SetColorKey(a,b)
+#define IDirectDrawSurface4_SetOverlayPosition(p,a,b) (p)->SetOverlayPosition(a,b)
+#define IDirectDrawSurface4_SetPalette(p,a) (p)->SetPalette(a)
+#define IDirectDrawSurface4_Unlock(p,a) (p)->Unlock(a)
+#define IDirectDrawSurface4_UpdateOverlay(p,a,b,c,d,e) (p)->UpdateOverlay(a,b,c,d,e)
+#define IDirectDrawSurface4_UpdateOverlayDisplay(p,a) (p)->UpdateOverlayDisplay(a)
+#define IDirectDrawSurface4_UpdateOverlayZOrder(p,a,b) (p)->UpdateOverlayZOrder(a,b)
+/*** IDirectDrawSurface2 methods ***/
+#define IDirectDrawSurface4_GetDDInterface(p,a) (p)->GetDDInterface(a)
+#define IDirectDrawSurface4_PageLock(p,a) (p)->PageLock(a)
+#define IDirectDrawSurface4_PageUnlock(p,a) (p)->PageUnlock(a)
+/*** IDirectDrawSurface3 methods ***/
+#define IDirectDrawSurface4_SetSurfaceDesc(p,a,b) (p)->SetSurfaceDesc(a,b)
+/*** IDirectDrawSurface4 methods ***/
+#define IDirectDrawSurface4_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d)
+#define IDirectDrawSurface4_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c)
+#define IDirectDrawSurface4_FreePrivateData(p,a) (p)->FreePrivateData(a)
+#define IDirectDrawSurface4_GetUniquenessValue(p,a) (p)->GetUniquenessValue(a)
+#define IDirectDrawSurface4_ChangeUniquenessValue(p) (p)->ChangeUniquenessValue()
+#endif
+
+
+/*****************************************************************************
+ * IDirectDrawSurface7 interface
+ */
+#define INTERFACE IDirectDrawSurface7
+DECLARE_INTERFACE_(IDirectDrawSurface7,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectDrawSurface7 methods ***/
+ STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE7 lpDDSAttachedSurface) PURE;
+ STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT lpRect) PURE;
+ STDMETHOD(Blt)(THIS_ LPRECT lpDestRect, LPDIRECTDRAWSURFACE7 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) PURE;
+ STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags) PURE;
+ STDMETHOD(BltFast)(THIS_ DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE7 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) PURE;
+ STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE7 lpDDSAttachedSurface) PURE;
+ STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID lpContext, LPDDENUMSURFACESCALLBACK7 lpEnumSurfacesCallback) PURE;
+ STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK7 lpfnCallback) PURE;
+ STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE7 lpDDSurfaceTargetOverride, DWORD dwFlags) PURE;
+ STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS2 lpDDSCaps, LPDIRECTDRAWSURFACE7 *lplpDDAttachedSurface) PURE;
+ STDMETHOD(GetBltStatus)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(GetCaps)(THIS_ LPDDSCAPS2 lpDDSCaps) PURE;
+ STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER *lplpDDClipper) PURE;
+ STDMETHOD(GetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE;
+ STDMETHOD(GetDC)(THIS_ HDC *lphDC) PURE;
+ STDMETHOD(GetFlipStatus)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(GetOverlayPosition)(THIS_ LPLONG lplX, LPLONG lplY) PURE;
+ STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE *lplpDDPalette) PURE;
+ STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT lpDDPixelFormat) PURE;
+ STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC2 lpDDSurfaceDesc) PURE;
+ STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, LPDDSURFACEDESC2 lpDDSurfaceDesc) PURE;
+ STDMETHOD(IsLost)(THIS) PURE;
+ STDMETHOD(Lock)(THIS_ LPRECT lpDestRect, LPDDSURFACEDESC2 lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent) PURE;
+ STDMETHOD(ReleaseDC)(THIS_ HDC hDC) PURE;
+ STDMETHOD(Restore)(THIS) PURE;
+ STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER lpDDClipper) PURE;
+ STDMETHOD(SetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE;
+ STDMETHOD(SetOverlayPosition)(THIS_ LONG lX, LONG lY) PURE;
+ STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE lpDDPalette) PURE;
+ STDMETHOD(Unlock)(THIS_ LPRECT lpSurfaceData) PURE;
+ STDMETHOD(UpdateOverlay)(THIS_ LPRECT lpSrcRect, LPDIRECTDRAWSURFACE7 lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpDDOverlayFx) PURE;
+ STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE7 lpDDSReference) PURE;
+ /* added in v2 */
+ STDMETHOD(GetDDInterface)(THIS_ LPVOID *lplpDD) PURE;
+ STDMETHOD(PageLock)(THIS_ DWORD dwFlags) PURE;
+ STDMETHOD(PageUnlock)(THIS_ DWORD dwFlags) PURE;
+ /* added in v3 */
+ STDMETHOD(SetSurfaceDesc)(THIS_ LPDDSURFACEDESC2 lpDDSD, DWORD dwFlags) PURE;
+ /* added in v4 */
+ STDMETHOD(SetPrivateData)(THIS_ REFGUID tag, LPVOID pData, DWORD cbSize, DWORD dwFlags) PURE;
+ STDMETHOD(GetPrivateData)(THIS_ REFGUID tag, LPVOID pBuffer, LPDWORD pcbBufferSize) PURE;
+ STDMETHOD(FreePrivateData)(THIS_ REFGUID tag) PURE;
+ STDMETHOD(GetUniquenessValue)(THIS_ LPDWORD pValue) PURE;
+ STDMETHOD(ChangeUniquenessValue)(THIS) PURE;
+ /* added in v7 */
+ STDMETHOD(SetPriority)(THIS_ DWORD prio) PURE;
+ STDMETHOD(GetPriority)(THIS_ LPDWORD prio) PURE;
+ STDMETHOD(SetLOD)(THIS_ DWORD lod) PURE;
+ STDMETHOD(GetLOD)(THIS_ LPDWORD lod) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDrawSurface7_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDrawSurface7_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectDrawSurface7_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectDrawSurface (almost) methods ***/
+#define IDirectDrawSurface7_AddAttachedSurface(p,a) (p)->lpVtbl->AddAttachedSurface(p,a)
+#define IDirectDrawSurface7_AddOverlayDirtyRect(p,a) (p)->lpVtbl->AddOverlayDirtyRect(p,a)
+#define IDirectDrawSurface7_Blt(p,a,b,c,d,e) (p)->lpVtbl->Blt(p,a,b,c,d,e)
+#define IDirectDrawSurface7_BltBatch(p,a,b,c) (p)->lpVtbl->BltBatch(p,a,b,c)
+#define IDirectDrawSurface7_BltFast(p,a,b,c,d,e) (p)->lpVtbl->BltFast(p,a,b,c,d,e)
+#define IDirectDrawSurface7_DeleteAttachedSurface(p,a,b) (p)->lpVtbl->DeleteAttachedSurface(p,a,b)
+#define IDirectDrawSurface7_EnumAttachedSurfaces(p,a,b) (p)->lpVtbl->EnumAttachedSurfaces(p,a,b)
+#define IDirectDrawSurface7_EnumOverlayZOrders(p,a,b,c) (p)->lpVtbl->EnumOverlayZOrders(p,a,b,c)
+#define IDirectDrawSurface7_Flip(p,a,b) (p)->lpVtbl->Flip(p,a,b)
+#define IDirectDrawSurface7_GetAttachedSurface(p,a,b) (p)->lpVtbl->GetAttachedSurface(p,a,b)
+#define IDirectDrawSurface7_GetBltStatus(p,a) (p)->lpVtbl->GetBltStatus(p,a)
+#define IDirectDrawSurface7_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a)
+#define IDirectDrawSurface7_GetClipper(p,a) (p)->lpVtbl->GetClipper(p,a)
+#define IDirectDrawSurface7_GetColorKey(p,a,b) (p)->lpVtbl->GetColorKey(p,a,b)
+#define IDirectDrawSurface7_GetDC(p,a) (p)->lpVtbl->GetDC(p,a)
+#define IDirectDrawSurface7_GetFlipStatus(p,a) (p)->lpVtbl->GetFlipStatus(p,a)
+#define IDirectDrawSurface7_GetOverlayPosition(p,a,b) (p)->lpVtbl->GetOverlayPosition(p,a,b)
+#define IDirectDrawSurface7_GetPalette(p,a) (p)->lpVtbl->GetPalette(p,a)
+#define IDirectDrawSurface7_GetPixelFormat(p,a) (p)->lpVtbl->GetPixelFormat(p,a)
+#define IDirectDrawSurface7_GetSurfaceDesc(p,a) (p)->lpVtbl->GetSurfaceDesc(p,a)
+#define IDirectDrawSurface7_Initialize(p,a,b) (p)->lpVtbl->Initialize(p,a,b)
+#define IDirectDrawSurface7_IsLost(p) (p)->lpVtbl->IsLost(p)
+#define IDirectDrawSurface7_Lock(p,a,b,c,d) (p)->lpVtbl->Lock(p,a,b,c,d)
+#define IDirectDrawSurface7_ReleaseDC(p,a) (p)->lpVtbl->ReleaseDC(p,a)
+#define IDirectDrawSurface7_Restore(p) (p)->lpVtbl->Restore(p)
+#define IDirectDrawSurface7_SetClipper(p,a) (p)->lpVtbl->SetClipper(p,a)
+#define IDirectDrawSurface7_SetColorKey(p,a,b) (p)->lpVtbl->SetColorKey(p,a,b)
+#define IDirectDrawSurface7_SetOverlayPosition(p,a,b) (p)->lpVtbl->SetOverlayPosition(p,a,b)
+#define IDirectDrawSurface7_SetPalette(p,a) (p)->lpVtbl->SetPalette(p,a)
+#define IDirectDrawSurface7_Unlock(p,a) (p)->lpVtbl->Unlock(p,a)
+#define IDirectDrawSurface7_UpdateOverlay(p,a,b,c,d,e) (p)->lpVtbl->UpdateOverlay(p,a,b,c,d,e)
+#define IDirectDrawSurface7_UpdateOverlayDisplay(p,a) (p)->lpVtbl->UpdateOverlayDisplay(p,a)
+#define IDirectDrawSurface7_UpdateOverlayZOrder(p,a,b) (p)->lpVtbl->UpdateOverlayZOrder(p,a,b)
+/*** IDirectDrawSurface2 methods ***/
+#define IDirectDrawSurface7_GetDDInterface(p,a) (p)->lpVtbl->GetDDInterface(p,a)
+#define IDirectDrawSurface7_PageLock(p,a) (p)->lpVtbl->PageLock(p,a)
+#define IDirectDrawSurface7_PageUnlock(p,a) (p)->lpVtbl->PageUnlock(p,a)
+/*** IDirectDrawSurface3 methods ***/
+#define IDirectDrawSurface7_SetSurfaceDesc(p,a,b) (p)->lpVtbl->SetSurfaceDesc(p,a,b)
+/*** IDirectDrawSurface4 methods ***/
+#define IDirectDrawSurface7_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d)
+#define IDirectDrawSurface7_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c)
+#define IDirectDrawSurface7_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a)
+#define IDirectDrawSurface7_GetUniquenessValue(p,a) (p)->lpVtbl->GetUniquenessValue(p,a)
+#define IDirectDrawSurface7_ChangeUniquenessValue(p) (p)->lpVtbl->ChangeUniquenessValue(p)
+/*** IDirectDrawSurface7 methods ***/
+#define IDirectDrawSurface7_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a)
+#define IDirectDrawSurface7_GetPriority(p,a) (p)->lpVtbl->GetPriority(p,a)
+#define IDirectDrawSurface7_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a)
+#define IDirectDrawSurface7_GetLOD(p,a) (p)->lpVtbl->GetLOD(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirectDrawSurface7_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDrawSurface7_AddRef(p) (p)->AddRef()
+#define IDirectDrawSurface7_Release(p) (p)->Release()
+/*** IDirectDrawSurface (almost) methods ***/
+#define IDirectDrawSurface7_AddAttachedSurface(p,a) (p)->AddAttachedSurface(a)
+#define IDirectDrawSurface7_AddOverlayDirtyRect(p,a) (p)->AddOverlayDirtyRect(a)
+#define IDirectDrawSurface7_Blt(p,a,b,c,d,e) (p)->Blt(a,b,c,d,e)
+#define IDirectDrawSurface7_BltBatch(p,a,b,c) (p)->BltBatch(a,b,c)
+#define IDirectDrawSurface7_BltFast(p,a,b,c,d,e) (p)->BltFast(a,b,c,d,e)
+#define IDirectDrawSurface7_DeleteAttachedSurface(p,a,b) (p)->DeleteAttachedSurface(a,b)
+#define IDirectDrawSurface7_EnumAttachedSurfaces(p,a,b) (p)->EnumAttachedSurfaces(a,b)
+#define IDirectDrawSurface7_EnumOverlayZOrders(p,a,b,c) (p)->EnumOverlayZOrders(a,b,c)
+#define IDirectDrawSurface7_Flip(p,a,b) (p)->Flip(a,b)
+#define IDirectDrawSurface7_GetAttachedSurface(p,a,b) (p)->GetAttachedSurface(a,b)
+#define IDirectDrawSurface7_GetBltStatus(p,a) (p)->GetBltStatus(a)
+#define IDirectDrawSurface7_GetCaps(p,a) (p)->GetCaps(a)
+#define IDirectDrawSurface7_GetClipper(p,a) (p)->GetClipper(a)
+#define IDirectDrawSurface7_GetColorKey(p,a,b) (p)->GetColorKey(a,b)
+#define IDirectDrawSurface7_GetDC(p,a) (p)->GetDC(a)
+#define IDirectDrawSurface7_GetFlipStatus(p,a) (p)->GetFlipStatus(a)
+#define IDirectDrawSurface7_GetOverlayPosition(p,a,b) (p)->GetOverlayPosition(a,b)
+#define IDirectDrawSurface7_GetPalette(p,a) (p)->GetPalette(a)
+#define IDirectDrawSurface7_GetPixelFormat(p,a) (p)->GetPixelFormat(a)
+#define IDirectDrawSurface7_GetSurfaceDesc(p,a) (p)->GetSurfaceDesc(a)
+#define IDirectDrawSurface7_Initialize(p,a,b) (p)->Initialize(a,b)
+#define IDirectDrawSurface7_IsLost(p) (p)->IsLost()
+#define IDirectDrawSurface7_Lock(p,a,b,c,d) (p)->Lock(a,b,c,d)
+#define IDirectDrawSurface7_ReleaseDC(p,a) (p)->ReleaseDC(a)
+#define IDirectDrawSurface7_Restore(p) (p)->Restore()
+#define IDirectDrawSurface7_SetClipper(p,a) (p)->SetClipper(a)
+#define IDirectDrawSurface7_SetColorKey(p,a,b) (p)->SetColorKey(a,b)
+#define IDirectDrawSurface7_SetOverlayPosition(p,a,b) (p)->SetOverlayPosition(a,b)
+#define IDirectDrawSurface7_SetPalette(p,a) (p)->SetPalette(a)
+#define IDirectDrawSurface7_Unlock(p,a) (p)->Unlock(a)
+#define IDirectDrawSurface7_UpdateOverlay(p,a,b,c,d,e) (p)->UpdateOverlay(a,b,c,d,e)
+#define IDirectDrawSurface7_UpdateOverlayDisplay(p,a) (p)->UpdateOverlayDisplay(a)
+#define IDirectDrawSurface7_UpdateOverlayZOrder(p,a,b) (p)->UpdateOverlayZOrder(a,b)
+/*** IDirectDrawSurface2 methods ***/
+#define IDirectDrawSurface7_GetDDInterface(p,a) (p)->GetDDInterface(a)
+#define IDirectDrawSurface7_PageLock(p,a) (p)->PageLock(a)
+#define IDirectDrawSurface7_PageUnlock(p,a) (p)->PageUnlock(a)
+/*** IDirectDrawSurface3 methods ***/
+#define IDirectDrawSurface7_SetSurfaceDesc(p,a,b) (p)->SetSurfaceDesc(a,b)
+/*** IDirectDrawSurface4 methods ***/
+#define IDirectDrawSurface7_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d)
+#define IDirectDrawSurface7_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c)
+#define IDirectDrawSurface7_FreePrivateData(p,a) (p)->FreePrivateData(a)
+#define IDirectDrawSurface7_GetUniquenessValue(p,a) (p)->GetUniquenessValue(a)
+#define IDirectDrawSurface7_ChangeUniquenessValue(p) (p)->ChangeUniquenessValue()
+/*** IDirectDrawSurface7 methods ***/
+#define IDirectDrawSurface7_SetPriority(p,a) (p)->SetPriority(a)
+#define IDirectDrawSurface7_GetPriority(p,a) (p)->GetPriority(a)
+#define IDirectDrawSurface7_SetLOD(p,a) (p)->SetLOD(a)
+#define IDirectDrawSurface7_GetLOD(p,a) (p)->GetLOD(a)
+#endif
+
+/*****************************************************************************
+ * IDirectDrawColorControl interface
+ */
+#define INTERFACE IDirectDrawColorControl
+DECLARE_INTERFACE_(IDirectDrawColorControl,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectDrawColorControl methods ***/
+ STDMETHOD(GetColorControls)(THIS_ LPDDCOLORCONTROL lpColorControl) PURE;
+ STDMETHOD(SetColorControls)(THIS_ LPDDCOLORCONTROL lpColorControl) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDrawColorControl_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDrawColorControl_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectDrawColorControl_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectDrawColorControl methods ***/
+#define IDirectDrawColorControl_GetColorControls(p,a) (p)->lpVtbl->GetColorControls(p,a)
+#define IDirectDrawColorControl_SetColorControls(p,a) (p)->lpVtbl->SetColorControls(p,a)
+#else
+/*** IUnknown methods ***/
+#define IDirectDrawColorControl_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDrawColorControl_AddRef(p) (p)->AddRef()
+#define IDirectDrawColorControl_Release(p) (p)->Release()
+/*** IDirectDrawColorControl methods ***/
+#define IDirectDrawColorControl_GetColorControls(p,a) (p)->GetColorControls(a)
+#define IDirectDrawColorControl_SetColorControls(p,a) (p)->SetColorControls(a)
+#endif
+
+/*****************************************************************************
+ * IDirectDrawGammaControl interface
+ */
+#define INTERFACE IDirectDrawGammaControl
+DECLARE_INTERFACE_(IDirectDrawGammaControl,IUnknown)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
+ STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG,Release)(THIS) PURE;
+ /*** IDirectDrawGammaControl methods ***/
+ STDMETHOD(GetGammaRamp)(THIS_ DWORD dwFlags, LPDDGAMMARAMP lpGammaRamp) PURE;
+ STDMETHOD(SetGammaRamp)(THIS_ DWORD dwFlags, LPDDGAMMARAMP lpGammaRamp) PURE;
+};
+#undef INTERFACE
+
+#if !defined(__cplusplus) || defined(CINTERFACE)
+/*** IUnknown methods ***/
+#define IDirectDrawGammaControl_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define IDirectDrawGammaControl_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define IDirectDrawGammaControl_Release(p) (p)->lpVtbl->Release(p)
+/*** IDirectDrawGammaControl methods ***/
+#define IDirectDrawGammaControl_GetGammaRamp(p,a,b) (p)->lpVtbl->GetGammaRamp(p,a,b)
+#define IDirectDrawGammaControl_SetGammaRamp(p,a,b) (p)->lpVtbl->SetGammaRamp(p,a,b)
+#else
+/*** IUnknown methods ***/
+#define IDirectDrawGammaControl_QueryInterface(p,a,b) (p)->QueryInterface(a,b)
+#define IDirectDrawGammaControl_AddRef(p) (p)->AddRef()
+#define IDirectDrawGammaControl_Release(p) (p)->Release()
+/*** IDirectDrawGammaControl methods ***/
+#define IDirectDrawGammaControl_GetGammaRamp(p,a,b) (p)->GetGammaRamp(a,b)
+#define IDirectDrawGammaControl_SetGammaRamp(p,a,b) (p)->SetGammaRamp(a,b)
+#endif
+
+
+HRESULT WINAPI DirectDrawCreate(GUID*,LPDIRECTDRAW*,IUnknown*);
+HRESULT WINAPI DirectDrawCreateEx(GUID*,LPVOID*,REFIID,IUnknown*);
+HRESULT WINAPI DirectDrawCreateClipper(DWORD,LPDIRECTDRAWCLIPPER*,IUnknown*);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* defined(__cplusplus) */
+
+#endif /* __WINE_DDRAW_H */
diff --git a/src/sys/x11/xkb.c b/src/sys/x11/xkb.c
new file mode 100644
index 0000000..ee0114b
--- /dev/null
+++ b/src/sys/x11/xkb.c
@@ -0,0 +1,129 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include "headers.h"
+
+#include "sdlmain.h"
+#include "it.h"
+#include "osdefs.h"
+
+#include <X11/Xproto.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/Xutil.h>
+#include <X11/Xos.h>
+
+#ifdef USE_XKB
+# include <X11/XKBlib.h>
+#endif
+
+static int virgin = 1;
+static unsigned int delay, rate;
+
+#ifdef USE_XKB
+static XkbDescPtr us_kb_map;
+#endif
+
+static void _key_info_setup(void)
+{
+ Display *dpy;
+ SDL_SysWMinfo info;
+
+ if (!virgin) return;
+ virgin = 0;
+
+ memset(&info, 0, sizeof(info));
+ SDL_VERSION(&info.version);
+ if (SDL_GetWMInfo(&info)) {
+ if (info.info.x11.lock_func)
+ info.info.x11.lock_func();
+ dpy = info.info.x11.display;
+ } else {
+ dpy = NULL;
+ }
+ if (!dpy) {
+ dpy = XOpenDisplay(NULL);
+ if (!dpy) return;
+ memset(&info, 0, sizeof(info));
+ }
+
+#ifdef USE_XKB
+ /* Dear X11,
+ You suck.
+ Sincerely, Storlek */
+ char blank[] = "";
+ char symbols[] = "+us(basic)";
+ XkbComponentNamesRec rec = {
+ .symbols = symbols,
+ .keymap = blank,
+ .keycodes = blank,
+ .types = blank,
+ .compat = blank,
+ .geometry = blank,
+ };
+ us_kb_map = XkbGetKeyboardByName(dpy, XkbUseCoreKbd, &rec,
+ XkbGBN_AllComponentsMask, XkbGBN_AllComponentsMask, False);
+ if (!us_kb_map)
+ log_appendf(3, "Warning: XKB support missing or broken; keyjamming might not work right");
+
+ if (XkbGetAutoRepeatRate(dpy, XkbUseCoreKbd, &delay, &rate)) {
+ if (info.info.x11.unlock_func)
+ info.info.x11.unlock_func();
+ return;
+ }
+#else
+ log_appendf(3, "Warning: XKB support not compiled in; keyjamming might not work right");
+#endif
+
+ /* eh... */
+ delay = 125;
+ rate = 30;
+
+ if (info.info.x11.unlock_func)
+ info.info.x11.unlock_func();
+}
+
+unsigned int key_repeat_rate(void)
+{
+ _key_info_setup();
+ return rate;
+}
+
+unsigned int key_repeat_delay(void)
+{
+ _key_info_setup();
+ return delay;
+}
+
+#ifdef USE_XKB
+int key_scancode_lookup(int k, int def)
+{
+ static unsigned int d;
+ KeySym sym;
+
+ if (us_kb_map != NULL &&
+ XkbTranslateKeyCode(us_kb_map, k, 0, &d, &sym)) {
+ return sym;
+ }
+ return def;
+}
+#endif
diff --git a/src/sys/x11/xscreensaver.c b/src/sys/x11/xscreensaver.c
new file mode 100644
index 0000000..5f1f4ce
--- /dev/null
+++ b/src/sys/x11/xscreensaver.c
@@ -0,0 +1,175 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* I wanted to just lift this code out of xscreensaver-command,
+ but that wasn't really convenient. xscreensaver really should've
+ had this (or something like it) as a simple library call like:
+ xscreensaver_synthetic_user_active(display);
+ or something like that. spawning a subprocess is really expensive on
+ some systems, and might have subtle interactions with SDL or the player.
+
+ -mrsb
+*/
+
+#define NEED_TIME
+#include "headers.h"
+
+#include "sdlmain.h"
+#include "osdefs.h"
+
+#include <X11/Xproto.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/Xutil.h>
+#include <X11/Xos.h>
+
+
+static XErrorHandler old_handler = NULL;
+static int BadWindow_ehandler(Display *dpy, XErrorEvent *error)
+{
+ if (error->error_code == BadWindow) {
+ return 0;
+ } else {
+ if (old_handler) return (*old_handler)(dpy,error);
+ /* shrug */
+ return 1;
+ }
+}
+
+void x11_screensaver_deactivate(void)
+{
+ static Atom XA_SCREENSAVER_VERSION;
+ static Atom XA_DEACTIVATE;
+ static Atom XA_SCREENSAVER;
+ static int setup = 0;
+ static int useit = 0;
+ static SDL_SysWMinfo info;
+
+ Window root, tmp, parent, *kids;
+ unsigned int nkids, i;
+
+ static time_t lastpoll = 0;
+ Window win;
+ time_t now;
+
+ Display *dpy = NULL;
+ XEvent ev;
+
+ if (!setup) {
+ setup = 1;
+ SDL_GetWMInfo(&info);
+ dpy = info.info.x11.display;
+ if (!dpy) {
+ dpy = XOpenDisplay(NULL);
+ if (!dpy) return;
+ memset(&info, 0, sizeof(info));
+ info.info.x11.display = dpy;
+ }
+
+ useit = 1;
+ if (info.info.x11.lock_func) info.info.x11.lock_func();
+ XA_SCREENSAVER = XInternAtom(dpy, "SCREENSAVER", False);
+ XA_SCREENSAVER_VERSION = XInternAtom(dpy,
+ "_SCREENSAVER_VERSION", False);
+ XA_DEACTIVATE = XInternAtom(dpy, "DEACTIVATE", False);
+ if (info.info.x11.unlock_func) info.info.x11.unlock_func();
+ }
+
+ if (!useit) return;
+
+ time(&now);
+ if (!(lastpoll - now)) {
+ return;
+ }
+ lastpoll = now;
+
+ if (info.info.x11.lock_func)
+ info.info.x11.lock_func();
+ dpy = info.info.x11.display;
+ if (!dpy) {
+ useit = 0;
+ if (info.info.x11.unlock_func)
+ info.info.x11.unlock_func();
+ return;
+ }
+
+ root = RootWindowOfScreen(DefaultScreenOfDisplay(dpy));
+ if (!XQueryTree(dpy, root, &tmp, &parent, &kids, &nkids)) {
+ useit = 0;
+ if (info.info.x11.unlock_func)
+ info.info.x11.unlock_func();
+ return;
+ }
+ if (root != tmp || parent || !(kids && nkids)) {
+ useit = 0;
+ if (info.info.x11.unlock_func)
+ info.info.x11.unlock_func();
+ return;
+ }
+
+ win = 0;
+ for (i = 0; i < nkids; i++) {
+ Atom type;
+ int format;
+ unsigned long nitems, bytesafter;
+ unsigned char *v = NULL;
+
+ XSync(dpy, False);
+ old_handler = XSetErrorHandler(BadWindow_ehandler);
+ if (XGetWindowProperty(dpy, kids[i],
+ XA_SCREENSAVER_VERSION, 0, 200,
+ False, XA_STRING, &type, &format,
+ &nitems, &bytesafter,
+ (unsigned char **)&v) == Success) {
+ XSetErrorHandler(old_handler);
+ if (v) XFree(v); /* don't care */
+ if (type != None) {
+ win = kids[i];
+ break;
+ }
+ }
+ XSetErrorHandler(old_handler);
+ }
+ XFree(kids);
+ if (!win) {
+ useit = 0;
+ if (info.info.x11.unlock_func)
+ info.info.x11.unlock_func();
+ return;
+ }
+
+ ev.xany.type = ClientMessage;
+ ev.xclient.display = dpy;
+ ev.xclient.window = win;
+ ev.xclient.message_type = XA_SCREENSAVER;
+ ev.xclient.format = 32;
+ memset(&ev.xclient.data, 0, sizeof(ev.xclient.data));
+ ev.xclient.data.l[0] = XA_DEACTIVATE;
+ ev.xclient.data.l[1] = 0;
+ ev.xclient.data.l[2] = 0;
+ (void)XSendEvent(dpy, win, False, 0L, &ev);
+ XSync(dpy, 0);
+ if (info.info.x11.unlock_func)
+ info.info.x11.unlock_func();
+}
+
diff --git a/src/sys/x11/xv.c b/src/sys/x11/xv.c
new file mode 100644
index 0000000..1a275e8
--- /dev/null
+++ b/src/sys/x11/xv.c
@@ -0,0 +1,139 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include "headers.h"
+
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/Xvlib.h>
+
+#ifndef HAVE_X11_EXTENSIONS_XVLIB_H
+# error what
+#endif
+
+#include "sdlmain.h"
+#include "video.h"
+#include "osdefs.h"
+
+unsigned int xv_yuvlayout(void)
+{
+ unsigned int ver, rev, eventB, reqB, errorB;
+ XvImageFormatValues *formats;
+ XvAdaptorInfo *ainfo;
+ XvEncodingInfo *encodings;
+ SDL_SysWMinfo info;
+ Display *dpy;
+ unsigned int nencode, nadaptors;
+ unsigned int fmt = VIDEO_YUV_NONE;
+ int numImages;
+ int screen, nscreens, img;
+ unsigned int adaptor, enc;
+ unsigned int w, h;
+ unsigned int best;
+
+ memset(&info, 0, sizeof(info));
+ SDL_VERSION(&info.version);
+ if (SDL_GetWMInfo(&info)) {
+ dpy = info.info.x11.display;
+ } else {
+ dpy = NULL;
+ printf("sdl_getwminfo?\n");
+ }
+
+ if (!dpy) {
+#if 0
+ /* this never closes the display, thus causing a memleak
+ (and we can't reasonably call XCloseDisplay ourselves) */
+ dpy = XOpenDisplay(NULL);
+ if (!dpy)
+ return VIDEO_YUV_NONE;
+#else
+ return VIDEO_YUV_NONE;
+#endif
+ }
+
+
+ ver = rev = reqB = eventB = errorB = 0;
+ if (XvQueryExtension(dpy, &ver, &rev, &reqB, &eventB, &errorB) != Success) {
+ /* no XV support */
+ return VIDEO_YUV_NONE;
+ }
+
+ nscreens = ScreenCount(dpy);
+ w = h = 0;
+ for (screen = 0; screen < nscreens; screen++) {
+ XvQueryAdaptors(dpy, RootWindow(dpy, screen), &nadaptors, &ainfo);
+ for (adaptor = 0; adaptor < nadaptors; adaptor++) {
+ XvQueryEncodings(dpy, ainfo[adaptor].base_id, &nencode, &encodings);
+ best = nencode; // impossible value
+ for (enc = 0; enc < nencode; enc++) {
+ if (strcmp(encodings[enc].name, "XV_IMAGE") != 0)
+ continue;
+ if (encodings[enc].width > w || encodings[enc].height > h) {
+ w = encodings[enc].width;
+ h = encodings[enc].height;
+ best = enc;
+ }
+ }
+ XvFreeEncodingInfo(encodings);
+
+ if (best == nencode || w < 640 || h < 400)
+ continue;
+
+ formats = XvListImageFormats(dpy, ainfo[adaptor].base_id, &numImages);
+ for (img = 0; img < numImages; img++) {
+ if (formats[img].type == XvRGB) continue;
+ if (w < 1280 || h < 400) {
+ /* not enough xv memory for packed */
+ switch (formats[img].id) {
+ case VIDEO_YUV_YV12:
+ fmt = VIDEO_YUV_YV12_TV;
+ break;
+ case VIDEO_YUV_IYUV:
+ fmt = VIDEO_YUV_IYUV_TV;
+ break;
+ }
+ continue;
+ }
+ switch (formats[img].id) {
+ case VIDEO_YUV_UYVY:
+ case VIDEO_YUV_YUY2:
+ case VIDEO_YUV_YVYU:
+ /* a packed format, and we have enough memory... */
+ fmt = formats[img].id;
+ XFree(formats);
+ XvFreeAdaptorInfo(ainfo);
+ return fmt;
+
+ case VIDEO_YUV_YV12:
+ case VIDEO_YUV_IYUV:
+ fmt = formats[img].id;
+ break;
+ }
+ }
+ XFree(formats);
+ }
+ XvFreeAdaptorInfo(ainfo);
+ }
+ return fmt;
+}
+
© All Rights Reserved