From 223879d264009f4678803651f885214f84606cb7 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Thu, 28 May 2009 18:26:13 +0000 Subject: Add droplay example program from /research, adapted to work with OPL library. Subversion-branch: /branches/opl-branch Subversion-revision: 1535 --- opl/examples/Makefile.am | 8 +++ opl/examples/droplay.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+) create mode 100644 opl/examples/Makefile.am create mode 100644 opl/examples/droplay.c (limited to 'opl/examples') diff --git a/opl/examples/Makefile.am b/opl/examples/Makefile.am new file mode 100644 index 00000000..3dc07d46 --- /dev/null +++ b/opl/examples/Makefile.am @@ -0,0 +1,8 @@ + +AM_CFLAGS = -I.. + +noinst_PROGRAMS=droplay + +droplay_LDADD = ../libopl.a @LDFLAGS@ @SDL_LIBS@ +droplay_SOURCES = droplay.c + diff --git a/opl/examples/droplay.c b/opl/examples/droplay.c new file mode 100644 index 00000000..7cd595e9 --- /dev/null +++ b/opl/examples/droplay.c @@ -0,0 +1,177 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright(C) 2009 Simon Howard +// +// 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. +// +// DESCRIPTION: +// Demonstration program for OPL library to play back DRO +// format files. +// +//----------------------------------------------------------------------------- + + +#include +#include + +#include "SDL.h" + +#include "opl.h" + +#define HEADER_STRING "DBRAWOPL" +#define ADLIB_PORT 0x388 + +void WriteReg(unsigned int reg, unsigned int val) +{ + int i; + + OPL_WritePort(OPL_REGISTER_PORT, reg); + + for (i=0; i<6; ++i) + { + OPL_ReadPort(OPL_REGISTER_PORT); + } + + OPL_WritePort(OPL_DATA_PORT, val); + + for (i=0; i<35; ++i) + { + OPL_ReadPort(OPL_REGISTER_PORT); + } +} + +void ClearAllRegs(void) +{ + int i; + + for (i=0; i<=0xff; ++i) + { + WriteReg(i, 0x00); + } +} + +// Detect an OPL chip. + +int DetectOPL(void) +{ + WriteReg(OPL_REG_TIMER_CTRL, 0x60); + WriteReg(OPL_REG_TIMER_CTRL, 0x80); + int val1 = OPL_ReadPort(OPL_REGISTER_PORT) & 0xe0; + WriteReg(OPL_REG_TIMER1, 0xff); + WriteReg(OPL_REG_TIMER_CTRL, 0x21); + SDL_Delay(50); + int val2 = OPL_ReadPort(OPL_REGISTER_PORT) & 0xe0; + WriteReg(OPL_REG_TIMER_CTRL, 0x60); + WriteReg(OPL_REG_TIMER_CTRL, 0x80); + + return val1 != 0 || val2 != 0xc0; +} + +void Init(void) +{ + if (SDL_Init(SDL_INIT_TIMER) < 0) + { + fprintf(stderr, "Unable to initialise SDL timer\n"); + exit(-1); + } + + if (!OPL_Init(ADLIB_PORT)) + { + fprintf(stderr, "Unable to initialise OPL layer\n"); + exit(-1); + } + + if (!DetectOPL()) + { + fprintf(stderr, "Adlib not detected\n"); + exit(-1); + } +} + +void Shutdown(void) +{ + OPL_Shutdown(); +} + +void PlayFile(char *filename) +{ + FILE *stream; + char buf[8]; + + stream = fopen(filename, "rb"); + + if (fread(buf, 1, 8, stream) < 8) + { + fprintf(stderr, "failed to read raw OPL header\n"); + exit(-1); + } + + if (strncmp(buf, HEADER_STRING, 8) != 0) + { + fprintf(stderr, "Raw OPL header not found\n"); + exit(-1); + } + + fseek(stream, 28, SEEK_SET); + + while (!feof(stream)) + { + int reg, val; + + reg = fgetc(stream); + val = fgetc(stream); + + // Delay? + + if (reg == 0x00) + { + SDL_Delay(val); + } + else if (reg == 0x01) + { + val |= (fgetc(stream) << 8); + SDL_Delay(val); + } + else + { + WriteReg(reg, val); + } + } + + fclose(stream); +} + +int main(int argc, char *argv[]) +{ + if (argc < 2) + { + printf("Usage: %s \n", argv[0]); + exit(-1); + } + + Init(); + ClearAllRegs(); + SDL_Delay(1000); + + PlayFile(argv[1]); + + ClearAllRegs(); + Shutdown(); + + return 0; +} + -- cgit v1.2.3 From b695843cc549e3de4845e340c611efb0ae98866c Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Thu, 28 May 2009 18:34:05 +0000 Subject: Fix OPL detect. Subversion-branch: /branches/opl-branch Subversion-revision: 1536 --- opl/examples/droplay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'opl/examples') diff --git a/opl/examples/droplay.c b/opl/examples/droplay.c index 7cd595e9..af1a59d9 100644 --- a/opl/examples/droplay.c +++ b/opl/examples/droplay.c @@ -78,7 +78,7 @@ int DetectOPL(void) WriteReg(OPL_REG_TIMER_CTRL, 0x60); WriteReg(OPL_REG_TIMER_CTRL, 0x80); - return val1 != 0 || val2 != 0xc0; + return val1 == 0 && val2 == 0xc0; } void Init(void) -- cgit v1.2.3 From 6e4f6ab9626d81e4106d3ccc974a76d832fdff13 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Thu, 28 May 2009 18:37:31 +0000 Subject: Set channel bits for OPL3 so that OPL2 traces will play back properly. Subversion-branch: /branches/opl-branch Subversion-revision: 1537 --- opl/examples/droplay.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'opl/examples') diff --git a/opl/examples/droplay.c b/opl/examples/droplay.c index af1a59d9..5f09fe11 100644 --- a/opl/examples/droplay.c +++ b/opl/examples/droplay.c @@ -39,6 +39,15 @@ void WriteReg(unsigned int reg, unsigned int val) { int i; + // This was recorded from an OPL2, but we are probably playing + // back on an OPL3, so we need to enable the original OPL2 + // channels. Doom does this already, but other games don't. + + if ((reg & 0xf0) == OPL_REGS_FEEDBACK) + { + val |= 0x30; + } + OPL_WritePort(OPL_REGISTER_PORT, reg); for (i=0; i<6; ++i) -- cgit v1.2.3 From 98ee23f4268dbb1395aa0b2cbfad9f53d1092b33 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 30 May 2009 23:24:11 +0000 Subject: Add initial callback/timer API. Subversion-branch: /branches/opl-branch Subversion-revision: 1538 --- opl/examples/.gitignore | 5 +++ opl/examples/droplay.c | 94 +++++++++++++++++++++++++++++++++++++------------ 2 files changed, 77 insertions(+), 22 deletions(-) create mode 100644 opl/examples/.gitignore (limited to 'opl/examples') diff --git a/opl/examples/.gitignore b/opl/examples/.gitignore new file mode 100644 index 00000000..49bb1af8 --- /dev/null +++ b/opl/examples/.gitignore @@ -0,0 +1,5 @@ +Makefile.in +Makefile +.deps +droplay + diff --git a/opl/examples/droplay.c b/opl/examples/droplay.c index 5f09fe11..89cf6862 100644 --- a/opl/examples/droplay.c +++ b/opl/examples/droplay.c @@ -116,44 +116,51 @@ void Shutdown(void) OPL_Shutdown(); } -void PlayFile(char *filename) +struct timer_data { - FILE *stream; - char buf[8]; - - stream = fopen(filename, "rb"); + int running; + FILE *fstream; +}; - if (fread(buf, 1, 8, stream) < 8) - { - fprintf(stderr, "failed to read raw OPL header\n"); - exit(-1); - } +void TimerCallback(void *data) +{ + struct timer_data *timer_data = data; + int delay; - if (strncmp(buf, HEADER_STRING, 8) != 0) + if (!timer_data->running) { - fprintf(stderr, "Raw OPL header not found\n"); - exit(-1); + return; } - fseek(stream, 28, SEEK_SET); + // Read data until we must make a delay. - while (!feof(stream)) + for (;;) { int reg, val; - reg = fgetc(stream); - val = fgetc(stream); + // End of file? - // Delay? + if (feof(timer_data->fstream)) + { + timer_data->running = 0; + return; + } + + reg = fgetc(timer_data->fstream); + val = fgetc(timer_data->fstream); + + // Register value of 0 or 1 indicates a delay. if (reg == 0x00) { - SDL_Delay(val); + delay = val; + break; } else if (reg == 0x01) { - val |= (fgetc(stream) << 8); - SDL_Delay(val); + val |= (fgetc(timer_data->fstream) << 8); + delay = val; + break; } else { @@ -161,7 +168,50 @@ void PlayFile(char *filename) } } - fclose(stream); + // Schedule the next timer callback. + + OPL_SetCallback(delay, TimerCallback, timer_data); +} + +void PlayFile(char *filename) +{ + struct timer_data timer_data; + int running; + char buf[8]; + + timer_data.fstream = fopen(filename, "rb"); + + if (fread(buf, 1, 8, timer_data.fstream) < 8) + { + fprintf(stderr, "failed to read raw OPL header\n"); + exit(-1); + } + + if (strncmp(buf, HEADER_STRING, 8) != 0) + { + fprintf(stderr, "Raw OPL header not found\n"); + exit(-1); + } + + fseek(timer_data.fstream, 28, SEEK_SET); + timer_data.running = 1; + + // Start callback loop sequence. + + OPL_SetCallback(0, TimerCallback, &timer_data); + + // Sleep until the playback finishes. + + do + { + OPL_Lock(); + running = timer_data.running; + OPL_Unlock(); + + SDL_Delay(100); + } while (running); + + fclose(timer_data.fstream); } int main(int argc, char *argv[]) -- cgit v1.2.3 From e33a4961331301b1e3a5c65d148050fa33c4c594 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 28 Aug 2009 18:04:04 +0000 Subject: Working SDL OPL driver. Subversion-branch: /branches/opl-branch Subversion-revision: 1632 --- opl/examples/Makefile.am | 2 +- opl/examples/droplay.c | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'opl/examples') diff --git a/opl/examples/Makefile.am b/opl/examples/Makefile.am index 3dc07d46..7c2c7c8a 100644 --- a/opl/examples/Makefile.am +++ b/opl/examples/Makefile.am @@ -3,6 +3,6 @@ AM_CFLAGS = -I.. noinst_PROGRAMS=droplay -droplay_LDADD = ../libopl.a @LDFLAGS@ @SDL_LIBS@ +droplay_LDADD = ../libopl.a @LDFLAGS@ @SDL_LIBS@ @SDLMIXER_LIBS@ droplay_SOURCES = droplay.c diff --git a/opl/examples/droplay.c b/opl/examples/droplay.c index 89cf6862..5158fbcd 100644 --- a/opl/examples/droplay.c +++ b/opl/examples/droplay.c @@ -77,16 +77,20 @@ void ClearAllRegs(void) int DetectOPL(void) { + int val1, val2; + WriteReg(OPL_REG_TIMER_CTRL, 0x60); WriteReg(OPL_REG_TIMER_CTRL, 0x80); - int val1 = OPL_ReadPort(OPL_REGISTER_PORT) & 0xe0; + val1 = OPL_ReadPort(OPL_REGISTER_PORT) & 0xe0; WriteReg(OPL_REG_TIMER1, 0xff); WriteReg(OPL_REG_TIMER_CTRL, 0x21); - SDL_Delay(50); - int val2 = OPL_ReadPort(OPL_REGISTER_PORT) & 0xe0; + OPL_Delay(50); + val2 = OPL_ReadPort(OPL_REGISTER_PORT) & 0xe0; WriteReg(OPL_REG_TIMER_CTRL, 0x60); WriteReg(OPL_REG_TIMER_CTRL, 0x80); +// Temporary hack for SDL driver. +return 1; return val1 == 0 && val2 == 0xc0; } -- cgit v1.2.3 From ca065a06caac9ba5fab3eb8b1f49d529755506db Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 29 Aug 2009 20:08:21 +0000 Subject: Set timer callback for OPL emulator so that the adlib detection routine works. Subversion-branch: /branches/opl-branch Subversion-revision: 1633 --- opl/examples/droplay.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'opl/examples') diff --git a/opl/examples/droplay.c b/opl/examples/droplay.c index 5158fbcd..b1656815 100644 --- a/opl/examples/droplay.c +++ b/opl/examples/droplay.c @@ -89,8 +89,6 @@ int DetectOPL(void) WriteReg(OPL_REG_TIMER_CTRL, 0x60); WriteReg(OPL_REG_TIMER_CTRL, 0x80); -// Temporary hack for SDL driver. -return 1; return val1 == 0 && val2 == 0xc0; } -- cgit v1.2.3 From e7262d2a8859501152ef22bc7cb9dcc26b05c402 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 29 Aug 2009 20:12:49 +0000 Subject: Fix crash when specifying an invalid filename. Subversion-branch: /branches/opl-branch Subversion-revision: 1634 --- opl/examples/droplay.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'opl/examples') diff --git a/opl/examples/droplay.c b/opl/examples/droplay.c index b1656815..4c2fc2f8 100644 --- a/opl/examples/droplay.c +++ b/opl/examples/droplay.c @@ -183,6 +183,12 @@ void PlayFile(char *filename) timer_data.fstream = fopen(filename, "rb"); + if (timer_data.fstream == NULL) + { + fprintf(stderr, "Failed to open %s\n", filename); + exit(-1); + } + if (fread(buf, 1, 8, timer_data.fstream) < 8) { fprintf(stderr, "failed to read raw OPL header\n"); @@ -226,7 +232,6 @@ int main(int argc, char *argv[]) Init(); ClearAllRegs(); - SDL_Delay(1000); PlayFile(argv[1]); -- cgit v1.2.3 From a10180a460f6425cd308719584aa58ab4fcb63fb Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 29 Aug 2009 21:26:43 +0000 Subject: Use OPL_Delay to wait 1ms for timer to expire when doing OPL detect. Subversion-branch: /branches/opl-branch Subversion-revision: 1638 --- opl/examples/droplay.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'opl/examples') diff --git a/opl/examples/droplay.c b/opl/examples/droplay.c index 4c2fc2f8..d53a427b 100644 --- a/opl/examples/droplay.c +++ b/opl/examples/droplay.c @@ -81,11 +81,16 @@ int DetectOPL(void) WriteReg(OPL_REG_TIMER_CTRL, 0x60); WriteReg(OPL_REG_TIMER_CTRL, 0x80); + val1 = OPL_ReadPort(OPL_REGISTER_PORT) & 0xe0; + WriteReg(OPL_REG_TIMER1, 0xff); WriteReg(OPL_REG_TIMER_CTRL, 0x21); - OPL_Delay(50); + + OPL_Delay(1); + val2 = OPL_ReadPort(OPL_REGISTER_PORT) & 0xe0; + WriteReg(OPL_REG_TIMER_CTRL, 0x60); WriteReg(OPL_REG_TIMER_CTRL, 0x80); -- cgit v1.2.3 From dce2c95f05b8f5ed734d1a1b75ccd7bfb2260557 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 26 Sep 2009 23:52:41 +0000 Subject: Move register read/write code into OPL library. Detect OPL in the library code, so that we fall back to software emulation if we have port access but an OPL is not detected. Fix detection of ioperm in configure. Subversion-branch: /branches/opl-branch Subversion-revision: 1692 --- opl/examples/droplay.c | 31 ------------------------------- 1 file changed, 31 deletions(-) (limited to 'opl/examples') diff --git a/opl/examples/droplay.c b/opl/examples/droplay.c index d53a427b..36f5c3c0 100644 --- a/opl/examples/droplay.c +++ b/opl/examples/droplay.c @@ -73,30 +73,6 @@ void ClearAllRegs(void) } } -// Detect an OPL chip. - -int DetectOPL(void) -{ - int val1, val2; - - WriteReg(OPL_REG_TIMER_CTRL, 0x60); - WriteReg(OPL_REG_TIMER_CTRL, 0x80); - - val1 = OPL_ReadPort(OPL_REGISTER_PORT) & 0xe0; - - WriteReg(OPL_REG_TIMER1, 0xff); - WriteReg(OPL_REG_TIMER_CTRL, 0x21); - - OPL_Delay(1); - - val2 = OPL_ReadPort(OPL_REGISTER_PORT) & 0xe0; - - WriteReg(OPL_REG_TIMER_CTRL, 0x60); - WriteReg(OPL_REG_TIMER_CTRL, 0x80); - - return val1 == 0 && val2 == 0xc0; -} - void Init(void) { if (SDL_Init(SDL_INIT_TIMER) < 0) @@ -110,12 +86,6 @@ void Init(void) fprintf(stderr, "Unable to initialise OPL layer\n"); exit(-1); } - - if (!DetectOPL()) - { - fprintf(stderr, "Adlib not detected\n"); - exit(-1); - } } void Shutdown(void) @@ -236,7 +206,6 @@ int main(int argc, char *argv[]) } Init(); - ClearAllRegs(); PlayFile(argv[1]); -- cgit v1.2.3