aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorEugene Sandulenko2009-02-15 10:10:23 +0000
committerEugene Sandulenko2009-02-15 10:10:23 +0000
commitc399437479e8489da3d3bd64bcfbd1446ee44a7d (patch)
tree69032cb89fea770581a09130e5f0f4018056084f /engines
parent3fb25cf100abb955f7dda5a27066af2993039cc9 (diff)
downloadscummvm-rg350-c399437479e8489da3d3bd64bcfbd1446ee44a7d.tar.gz
scummvm-rg350-c399437479e8489da3d3bd64bcfbd1446ee44a7d.tar.bz2
scummvm-rg350-c399437479e8489da3d3bd64bcfbd1446ee44a7d.zip
- Remove unneeded files
- Make whole thing finally compilable svn-id: r38214
Diffstat (limited to 'engines')
-rw-r--r--engines/sci/engine/kemu_old.c330
-rw-r--r--engines/sci/engine/simplesaid.c312
-rw-r--r--engines/sci/gfx/gfx_console.c1450
-rw-r--r--engines/sci/include/conf_summary.h106
-rw-r--r--engines/sci/include/modules.h84
-rw-r--r--engines/sci/include/sci_conf.h187
-rw-r--r--engines/sci/main.c1840
-rw-r--r--engines/sci/module.mk2
-rw-r--r--engines/sci/scicore/sci_dos.c219
-rw-r--r--engines/sci/sfx/old/Makefile24
-rw-r--r--engines/sci/sfx/old/README6
-rw-r--r--engines/sci/sfx/old/ROADMAP72
-rw-r--r--engines/sci/sfx/old/main.c49
-rw-r--r--engines/sci/sfx/old/midi.c30
-rw-r--r--engines/sci/sfx/old/midi.h30
-rw-r--r--engines/sci/sfx/old/midi_mt32.c341
-rw-r--r--engines/sci/sfx/old/midi_mt32.h29
-rw-r--r--engines/sci/sfx/old/midiout.c63
-rw-r--r--engines/sci/sfx/old/midiout.h29
-rw-r--r--engines/sci/sfx/old/midiout_alsaraw.c51
-rw-r--r--engines/sci/sfx/old/midiout_alsaraw.h28
-rw-r--r--engines/sci/sfx/old/midiout_unixraw.c52
-rw-r--r--engines/sci/sfx/old/midiout_unixraw.h28
-rw-r--r--engines/sci/sfx/softseq/fmopl.c1144
-rw-r--r--engines/sci/sfx/softseq/mt32/freeverb.cpp310
-rw-r--r--engines/sci/sfx/softseq/mt32/freeverb.h239
-rw-r--r--engines/sci/sfx/softseq/mt32/i386.cpp849
-rw-r--r--engines/sci/sfx/softseq/mt32/i386.h49
-rw-r--r--engines/sci/sfx/softseq/mt32/mt32_file.cpp112
-rw-r--r--engines/sci/sfx/softseq/mt32/mt32_file.h67
-rw-r--r--engines/sci/sfx/softseq/mt32/mt32emu.h70
-rw-r--r--engines/sci/sfx/softseq/mt32/part.cpp632
-rw-r--r--engines/sci/sfx/softseq/mt32/part.h113
-rw-r--r--engines/sci/sfx/softseq/mt32/partial.cpp960
-rw-r--r--engines/sci/sfx/softseq/mt32/partial.h148
-rw-r--r--engines/sci/sfx/softseq/mt32/partialManager.cpp272
-rw-r--r--engines/sci/sfx/softseq/mt32/partialManager.h56
-rw-r--r--engines/sci/sfx/softseq/mt32/structures.h284
-rw-r--r--engines/sci/sfx/softseq/mt32/synth.cpp1199
-rw-r--r--engines/sci/sfx/softseq/mt32/synth.h300
-rw-r--r--engines/sci/sfx/softseq/mt32/tables.cpp749
-rw-r--r--engines/sci/sfx/softseq/mt32/tables.h116
42 files changed, 1 insertions, 13030 deletions
diff --git a/engines/sci/engine/kemu_old.c b/engines/sci/engine/kemu_old.c
deleted file mode 100644
index 4ec6c0a106..0000000000
--- a/engines/sci/engine/kemu_old.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/***************************************************************************
- kemu_old.c Copyright (C) 2002 Christoph Reichenbach
-
-
- This program may be modified and copied freely according to the terms of
- the GNU general public license (GPL), as long as the above copyright
- notice and the licensing information contained herein are preserved.
-
- Please refer to www.gnu.org for licensing details.
-
- This work is provided AS IS, without warranty of any kind, expressed or
- implied, including but not limited to the warranties of merchantibility,
- noninfringement, and fitness for a specific purpose. The author will not
- be held liable for any damage caused by this work or derivatives of it.
-
- By using this source code, you agree to the licensing terms as stated
- above.
-
-
- Please contact the maintainer for bug reports or inquiries.
-
- Current Maintainer:
-
- Christoph Reichenbach (CR) <jameson@linuxgames.com>
-
-***************************************************************************/
-/* Emulation code for old kernel functions */
-
-#include <engine.h>
-#include "kernel_compat.h"
-#include "kernel_types.h"
-#include "heap.h"
-
-#define EMU_HEAP_START_ADDR 1000
-
-#define EMU_TYPE_VERBATIM 0 /* Arithmetic values */
-#define EMU_TYPE_REGISTERS 1 /* Must re-interpret afterwards. Also used for objects. */
-#define EMU_TYPE_BLOCK 2 /* Bulk data; string or similar. May physically point to stack */
-
-static int funct_nr;
-
-typedef struct {
- heap_ptr start; /* Beginning of the block */
- reg_t pos; /* Needed for resolving conflicts */
- int length; /* Number of bytes occupied on the heap */
- object_t *obj; /* For object types: Pointer to the physical object */
-
- /* Emulation data part */
- int emudat_type; /* EMU_TYPE_... */
- heap_ptr emudat_location; /* Only for 1 and 2 */
- union {
- reg_t *regs; /* registers, for type 1 */
- byte *block; /* Bulk data location, for type 2 */
- } emu_data;
- int emudat_size; /* Amount of bytes or number of entries */
-} emu_param_t;
-
-static inline emu_param_t
-identify_value(state_t *s, reg_t reg, heap_ptr firstfree)
-{
- emu_param_t retval;
- int type = determine_reg_type(s, reg);
-
- retval.start = firstfree;
- retval.pos = reg;
-
- retval.obj = NULL;
- retval.length = 0;
- retval.emudat_type = EMU_TYPE_VERBATIM; /* To allow error aborts */
-
- if (type & KSIG_NULL)
- type &= KSIG_ARITHMETIC;
-
- switch (type) {
-
- case KSIG_ARITHMETIC: /* trivial */
- retval.emudat_size = 0;
- break;
-
- case KSIG_OBJECT:
- retval.emudat_type = EMU_TYPE_REGISTERS;
- retval.obj = obj_get(s, reg);
- if (!retval.obj) { BREAKPOINT(); }
- retval.length = -SCRIPT_OBJECT_MAGIC_OFFSET
- + retval.obj->variables_nr * 4 /* values and selectors */
- + 2; /* Extra magic selector word (is this really needed?) */
- retval.emu_data.regs = retval.obj->variables;
- retval.emudat_size = retval.obj->variables_nr;
- retval.emudat_location = retval.start - SCRIPT_OBJECT_MAGIC_OFFSET;
- break;
-
- case KSIG_REF: {
- retval.emudat_type = EMU_TYPE_BLOCK;
-
- retval.emu_data.block =
- s->seg_manager.dereference(&s->seg_manager,
- reg, &retval.emudat_size);
-
- if (!retval.emu_data.block) {
- SCIkdebug(SCIkERROR, "Cannot handle references into segment type %02x"
- " (from "PREG") during emulation\n",
- type, PRINT_REG(reg));
- retval.emudat_type = EMU_TYPE_VERBATIM;
- retval.length = 0;
- }
-
- retval.length = retval.emudat_size;
- retval.emudat_location = retval.start;
-
- break;
- }
-
- default:
- SCIkdebug(SCIkERROR, "Cannot handle argument type %02x (from "PREG
- ") during emulation\n",
- type, PRINT_REG(reg));
- }
-
- return retval;
-}
-
-static inline void
-writeout_value(state_t *s, emu_param_t *p)
-{
- if (p->obj) /* First copy object; don't need to read back this part later */
- memcpy(s->heap + p->start, p->obj->base_obj + SCRIPT_OBJECT_MAGIC_OFFSET,
- p->length);
-
- switch (p->emudat_type) {
-
- case EMU_TYPE_VERBATIM:
- SCIkdebug(SCIkEMU, "\tVerbatim/Arithmetic\n");
- return;
-
- case EMU_TYPE_REGISTERS: {
- int i, max = p->emudat_size;
-
- SCIkdebug(SCIkEMU, "\tObject, %d selectors\n", max);
-
- for (i = 0; i < max; i++) {
- byte *dest = s->heap + p->emudat_location + (i << 1);
-
- dest[0] = p->emu_data.regs[i].offset & 0xff;
- dest[1] = (p->emu_data.regs[i].offset >> 8) & 0xff;
- /* Assume they're all numeric values */
- }
- return;
- }
-
- case EMU_TYPE_BLOCK:
- SCIkdebug(SCIkEMU, "\tBulk\n");
- memcpy(s->heap + p->emudat_location, p->emu_data.block, p->emudat_size);
- return;
-
- default:
- BREAKPOINT();
- }
-}
-
-static inline void
-recover_value(state_t *s, emu_param_t *p)
-{ /* Writes back the value */
- switch (p->emudat_type) {
-
- case EMU_TYPE_VERBATIM:
- return;
-
- case EMU_TYPE_REGISTERS: {
- int i, max = p->emudat_size;
- for (i = 0; i < max; i++) {
- int val = GET_HEAP(p->emudat_location + (i << 1));
- if (p->emu_data.regs[i].offset != val) {
- SCIkdebug(SCIkEMU, " Recovering property #%d from %04x: 0:%04x\n",
- i, p->emudat_location + (i << 1), val);
- p->emu_data.regs[i] = make_reg(0, val);
- } else {
- SCIkdebug(SCIkEMU, " Property #%d from %04x is unchanged (%04x vs "PREG")\n",
- i, p->emudat_location + (i << 1), val, PRINT_REG(p->emu_data.regs[i]));
- }
- /* Don't overwrite unless something changed, to preserve pointers */
- }
- return;
- }
-
- case EMU_TYPE_BLOCK:
- memcpy(p->emu_data.block, s->heap + p->emudat_location, p->emudat_size);
- SCIkdebug(SCIkEMU, " Recovering %d raw bytes from %04x\n",
- p->emudat_size, p->emudat_location);
- return;
-
- default:
- BREAKPOINT();
- }
-}
-
-static void
-_restrict_against(state_t *s, emu_param_t *self, emu_param_t *other)
-{
- if (self->pos.segment != other->pos.segment)
- return;
-
- if (self->pos.offset <= other->pos.offset
- && self->pos.offset + self->emudat_size > other->pos.offset) {
- mem_obj_t *mobj = GET_SEGMENT_ANY(s->seg_manager, self->pos.segment);
-
- self->emudat_size = other->pos.offset - self->pos.offset;
-
- if (mobj && mobj->type == MEM_OBJ_STACK)
- self->emudat_size *= sizeof(reg_t); /* Accomodate for size differences */
- }
-}
-
-static void
-resolve_conflicts(state_t *s, emu_param_t *params, int count)
-{
- int i, j;
- for (i = 0; i < count; i++)
- for (j = 0; j < count; j++)
- if (i != j)
- _restrict_against(s, params + i, params + j);
-}
-
-reg_t
-kFsciEmu(state_t *s, int _funct_nr, int argc, reg_t *argv)
-{
- emu_param_t *shadow_args;
- funct_nr = _funct_nr;
-
- if (!s->kfunct_emu_table[funct_nr]) {
- SCIkwarn(SCIkERROR, "Attempt to emulate unknown kernel function %x\n",
- funct_nr);
- return NULL_REG;
- } else {
- heap_ptr argp = EMU_HEAP_START_ADDR; /* arguments go here */
- heap_ptr datap = argp + argc * 2; /* copied stuff goes here */
- int i;
-
- shadow_args = sci_malloc(sizeof(emu_param_t) * (argc + 1
- /* Prevents stupid warning */));
- memset(shadow_args, 0, sizeof(emu_param_t) * (argc + 1));
-
- SCIkdebug(SCIkEMU, "Emulating kernel call %s[%x] w/ %d arguments at HP:%04x\n",
- s->kernel_names[funct_nr], funct_nr, argc, argp);
-
- for (i = 0; i < argc; i++) {
- int emu_value = argv[i].offset; /* Value we'll pass to the function */
-
- SCIkdebug(SCIkEMU, " %3d : ["PREG"] ->\n", i, PRINT_REG(argv[i]));
-
- shadow_args[i] = identify_value(s, argv[i], datap);
-
- switch (shadow_args[i].emudat_type) {
-
- case EMU_TYPE_VERBATIM:
- break;
-
- case EMU_TYPE_REGISTERS:
- case EMU_TYPE_BLOCK:
- emu_value = shadow_args[i].emudat_location;
- break;
-
- default:
- BREAKPOINT();
-
- }
-
- SCIkdebug(SCIkEMU, "\t%04x [%d at %04x]\n",
- emu_value, shadow_args[i].length, shadow_args[i].start);
-
- PUT_HEAP(argp, emu_value);
- argp += 2;
-
- if (0xffff - shadow_args[i].length < datap) {
- SCIkdebug(SCIkERROR, "Out of heap space while emulating!\n");
- return NULL_REG;
- }
- datap += shadow_args[i].length; /* Step over last block we wrote */
- }
-
- for (i = 0; i < argc; i++)
- writeout_value(s, shadow_args + i);
-
- resolve_conflicts(s, shadow_args, argc);
-
- s->kfunct_emu_table[funct_nr](s, funct_nr, argc, EMU_HEAP_START_ADDR);
-
- for (i = 0; i < argc; i++)
- recover_value(s, shadow_args + i);
- free(shadow_args);
- return make_reg(0, s->acc);
- }
-}
-
-
-int
-read_selector16(state_t *s, heap_ptr object, selector_t selector_id, const char *file, int line)
-{
- int slc_count = GET_HEAP(object + SCRIPT_SELECTORCTR_OFFSET);
- int i;
- heap_ptr slc_names = object + slc_count * 2;
-
- for (i = 0; i < slc_count; i++) {
- if (GET_HEAP(slc_names + (i<<1)) == selector_id)
- return GET_HEAP(object + (i<<1));
- }
-
- SCIkdebug(SCIkWARNING, "[EMU] Could not read selector %d from HP:%04x (%s, L%d)\n",
- selector_id, object, file, line);
- return 0;
-}
-
-void
-write_selector16(state_t *s, heap_ptr object, selector_t selector_id,
- int value, const char *fname, int line)
-{
- int slc_count = GET_HEAP(object + SCRIPT_SELECTORCTR_OFFSET);
- int i;
- heap_ptr slc_names = object + slc_count * 2;
-
- for (i = 0; i < slc_count; i++) {
- if (GET_HEAP(slc_names + (i<<1)) == selector_id) {
- PUT_HEAP(object + (i<<1), value);
- return;
- }
- }
-
- SCIkdebug(SCIkWARNING, "[EMU] Could not write selector %d from HP:%04x (%s, L%d)\n",
- selector_id, object, fname, line);
-}
-
diff --git a/engines/sci/engine/simplesaid.c b/engines/sci/engine/simplesaid.c
deleted file mode 100644
index e74a3aec90..0000000000
--- a/engines/sci/engine/simplesaid.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/***************************************************************************
- simplesaid.c Copyright (C) 2000 Christoph Reichenbach
-
-
- This program may be modified and copied freely according to the terms of
- the GNU general public license (GPL), as long as the above copyright
- notice and the licensing information contained herein are preserved.
-
- Please refer to www.gnu.org for licensing details.
-
- This work is provided AS IS, without warranty of any kind, expressed or
- implied, including but not limited to the warranties of merchantibility,
- noninfringement, and fitness for a specific purpose. The author will not
- be held liable for any damage caused by this work or derivatives of it.
-
- By using this source code, you agree to the licensing terms as stated
- above.
-
-
- Please contact the maintainer for bug reports or inquiries.
-
- Current Maintainer:
-
- Christoph Reichenbach (CR) <jameson@linuxgames.com>
-
-***************************************************************************/
-
-
-#ifdef SCI_SIMPLE_SAID_CODE
-
-#include <engine.h>
-#include <kdebug.h>
-
-static int current_pword;
-static int said_pos;
-static int refstart_pos, parse_pos;
-static parse_tree_node_t *words;
-static int dontclaim; /* Whether the Parse() event should be claimed */
-static int reached_end;
-
-static state_t *state;
-static heap_ptr addr;
-
-#define WORDP_MODE_STAY 0
-#define WORDP_MODE_NEXT 1
-#define WORDP_MODE_SEEK 2
-
-/* hack */
-#define s state
-
-static inline int /* Returns whether the specified word matches */
-word_p(int mode, int word)
-{
- int oldpp = parse_pos;
- do {
- if (mode)
- ++parse_pos;
-
- current_pword = words[parse_pos << 1].content.value;
- /* SDEBUG("Word at %d = %03x\n", parse_pos, current_pword); */
- if (current_pword == word) {
- /* ++matches; */
- SCIkdebug(SCIkSAID, "wordp(%d, %03x) from %d -> 1\n", mode, word, oldpp);
-
- reached_end |= (words[(parse_pos + 1) << 1].type == -1);
-
- return 1;
- }
-
- } while ((mode == WORDP_MODE_SEEK) && (words[parse_pos <<1].type != -1));
-
- if (words[parse_pos << 1].type == -1)
- --parse_pos;
-
- SCIkdebug(SCIkSAID, "wordp(%d, %03x) from %d -> 0\n", mode, word, oldpp);
-
- return 0;
-}
-
-
-
-static inline int /* End of input? */
-end_p()
-{
- int val = (words[(parse_pos + 1) << 1 ].type == -1) || reached_end;
-
- SCIkdebug(SCIkSAID, "endp(pp=%d) = %d\n", parse_pos, val);
-
- return val;
-}
-
-
-
-static inline int /* Returns whether the current_word references that specified word */
-reference_p(int referenced_word_index, int word)
-{
- int val = 0;
- int seeker = (refstart_pos << 1) + 2;
-
- while (words[seeker].type != -1) {
-
- if (words[seeker].content.value == word)
- if (((words[seeker + 1].content.branches[0] > -1)
- && (words[seeker + 1].content.branches[0] == referenced_word_index))
- || ((words[seeker + 1].content.branches[1] > -1)
- && (words[seeker + 1].content.branches[1] == referenced_word_index))) {
- val = 1;
- reached_end |= (words[seeker + 2].type == -1);
- break;
- }
-
- seeker += 2;
- }
-
- SCIkdebug(SCIkSAID, "%03x > pos[%d] = %d (start at %d)\n", word, referenced_word_index, val, refstart_pos);
-
- return val;
-}
-
-
-static inline int /* Checks whether the current word has trailing references */
-follows_p(void)
-{
- /* int val = (words[(parse_pos << 1) + 1].content.branches[1] > (parse_pos << 1));
-
- SDEBUG("follows-p(pp=%d) = %d\n", parse_pos, val);*/
-
- dontclaim = 1;
- return 1; /* appears to work best */
-}
-
-
-static inline int
-next_parse_token(int *token_is_op)
-{
- int item = state->heap[addr++];
-
- if (item < 0xf0) {
- item = item << 8 | state->heap[addr++];
- *token_is_op = 0;
- } else
- *token_is_op = 1;
-
- return item;
-}
-
-#define STATE_INITIAL 0
-#define STATE_OR 1
-#define STATE_SEEK 2
-#define STATE_REF 3
-
-static int
-simplesaid(int minor_state, int terminator)
-{
- int major_state = STATE_INITIAL;
- int refword = parse_pos; /* The word references apply to */
- int aspiring_refword = -1; /* in "a < b < c", c refers to b, and aspiring_refword will be b. */
- int truth = 1;
- int token_is_op;
- SCIkdebug(SCIkSAID, "simplesaid(%02x)\n", terminator);
-
- while (42) {
-
- int token = next_parse_token(&token_is_op);
- SCIkdebug(SCIkSAID, "Got token %03x on truth %d\n", token, truth);
-
- if (token_is_op && (token == terminator)) {
- if (terminator == SAID_TERM)
- truth = truth && end_p();
- SCIkdebug(SCIkSAID, "Terminator; returning %d\n", truth);
- return truth;
- }
-
- if (token_is_op) /* operator? */
- switch (token) {
-
- case SAID_COMMA:
- minor_state = STATE_OR;
- break;
-
- case SAID_SLASH:
- if (!truth) {
- while (((token = next_parse_token(&token_is_op)) != terminator)
- && (token != SAID_TERM)); /* Proceed to end of block */
- if (token != terminator)
- SCIkwarn(SCIkERROR, "Syntax error: Unexpected end of spec");
- return 0;
- }
-
- major_state = STATE_SEEK;
- minor_state = STATE_INITIAL;
- break;
-
- case SAID_PARENC:
- SCIkwarn(SCIkERROR, "')' without matching '('\n");
- return 0;
-
- case SAID_PARENO:
- switch (minor_state) {
-
- case STATE_OR:
- truth |= simplesaid(minor_state, SAID_PARENC);
- break;
-
- case STATE_INITIAL:
- truth = truth && simplesaid(minor_state, SAID_PARENC);
- break;
-
- default:
- SCIkwarn(SCIkERROR, "'(' in minor state %d\n", minor_state);
- }
- break;
-
- case SAID_BRACKC:
- SCIkwarn(SCIkERROR, "']' without matching '['\n");
- return 0;
-
- case SAID_BRACKO: {
- int parse_pos_old = parse_pos;
- int recurse = simplesaid(minor_state, SAID_BRACKC);
- if (!recurse)
- parse_pos = parse_pos_old;
- break;
- }
-
- case SAID_LT:
- if (aspiring_refword > -1) /* "a < b < c" */
- refword = aspiring_refword; /* refword = 'b' (in the case above) */
- major_state = STATE_REF;
- break;
-
- case SAID_GT:
- return truth && follows_p();
-
- case SAID_TERM:
- SCIkwarn(SCIkERROR, "Unexpected end of spec\n");
- return 0;
-
- default:
- SCIkwarn(SCIkERROR, "Syntax error: Unexpected token 0x%02x\n", token);
- return 0;
- } else {
- int tempresult;
-
- /* ++word_tokens_nr; /* Normal word token */
-
- switch(major_state) {
-
- case STATE_INITIAL:
- tempresult = word_p(((minor_state == STATE_OR)? WORDP_MODE_STAY : WORDP_MODE_NEXT), token);
- refword = parse_pos;
- break;
-
- case STATE_SEEK:
- tempresult = word_p(WORDP_MODE_SEEK, token);
- major_state = STATE_INITIAL;
- refword = parse_pos;
- break;
-
- case STATE_REF:
- tempresult = reference_p(refword, token);
- aspiring_refword = parse_pos;
- break;
-
- default:
- SCIkwarn(SCIkERROR, "Invalid major state!\n");
- return 0;
- }
-
- SCIkdebug(SCIkSAID, "state=(%d,%d), truth = %d * %d\n", major_state, minor_state, truth, tempresult);
-
- if (minor_state == STATE_OR)
- truth |= tempresult;
- else
- truth = truth && tempresult;
-
- minor_state = STATE_INITIAL;
- }
- }
-}
-
-#undef s
-
-int
-vocab_simple_said_test(state_t *s, heap_ptr address)
-{
- int matched;
- current_pword = reached_end = 0;
- dontclaim = 0;
- said_pos = 0;
- if (s->parser_lastmatch_word == SAID_NO_MATCH)
- SCIkdebug(SCIkSAID, "lastmatch_word: none\n");
- else
- SCIkdebug(SCIkSAID, "lastmatch_word=%d\n", s->parser_lastmatch_word);
- parse_pos = (s->parser_lastmatch_word == SAID_NO_MATCH)? -1 : s->parser_lastmatch_word;
- refstart_pos = parse_pos;
- state = s;
- addr = address;
- words = s->parser_nodes;
- matched = simplesaid(STATE_INITIAL, SAID_TERM);
- SCIkdebug(SCIkSAID, "Result: (matched,dontclaim)=(%d,%d)\n", matched, dontclaim);
-
- if (!matched)
- return SAID_NO_MATCH;
-
- if (dontclaim) /* partial match */
- return parse_pos; /* Return lastmatch word */
-
- return SAID_FULL_MATCH;
-}
-
-#endif /* SCI_SIMPLE_SAID_CODE */
diff --git a/engines/sci/gfx/gfx_console.c b/engines/sci/gfx/gfx_console.c
deleted file mode 100644
index 0cde8092f3..0000000000
--- a/engines/sci/gfx/gfx_console.c
+++ /dev/null
@@ -1,1450 +0,0 @@
-/***************************************************************************
- gfx_console.c Copyright (C) 2002 Christoph Reichenbach
-
-
- This program may be modified and copied freely according to the terms of
- the GNU general public license (GPL), as long as the above copyright
- notice and the licensing information contained herein are preserved.
-
- Please refer to www.gnu.org for licensing details.
-
- This work is provided AS IS, without warranty of any kind, expressed or
- implied, including but not limited to the warranties of merchantibility,
- noninfringement, and fitness for a specific purpose. The author will not
- be held liable for any damage caused by this work or derivatives of it.
-
- By using this source code, you agree to the licensing terms as stated
- above.
-
-
- Please contact the maintainer for bug reports or inquiries.
-
- Current Maintainer:
-
- Christoph Reichenbach (CR) <jameson@linuxgames.com>
-
-***************************************************************************/
-/* Graphical on-screen console */
-
-
-#include <console.h>
-#include <ctype.h>
-
-#ifdef WANT_CONSOLE
-# define CON_MAX_CLUSTERS 16
-
-#define CON_CLUSTER_SIZE 64
-
-/* Number of console entries stored = CON_MAX_CLUSTERS * CON_CLUSTER_SIZE */
-
-#define CON_ENTRY_USED(e) ((e).height > 0)
-
-#define CON_INPUT_HISTORY_SIZE 64
-#define CON_BUILTIN_CHARS_NR 256
-#define CON_BUILTIN_CHARS_HEIGHT 8
-#define CON_BUILTIN_CHARS_WIDTH 8
-
-#define CON_OVERWRAP_SYMBOL 0x10
-
-#define CON_GFX_PROMPT "$ "
-
-extern byte con_builtin_font_data[];
-
-typedef struct {
- int height; /* Number of pixels occupied by this entry, or 0 if unused */
- int pixmaps_nr;
- gfx_pixmap_t **pixmaps;
- char *text; /* Dynamically allocated */
-} con_entry_t;
-
-
-typedef struct _con_buffer {
- con_entry_t entries[CON_CLUSTER_SIZE];
- struct _con_buffer *next;
- struct _con_buffer *prev;
-} con_buffer_t;
-
-typedef struct {
- con_buffer_t *buf;
- int entry;
- int offset; /* pixel offset relative to the bottom */
-} con_pos_t;
-
-typedef struct {
- int locked_to_end;
- con_pos_t pos;
- gfx_pixmap_t *background;
- gfx_color_t color_bg, color_transparent, color_cursor, color_text, color_input;
- gfx_pixmap_t *input_prompt;
- gfx_pixmap_t *input_precursor;
- gfx_pixmap_t *input_oncursor;
- gfx_pixmap_t *input_postcursor;
- int cursor_position;
- int input_window; /* First character to display, may be up to -2 to include prompt */
- char *input_text;
- int input_bufsize;
- int input_prompt_pos; /* -strlen(input prompt) */
- int input_history_pos;
- int partial_write;
- char *input_history[CON_INPUT_HISTORY_SIZE];
-} con_t;
-
-
-/* Visual options for the con */
-static int con_bg_red = 0;
-static int con_bg_green = 0;
-static int con_bg_blue = 64;
-static int con_bg_alpha = 64;
-static int con_displayed_lines = 180;
-static int con_border_width = 3;
-
-static int con_top_buffer_entry_nr = 0;
-static int con_buffer_clusters = 0;
-static con_buffer_t *con_buffer = NULL;
-static con_buffer_t *con_buffer_tail = NULL;
-static con_t con; /* The global con */
-static gfx_bitmap_font_t con_font;
-static int con_font_initialized = 0;
-static gfx_state_t *con_last_gfx_state = NULL;
-
-/*-- Forwards --*/
-static void
-_con_free_entry_pixmaps(gfx_state_t *state, con_entry_t *entry);
-/* Free all pixmaps from the specified entry
-** Parameters: (gfx_state_t *) state: The state to free from
-** (con_entry_t *) entry: The entry to liberate from its pixmaps
-*/
-
-static gfx_pixmap_t *
-_con_render_text(gfx_state_t *state, char *text, int len,
- gfx_color_t *color, gfx_color_t *bgcolor);
-/* Renders the specified text in the specified fg color
-** Parameters: (gfx_state_t *) state: The state to render in
-** (char *) text: The text to render
-** (int) len: Length of the text to render, or -1 for strlen
-** (gfx_color_t *) color: The fg color to choose
-** (gfx_color_t *) bgcolor: The bg color to choose
-** Returns : (gfx_pixmap_t *) An appropriate pixmap
-*/
-
-
-void
-con_jump_to_end(gfx_state_t *gfx);
-/* Makes the console jump to the logical end of its buffer and redraws
-** Parameters: (gfx_stat_t *) gfx: The graphics state to use fo rdrawing
-*/
-
-static void
-_con_redraw(gfx_state_t *state, int update_display_field, int update_input_field);
-/* Performs a (partial) redraw
-** Parameters: (gfx_state_t *) state: The graphical state to draw with
-** (int) update_display_field: Whether the upper part of the
-** console, used to display test, should be updated
-** (int) update_input_field: Whether the lower part of the
-** console, used to display the user input, should be
-** updated
-*/
-
-static void
-free_con_buffer(con_buffer_t *buf);
-/* Frees the specified con buffer and all of its predecessors
-** Parameters: (con_buffer_t *) buf: The buffer to free
-** Pixmaps are freed if neccessary, using the last used gfx state for con_gfx_show().
-*/
-
-void
-con_gfx_hide(gfx_state_t *state);
-/* Removes the console, restoring the background graphics
-** Parameters: (gfx_state_t *state: The graphics state to draw with
-*/
-
-static gfx_pixmap_t **
-_con_render_text_multiline(gfx_state_t *state, char *text, int maxchars, int *nr);
-/*-- code --*/
-
-static rect_t
-con_box()
-{
- return gfx_rect(0, 0, 320,
- con_displayed_lines
- + con_border_width);
-}
-
-void
-con_gfx_show(gfx_state_t *state)
-{
- gfxop_set_clip_zone(state, gfx_rect(0, 0, 320, 200));
- con_last_gfx_state = state;
-
- con.locked_to_end = 1;
- con.background = gfxop_grab_pixmap(state, con_box());
-
- gfxop_set_color(state, &con.color_bg, con_bg_red, con_bg_green,
- con_bg_blue, con_bg_alpha, -1, -1);
- gfxop_set_color(state, &con.color_transparent, 0, 0, 0, 255, -1, -1);
- gfxop_set_color(state, &con.color_text, 255, 255, 255, 0, -1, -1);
- gfxop_set_color(state, &con.color_input, 255, 255, 0, 0, -1, -1);
- gfxop_set_color(state, &con.color_cursor, 255, 0, 0, 0, -1, -1);
-
- if (!con.input_prompt) {
- con.input_prompt = _con_render_text(state, CON_GFX_PROMPT, -1,
- &con.color_input, NULL);
- con.input_text = (char*)sci_malloc(con.input_bufsize = 64);
- con.input_text[0] = 0;
- con.input_history_pos = 0;
- con.partial_write = 0;
- memset(con.input_history, 0, sizeof(char *) * CON_INPUT_HISTORY_SIZE);
- }
-
- con_jump_to_end(state);
- _con_redraw(state, 0, 1);
-}
-
-static void
-_con_draw_bg_pic(gfx_state_t *state, rect_t zone)
-{
- gfxop_draw_pixmap(state, con.background, zone, gfx_point(zone.x,zone.y));
-}
-
-void
-con_jump_to_end(gfx_state_t *state)
-{
- con.locked_to_end = 1;
- _con_redraw(state, 1, 0);
-}
-
-
-void
-con_fold_text(gfx_state_t *state)
-{
- con_buffer_t *seeker = con_buffer;
-
- /* Fold all text pixmaps */
- while (seeker) {
- int i;
- for (i = 0; i < CON_CLUSTER_SIZE; i++)
- if (CON_ENTRY_USED(seeker->entries[i])
- && seeker->entries[i].text && seeker->entries[i].pixmaps_nr)
- _con_free_entry_pixmaps(state, &seeker->entries[i]);
-
- seeker = seeker->next;
- }
-}
-
-void
-con_gfx_hide(gfx_state_t *state)
-{
- /* Restore background */
- _con_draw_bg_pic(state, con_box());
-
- if (con.background)
- gfxop_free_pixmap(state, con.background);
- con.background = NULL;
-
- con_fold_text(state);
- gfxop_update(state);
-}
-
-static inline con_buffer_t *
-_create_con_buffer(con_buffer_t *prev)
-{
- con_buffer_t *buf = (con_buffer_t *)sci_malloc(sizeof (con_buffer_t));
- int i;
-
- for (i = 0; i < CON_CLUSTER_SIZE; i++)
- buf->entries[i].height = 0;
-
- buf->prev = prev;
- buf->next = NULL;
- if (prev)
- prev->next = buf;
-
- con_buffer_clusters++;
-
- return buf;
-}
-
-
-static inline void
-_add_into_con_buffer(gfx_pixmap_t *pixmap, char *text)
-{
- con_entry_t *target;
-
- if (!con_buffer) {
- con_buffer = con_buffer_tail = _create_con_buffer(NULL);
- con_top_buffer_entry_nr = 0;
- }
-
- if (con_top_buffer_entry_nr == CON_CLUSTER_SIZE) {
- /* Out of entries in this cluster */
- con_buffer = _create_con_buffer(con_buffer);
- con_top_buffer_entry_nr = 0;
- }
-
- target = con_buffer->entries + con_top_buffer_entry_nr;
-
- if (con.partial_write && text) {
- int real_entry = con_top_buffer_entry_nr - 1;
- int needlen = strlen(text);
- char *oldtext;
-
- if (real_entry < 0)
- target = con_buffer->prev->entries + CON_CLUSTER_SIZE - 1;
- else
- target = con_buffer->entries + real_entry;
-
- if (target->pixmaps)
- _con_free_entry_pixmaps(con_last_gfx_state, target);
-
- needlen += strlen(target->text);
- oldtext = target->text;
- target->text = (char *)sci_malloc(needlen+1);
- strcpy(target->text, oldtext);
- strcat(target->text, text);
- free(oldtext);
- free(text);
-
- con.partial_write = (target->text && *(target->text) &&
- target->text[strlen(target->text) - 1] != '\n');
-
- return;
- }
- else ++con_top_buffer_entry_nr;
-
-
- con.partial_write = (text && *(text) &&
- text[strlen(text) - 1] != '\n');
-
- if (pixmap)
- target->height = pixmap->index_yl;
- else
- target->height = 1; /* Will be calculated on demand */
-
- if (!pixmap) {
- target->pixmaps = NULL;
- target->pixmaps_nr = 0;
- } else {
- target->pixmaps = (gfx_pixmap_t **)sci_malloc(sizeof(gfx_pixmap_t *));
- target->pixmaps[0] = pixmap;
- target->pixmaps_nr = 1;
- }
- target->text = text;
-
- while (con_buffer_clusters > CON_MAX_CLUSTERS
- && con_buffer_tail) {
- if (con_buffer_tail->next) {
- con_buffer_tail = con_buffer_tail->next;
- free_con_buffer(con_buffer_tail->prev);
- } else {
- fprintf(stderr,"WARNING: During cleanup, con_buffer_tail ran out!\n");
- free_con_buffer(con_buffer_tail->prev);
- con_buffer_tail = con_buffer = NULL;
- }
- }
-}
-
-
-void
-con_gfx_insert_string(char *string)
-{
- if (string)
- _add_into_con_buffer(NULL, string);
-}
-
-void
-con_gfx_insert_pixmap(gfx_pixmap_t *pixmap)
-{
- if (pixmap)
- _add_into_con_buffer(pixmap, NULL);
-}
-
-static int
-_unfold_graphics(gfx_state_t *state, con_entry_t *drawme, int nr_chars)
- /* Returns whether unfolding was neccessary */
-{
- if (drawme->text && !drawme->pixmaps_nr) {
- int i;
- drawme->pixmaps = _con_render_text_multiline(state, drawme->text,
- nr_chars,
- &drawme->pixmaps_nr);
-
- drawme->height = 0;
- for (i = 0; i < drawme->pixmaps_nr; i++)
- drawme->height +=
- (drawme->pixmaps[i]->yl + state->driver->mode->yfact - 1)
- / state->driver->mode->yfact;
- /* Divide by scaler, round up */
- return 1;
- }
-
- return 0;
-}
-
-void
-con_scroll(gfx_state_t *state, int offset, int maxchars)
-{
- con_entry_t *next_entry;
- /* Scrolls within the display by the specified amount */
-
- if (con.locked_to_end) {
- con.pos.buf = con_buffer;
- con.pos.offset = 0;
- con.pos.entry = con_top_buffer_entry_nr - 1;
- }
-
- if (!con.pos.buf)
- return;
-
- con.locked_to_end = 0;
-
- con.pos.offset += offset; /* offset exceeds size -> Use PREVIOUS entry */
-
- while (con.pos.offset < 0 || con.pos.offset > con.pos.buf->entries[con.pos.entry].height) {
-
- if (con.pos.offset < 0) {
- if (++con.pos.entry == CON_CLUSTER_SIZE
- || ((con.pos.buf == con_buffer)
- && (con.pos.entry >= con_top_buffer_entry_nr))) {
- if (con.pos.buf->next) {
- con.pos.entry = 0;
- con.pos.buf = con.pos.buf->next;
- } else {
- con_jump_to_end(state);
- return;
- }
- }
-
- next_entry = con.pos.buf->entries + con.pos.entry;
-
- _unfold_graphics(state, next_entry, maxchars);
- con.pos.offset += next_entry->height;
- } else { /* offset too great ? */
-
- if (con.pos.entry == 0) {
- if (con.pos.buf->prev) {
- con.pos.entry = CON_CLUSTER_SIZE;
- con.pos.buf = con.pos.buf->prev;
- } else {
- con.pos.offset = con.pos.buf->entries[0].height - 1;
- return;
- }
- }
- --con.pos.entry;
-
- next_entry = con.pos.buf->entries + con.pos.entry;
-
- _unfold_graphics(state, next_entry, maxchars);
- con.pos.offset -= next_entry->height;
-
- if (con.pos.offset < 0)
- con.pos.offset = -con.pos.offset;
- }
- }
-}
-
-void
-con_gfx_init()
-{
- con_set_string_callback(con_gfx_insert_string);
- con_set_pixmap_callback(con_gfx_insert_pixmap);
- con.input_prompt = NULL;
- con.input_text = NULL;
- con.input_window = con.input_prompt_pos = -(int)strlen(CON_GFX_PROMPT);
- con.cursor_position = 0;
- con.input_precursor = NULL;
- con.input_postcursor = NULL;
- con.input_oncursor = NULL;
-}
-
-
-static void
-_init_con_font()
-{
- int i;
-
- con_font.ID = 0;
- con_font.chars_nr = CON_BUILTIN_CHARS_NR;
- con_font.widths = (int *)sci_malloc(sizeof(int) * CON_BUILTIN_CHARS_NR);
- for (i = 0; i < CON_BUILTIN_CHARS_NR; i++)
- con_font.widths[i] = CON_BUILTIN_CHARS_WIDTH;
- con_font.row_size = (CON_BUILTIN_CHARS_WIDTH + 7) >> 3;
- con_font.height = con_font.line_height = CON_BUILTIN_CHARS_HEIGHT;
- con_font.char_size = ((CON_BUILTIN_CHARS_WIDTH + 7) >> 3) * CON_BUILTIN_CHARS_HEIGHT;
- con_font.data = con_builtin_font_data;
-
- con_font_initialized = 1;
-}
-
-static gfx_pixmap_t **
-_con_render_text_multiline(gfx_state_t *state, char *text, int maxchars, int *nr)
-{
- int pixmaps_allocd = 1;
- gfx_pixmap_t **retval = (gfx_pixmap_t **)sci_malloc(sizeof(gfx_pixmap_t *) * pixmaps_allocd);
- char *printbuf = (char *)sci_malloc(maxchars + 8);
- int index = 0;
- int overwrap = 0;
-
- while (*text) {
- int len = 0;
-
- if (overwrap) {
- len = 2;
- printbuf[0] = ' ';
- printbuf[1] = CON_OVERWRAP_SYMBOL;
- overwrap = 0;
- }
-
- while (*text &&
- *text != '\n' && len < maxchars) {
- if (*text != '\t')
- printbuf[len++] = *text;
- else {
- int tabwidth = 8 - (len & 7);
- memset(printbuf + len, ' ', tabwidth);
- len += tabwidth;
- }
- text++;
- }
-
- if (*text && (*text != '\n'))
- overwrap = 1;
-
- if (index == pixmaps_allocd)
- retval = (gfx_pixmap_t **)sci_realloc(retval, sizeof(gfx_pixmap_t *) * (pixmaps_allocd+= 4));
-
- retval[index++] = _con_render_text(state, printbuf, len,
- &con.color_text, NULL);
- if (*text) text += (1 - overwrap);
- }
-
- *nr = index;
- sci_free(printbuf);
- return retval;
-}
-
-static gfx_pixmap_t *
-_con_render_text(gfx_state_t *state, char *text, int len,
- gfx_color_t *color, gfx_color_t *bgcolor)
-{
- gfx_pixmap_t *pxm;
-
- if (len < 0)
- len = strlen(text);
-
- if (!con_font_initialized)
- _init_con_font();
-
- pxm = gfxr_draw_font(&con_font, text, len,
- &color->visual,
- &color->visual,
- (bgcolor) ? &bgcolor->visual : NULL);
-
- pxm->flags |= GFX_PIXMAP_FLAG_SCALED_INDEX;
-
- gfx_xlate_pixmap(gfx_pixmap_alloc_data(pxm, state->driver->mode),
- state->driver->mode, GFX_XLATE_FILTER_NONE);
- return pxm;
-}
-
-static inline int
-_str_move_blank(char *data, int data_length, int initial_offset, int direction)
- /* Finds the next beginning or end of a word */
-{
- int offset = initial_offset;
- int abort = (direction < 0)? 0 : data_length;
- int lookahead = (direction < 0)? -1 : 0;
-
- if (offset != abort)
- offset += direction;
-
- while (offset != abort && isspace(data[offset]))
- offset += direction;
-
- while (offset != abort && !isspace(data[offset + lookahead]))
- offset += direction;
-
- return offset;
-}
-
-char *
-con_history_get_prev(int *handle) /* Should be -1 if not initialized yet */
-{
- int nexthandle;
-
- if (*handle == con.input_history_pos)
- return NULL;
-
- if (*handle == -1)
- *handle = con.input_history_pos;
-
- nexthandle = (*handle) - 1;
- if (nexthandle == -1)
- nexthandle = CON_INPUT_HISTORY_SIZE - 1;
-
- if (con.input_history[nexthandle])
- *handle = nexthandle;
-
- return con.input_history[nexthandle];
-}
-
-char *
-con_history_get_next(int *handle)
-{
- int last = (con.input_history_pos + CON_INPUT_HISTORY_SIZE - 1) % CON_INPUT_HISTORY_SIZE;
- int nexthandle;
-
- if (*handle < 0 || *handle > CON_INPUT_HISTORY_SIZE)
- return NULL;
-
- if (*handle == last) {
- *handle = -1;
- return NULL; /* End of history */
- }
-
- nexthandle = *handle + 1;
- if (nexthandle == CON_INPUT_HISTORY_SIZE)
- nexthandle = 0;
-
- if (con.input_history[nexthandle])
- *handle = nexthandle;
-
- return con.input_history[nexthandle];
-}
-
-void
-con_history_archive(char *msg)
-{
- char **writepos = &(con.input_history[con.input_history_pos]);
-
- if (*writepos)
- sci_free(*writepos);
-
- *writepos = msg;
-
- if (++con.input_history_pos >= CON_INPUT_HISTORY_SIZE)
- con.input_history_pos = 0;
-}
-
-char *
-con_gfx_read(gfx_state_t *state)
-{
- int chwidth = CON_BUILTIN_CHARS_WIDTH / state->driver->mode->xfact;
- int maxchars = 320 / chwidth;
- sci_event_t evt;
- char *retval;
- int done = 0;
- int slen = strlen(con.input_text);
- int history_handle = -1;
-
- do {
- int old_pos = con.cursor_position;
- int must_resize = 0; /* Have to re-calculate the strlen */
- int must_redraw = 0; /* Redraw input field */
- int must_rewin = 0; /* Re-calculate window */
- int must_redraw_text = 0; /* Redraw display field */
- if (slen+1 >= con.input_bufsize)
- con.input_text = (char *)sci_realloc(con.input_text, con.input_bufsize += 64);
-
- evt.type = 0;
- while (!evt.type)
- evt = gfxop_get_event(state, SCI_EVT_ANY);
-
- if (evt.type == SCI_EVT_KEYBOARD) {
-
- if (evt.buckybits & SCI_EVM_CTRL) {
- switch(evt.data) {
- case 'p':
- case 'P': {
- char *hist = con_history_get_prev(&history_handle);
-
- if (hist) {
- sci_free(con.input_text);
- con.input_text = sci_strdup(hist);
- }
- must_resize = must_redraw = must_rewin = 1;
- }
- break;
-
- case 'n':
- case 'N': {
- char *hist = con_history_get_next(&history_handle);
-
- if (hist) {
- sci_free(con.input_text);
- con.input_text = sci_strdup(hist);
- }
- must_resize = must_redraw = must_rewin = 1;
- }
- break;
-
- case 'a':
- case 'A': /* C-a */
- con.cursor_position = 0;
- break;
-
- case 'b':
- case 'B': /* C-b */
- if (con.cursor_position)
- --con.cursor_position;
- break;
-
- case 'e':
- case 'E': /* C-e */
- con.cursor_position = slen;
- break;
-
- case 'f':
- case 'F': /* C-f */
- if (con.cursor_position < slen)
- ++con.cursor_position;
- break;
-
- case 'd':
- case 'D':
- memmove(con.input_text + con.cursor_position,
- con.input_text + con.cursor_position + 1,
- slen - con.cursor_position);
- must_resize = must_redraw = 1;
- break;
-
- case 'h':
- case 'H':
- if (!con.cursor_position)
- break;
-
- memmove(con.input_text + con.cursor_position - 1,
- con.input_text + con.cursor_position,
- slen - con.cursor_position + 1);
- must_resize = must_redraw = 1;
- --con.cursor_position;
- break;
-
- case 'k':
- case 'K':
- con.input_text[con.cursor_position] = 0;
- must_resize = must_redraw = 1;
- break;
-
- case '`': return "go";
-
- default:
- break;
- }
- } else if (evt.buckybits & SCI_EVM_ALT) {
- switch(evt.data) {
- case 'b':
- case 'B':
- con.cursor_position = _str_move_blank(con.input_text,
- slen,
- con.cursor_position,
- -1);
- break;
-
- case 'f':
- case 'F':
- con.cursor_position = _str_move_blank(con.input_text,
- slen,
- con.cursor_position,
- 1);
- break;
-
- case 'd':
- case 'D': {
- int delpos = _str_move_blank(con.input_text, slen,
- con.cursor_position, 1);
-
- must_resize = must_redraw = 1;
- memmove(con.input_text + con.cursor_position,
- con.input_text + delpos,
- slen - delpos + 1);
- }
-
- default:
- break;
- }
- } else switch (evt.data) {
-
- case SCI_K_UP: {
- char *hist = con_history_get_prev(&history_handle);
-
- if (hist) {
- sci_free(con.input_text);
- con.input_text = sci_strdup(hist);
- }
- must_resize = must_redraw = must_rewin = 1;
- }
- break;
-
- case SCI_K_DOWN: {
- char *hist = con_history_get_next(&history_handle);
-
- if (hist) {
- sci_free(con.input_text);
- con.input_text = sci_strdup(hist);
- }
- must_resize = must_redraw = must_rewin = 1;
- }
- break;
-
-
- case SCI_K_LEFT:
- if (con.cursor_position)
- --con.cursor_position;
- break;
-
- case SCI_K_RIGHT:
- if (con.cursor_position < slen)
- ++con.cursor_position;
- break;
-
-
- case SCI_K_PGDOWN:
- must_redraw_text = 1;
- con_scroll(state, -75, maxchars);
- break;
-
- case SCI_K_PGUP:
- must_redraw_text = 1;
- con_scroll(state, 75, maxchars);
- break;
-
- case SCI_K_END:
- con_jump_to_end(state);
- must_redraw_text = 1;
- break;
-
- case SCI_K_DELETE:
- memmove(con.input_text + con.cursor_position,
- con.input_text + con.cursor_position + 1,
- slen - con.cursor_position);
- must_resize = must_redraw = 1;
- break;
-
- case SCI_K_BACKSPACE:
- if (!con.cursor_position)
- break;
-
- memmove(con.input_text + con.cursor_position - 1,
- con.input_text + con.cursor_position,
- slen - con.cursor_position + 1);
- must_resize = must_redraw = 1;
- --con.cursor_position;
- break;
-
-
- case SCI_K_ENTER:
- done = 1;
- break;
-
- default:
- if ((evt.character >= 32) && (evt.character <= 255)) {
- memmove(con.input_text + con.cursor_position + 1,
- con.input_text + con.cursor_position,
- slen - con.cursor_position + 1);
-
- con.input_text[con.cursor_position] = evt.character;
- ++con.cursor_position;
- ++slen;
- must_redraw = 1;
- }
- }
- }
-
- if (must_resize)
- slen = strlen(con.input_text);
-
- if (old_pos != con.cursor_position)
- must_redraw = 1;
-
- if (must_rewin) {
- int chwidth = CON_BUILTIN_CHARS_WIDTH / state->driver->mode->xfact;
- int nr_chars = 320 / chwidth;
-
- con.cursor_position = slen;
- con.input_window = slen - nr_chars + (nr_chars >> 3);
- }
-
- if (must_redraw || must_redraw_text) {
- _con_redraw(state, must_redraw_text, must_redraw);
- gfxop_update(state);
- }
- } while (!done);
-
- retval = con.input_text;
- con.input_text = (char *)sci_malloc(64);
- con.input_text[0] = 0;
- con.input_window = con.input_prompt_pos;
- con.cursor_position = 0;
-
- if (!*retval) {
- int hist = -1;
- sci_free(retval);
- return con_history_get_prev(&hist);
- }
- /* else */
- con_history_archive(retval);
- return retval;
-}
-
-static void
-_con_redraw(gfx_state_t *state, int update_display_field, int update_input_field)
-{
- int chwidth = CON_BUILTIN_CHARS_WIDTH / state->driver->mode->xfact;
- int nr_chars = 320 / chwidth;
- int offset = con_displayed_lines;
- int pixmap_index = -42;
- int must_recompute_pixmap_index = 1;
- int max_offset;
- con_pos_t pos = con.pos;
- rect_t fullbox = con_box();
- int yscale = state->driver->mode->yfact;
- int input_field_height = con.input_prompt ?
- (con.input_prompt->index_yl + yscale - 1) / yscale : 0;
- /* This delta is in "virtual" SCI pixels */
- int input_field_size = con_border_width + input_field_height;
- /* Let's consider the bottom padding to be part of the input field */
-
-
- if (!update_input_field && !update_display_field)
- return;
- if (!update_input_field)
- fullbox.yl -= input_field_size;
-
- if (!update_display_field) {
- fullbox.y = fullbox.yl - input_field_size;
- fullbox.yl = input_field_size;
- }
-
- if (con.color_bg.alpha)
- _con_draw_bg_pic(state, fullbox);
-
- /* Draw overlay box */
- gfxop_draw_box(state, fullbox, con.color_bg, con.color_bg,
- GFX_BOX_SHADE_FLAT);
-
- if (update_input_field) {
-
- if (con_border_width >= 2) {
- int y = con_displayed_lines + con_border_width - 2;
-
- gfxop_draw_line(state, gfx_point(0, y), gfx_point(319, y),
- con.color_input, GFX_LINE_MODE_FINE,
- GFX_LINE_STYLE_NORMAL);
- }
-
- if (con.input_prompt) {
- int promptlen = strlen(CON_GFX_PROMPT);
-
- if (con.cursor_position - con.input_window < (nr_chars >> 3))
- con.input_window -= (nr_chars >> 1);
- else if (con.cursor_position - con.input_window > (nr_chars - (nr_chars >> 3)))
- con.input_window += (nr_chars >> 1);
-
- if (con.input_window < con.input_prompt_pos)
- con.input_window = con.input_prompt_pos;
-
- offset -= input_field_height;
-
- if (con.input_oncursor) {
- gfxop_free_pixmap(state, con.input_oncursor);
- con.input_oncursor = NULL;
- }
-
- if (con.input_text) {
- char oncursorbuf[2];
- char *postcursor_text = con.input_text + con.cursor_position + 1;
- char temp_sep;
-
- oncursorbuf[1] = 0;
- oncursorbuf[0] = temp_sep = con.input_text[con.cursor_position];
-
- if (!temp_sep)
- oncursorbuf[0] = ' '; /* Draw at least a blank cursor */
-
- if (con.input_precursor) {
- gfxop_free_pixmap(state, con.input_precursor);
- con.input_precursor = NULL;
- }
- if (con.input_postcursor) {
- gfxop_free_pixmap(state, con.input_postcursor);
- con.input_postcursor = NULL;
- }
-
- con.input_oncursor = _con_render_text(state, oncursorbuf, -1,
- &con.color_input,
- &con.color_cursor);
- if (con.input_text[0])
- con.input_precursor = _con_render_text(state,
- con.input_text, -1,
- &con.color_input,
- NULL);
- if (postcursor_text[-1])
- con.input_postcursor = _con_render_text(state,
- postcursor_text,
- -1,
- &con.color_input,
- NULL);
-
- con.input_text[con.cursor_position] = temp_sep;
- } else {
- con.input_oncursor = _con_render_text(state, " ", -1,
- &con.color_input,
- &con.color_cursor);
- }
-
-
- if (con.input_window < 0) {
- con.input_prompt->xoffset = 0;
- con.input_prompt->yoffset = 0;
- gfxop_draw_pixmap(state, con.input_prompt,
- gfx_rect(0, 0,
- con.input_prompt->index_xl,
- con.input_prompt->index_yl),
- gfx_point(chwidth * (strlen(CON_GFX_PROMPT)
- + con.input_window),
- offset));
- }
-
- if (con.input_precursor && con.input_window < con.cursor_position)
- gfxop_draw_pixmap(state, con.input_precursor,
- gfx_rect(0, 0,
- con.input_precursor->index_xl,
- con.input_precursor->index_yl),
- gfx_point(chwidth * -con.input_window,
- offset));
-
- if (con.input_postcursor && con.input_window + nr_chars - 1 >
- con.cursor_position) {
- gfxop_draw_pixmap(state, con.input_postcursor,
- gfx_rect(0, 0,
- con.input_postcursor->index_xl,
- con.input_postcursor->index_yl),
- gfx_point(chwidth * (con.cursor_position + 1
- - con.input_window),
- offset));
- }
-
- if (con.input_oncursor)
- gfxop_draw_pixmap(state, con.input_oncursor,
- gfx_rect(0, 0,
- con.input_oncursor->index_xl,
- con.input_oncursor->index_yl),
- gfx_point(chwidth * (con.cursor_position
- - con.input_window),
- offset));
-
-
- }
- } else
- offset -= input_field_height;
-
- if (!update_display_field) {
- gfxop_update_box(state, fullbox);
- return;
- }
-
- max_offset = offset;
-
- if (con.locked_to_end) {
- pos.buf = con_buffer;
- pos.offset = 0;
- pos.entry = con_top_buffer_entry_nr - 1;
- }
-
- while (pos.buf && offset >= 0) {
- con_entry_t *drawme;
- int depth = pos.offset;
- int line_yl;
-
- pos.offset = 0;
-
- if (pos.entry < 0) {
- pos.entry = CON_CLUSTER_SIZE - 1;
- if (pos.buf)
- pos.buf = pos.buf->prev;
-
- if (!pos.buf)
- break;
- }
-
- drawme = &(pos.buf->entries[pos.entry]);
-
- if (_unfold_graphics(state, drawme, nr_chars))
- must_recompute_pixmap_index = 1;
-
- if (must_recompute_pixmap_index) {
- pixmap_index = drawme->pixmaps_nr - 1;
- must_recompute_pixmap_index = 0;
- }
-
- if (pixmap_index < 0) {
- pos.entry--;
- continue;
- }
-
- while (pixmap_index >= 0
- && depth > (drawme->pixmaps[pixmap_index]->yl + yscale - 1) / yscale)
- depth -= (drawme->pixmaps[pixmap_index--]->yl + yscale -1) / yscale;
-
- if (pixmap_index == -1) {
- fprintf(stderr, "ERROR: Offset too great! It was %d in a block of height %d\n",
- con.pos.offset, drawme->height);
- exit(1);
- continue;
- }
-
- line_yl = (drawme->pixmaps[pixmap_index]->yl + yscale - 1) / yscale;
-
- offset -= line_yl - depth;
- depth = line_yl;
-
- if (offset + depth > max_offset)
- depth = max_offset - offset;
-
- gfxop_draw_pixmap(state, drawme->pixmaps[pixmap_index],
- gfx_rect(0, 0,
- drawme->pixmaps[pixmap_index]->index_xl, depth),
- gfx_point(0, offset));
- /*
- ** TODO: Insert stuff into overwrapped lines **
- if (pixmap_index)
- gfxop_draw_line(state, gfx_rect(chwidth - 2, offset,
- chwidth - 2, offset + depth),
- con.color_text, GFX_LINE_MODE_FINE, GFX_LINE_STYLE_NORMAL);
- */
-
- if (!pixmap_index) {
- pos.entry--;
- must_recompute_pixmap_index = 1;
- } else
- --pixmap_index;
- }
-
- gfxop_update_box(state, fullbox);
-}
-
-static void
-_con_free_entry_pixmaps(gfx_state_t *state, con_entry_t *entry)
-{
- int j;
-
- if (entry->pixmaps) {
- for (j = 0; j < entry->pixmaps_nr; j++)
- gfxop_free_pixmap(state, entry->pixmaps[j]);
- sci_free(entry->pixmaps);
- entry->pixmaps_nr = 0;
- entry->pixmaps = NULL;
- }
-}
-
-
-static void
-_free_con_buffer(con_buffer_t *buf);
-
-static void
-free_con_buffer(con_buffer_t *buf)
-/* Frees a con buffer and all of its predecessors */
-{
- /* First, make sure we're not destroying the current display */
- if (!con.locked_to_end) {
- con_buffer_t *seeker = con.pos.buf;
- while (seeker && seeker != buf)
- seeker = seeker->prev;
-
- if (seeker) {
- if (seeker->prev)
- con.pos.buf = seeker->next;
- else
- con.locked_to_end = 1;
- }
- }
- _free_con_buffer(buf);
-}
-
-static void
-_free_con_buffer(con_buffer_t *buf)
-{
- int i;
-
- if (buf) {
- con_buffer_t *prev = buf->prev;
-
- if (buf->next)
- buf->next->prev = NULL;
- for (i = 0; i < CON_CLUSTER_SIZE; i++)
- if (CON_ENTRY_USED(buf->entries[i])) {
- if (buf->entries[i].text)
- sci_free(buf->entries[i].text);
- _con_free_entry_pixmaps(con_last_gfx_state, &buf->entries[i]);
-
- buf->entries[i].height = -1;
- }
- sci_free(buf);
- --con_buffer_clusters;
-
- if (prev)
- _free_con_buffer(prev);
- }
-}
-
-
-byte con_builtin_font_data[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e,
- 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e,
- 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00,
- 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00,
- 0x38, 0x7c, 0x38, 0xfe, 0xfe, 0xd6, 0x10, 0x38,
- 0x10, 0x38, 0x7c, 0xfe, 0xfe, 0x7c, 0x10, 0x38,
- 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00,
- 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff,
- 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
- 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff,
- 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78,
- 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18,
- 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0,
- 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0,
- 0x18, 0xdb, 0x3c, 0xe7, 0xe7, 0x3c, 0xdb, 0x18,
- 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00,
- 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00,
- 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18,
- 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00,
- 0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00,
- 0x3e, 0x61, 0x3c, 0x66, 0x66, 0x3c, 0x86, 0x7c,
- 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00,
- 0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff,
- 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00,
- 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00,
- 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00,
- 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00,
- 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00,
- 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x00,
- 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00,
- 0x18, 0x3e, 0x60, 0x3c, 0x06, 0x7c, 0x18, 0x00,
- 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00,
- 0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00,
- 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x0c, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00,
- 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00,
- 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
- 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30,
- 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
- 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00,
- 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00,
- 0x18, 0x38, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00,
- 0x7c, 0xc6, 0x06, 0x1c, 0x30, 0x66, 0xfe, 0x00,
- 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x00,
- 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00,
- 0xfe, 0xc0, 0xc0, 0xfc, 0x06, 0xc6, 0x7c, 0x00,
- 0x38, 0x60, 0xc0, 0xfc, 0xc6, 0xc6, 0x7c, 0x00,
- 0xfe, 0xc6, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00,
- 0x7c, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0x7c, 0x00,
- 0x7c, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
- 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00,
- 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30,
- 0x06, 0x0c, 0x18, 0x30, 0x18, 0x0c, 0x06, 0x00,
- 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00,
- 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00,
- 0x7c, 0xc6, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x00,
- 0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00,
- 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00,
- 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00,
- 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00,
- 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00,
- 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00,
- 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00,
- 0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3a, 0x00,
- 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00,
- 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
- 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00,
- 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00,
- 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00,
- 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00,
- 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00,
- 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
- 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00,
- 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xce, 0x7c, 0x0e,
- 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00,
- 0x3c, 0x66, 0x30, 0x18, 0x0c, 0x66, 0x3c, 0x00,
- 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x3c, 0x00,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00,
- 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00,
- 0xc6, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0xc6, 0x00,
- 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x00,
- 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00,
- 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00,
- 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00,
- 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00,
- 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00,
- 0xe0, 0x60, 0x7c, 0x66, 0x66, 0x66, 0xdc, 0x00,
- 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc6, 0x7c, 0x00,
- 0x1c, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00,
- 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00,
- 0x3c, 0x66, 0x60, 0xf8, 0x60, 0x60, 0xf0, 0x00,
- 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8,
- 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00,
- 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00,
- 0x06, 0x00, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c,
- 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00,
- 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
- 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0x00,
- 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x00,
- 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
- 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0,
- 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e,
- 0x00, 0x00, 0xdc, 0x76, 0x60, 0x60, 0xf0, 0x00,
- 0x00, 0x00, 0x7e, 0xc0, 0x7c, 0x06, 0xfc, 0x00,
- 0x30, 0x30, 0xfc, 0x30, 0x30, 0x36, 0x1c, 0x00,
- 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00,
- 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00,
- 0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00,
- 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00,
- 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0xfc,
- 0x00, 0x00, 0x7e, 0x4c, 0x18, 0x32, 0x7e, 0x00,
- 0x0e, 0x18, 0x18, 0x70, 0x18, 0x18, 0x0e, 0x00,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00,
- 0x70, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x70, 0x00,
- 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x18, 0x00,
- 0x18, 0x18, 0x7e, 0xc0, 0xc0, 0x7e, 0x18, 0x18,
- 0x38, 0x6c, 0x64, 0xf0, 0x60, 0x66, 0xfc, 0x00,
- 0x00, 0xc6, 0x7c, 0xc6, 0xc6, 0x7c, 0xc6, 0x00,
- 0x66, 0x66, 0x3c, 0x7e, 0x18, 0x7e, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x18,
- 0x3e, 0x61, 0x3c, 0x66, 0x66, 0x3c, 0x86, 0x7c,
- 0x00, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x7e, 0x81, 0x9d, 0xa1, 0xa1, 0x9d, 0x81, 0x7e,
- 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00,
- 0x00, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
- 0x7e, 0x81, 0xb9, 0xa5, 0xb9, 0xa5, 0x81, 0x7e,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x7e, 0x00,
- 0x78, 0x0c, 0x18, 0x30, 0x7c, 0x00, 0x00, 0x00,
- 0x78, 0x0c, 0x38, 0x0c, 0x78, 0x00, 0x00, 0x00,
- 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0xc0,
- 0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00,
- 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x38,
- 0x18, 0x38, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00,
- 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00,
- 0x00, 0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00,
- 0x63, 0xe6, 0x6c, 0x7a, 0x36, 0x6a, 0xdf, 0x06,
- 0x63, 0xe6, 0x6c, 0x7e, 0x33, 0x66, 0xcc, 0x0f,
- 0xe1, 0x32, 0xe4, 0x3a, 0xf6, 0x2a, 0x5f, 0x86,
- 0x18, 0x00, 0x18, 0x18, 0x30, 0x63, 0x3e, 0x00,
- 0x18, 0x0c, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x00,
- 0x30, 0x60, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x00,
- 0x7c, 0x82, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x00,
- 0x76, 0xdc, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x00,
- 0xc6, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00,
- 0x38, 0x6c, 0x7c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00,
- 0x3e, 0x6c, 0xcc, 0xfe, 0xcc, 0xcc, 0xce, 0x00,
- 0x7c, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x0c, 0x78,
- 0x30, 0x18, 0xfe, 0xc0, 0xfc, 0xc0, 0xfe, 0x00,
- 0x18, 0x30, 0xfe, 0xc0, 0xf8, 0xc0, 0xfe, 0x00,
- 0x7c, 0x82, 0xfe, 0xc0, 0xfc, 0xc0, 0xfe, 0x00,
- 0xc6, 0x00, 0xfe, 0xc0, 0xfc, 0xc0, 0xfe, 0x00,
- 0x30, 0x18, 0x3c, 0x18, 0x18, 0x18, 0x3c, 0x00,
- 0x0c, 0x18, 0x3c, 0x18, 0x18, 0x18, 0x3c, 0x00,
- 0x3c, 0x42, 0x3c, 0x18, 0x18, 0x18, 0x3c, 0x00,
- 0x66, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x3c, 0x00,
- 0xf8, 0x6c, 0x66, 0xf6, 0x66, 0x6c, 0xf8, 0x00,
- 0x76, 0xdc, 0x00, 0xe6, 0xf6, 0xde, 0xce, 0x00,
- 0x0c, 0x06, 0x38, 0x6c, 0xc6, 0x6c, 0x38, 0x00,
- 0x30, 0x60, 0x38, 0x6c, 0xc6, 0x6c, 0x38, 0x00,
- 0x7c, 0x82, 0x38, 0x6c, 0xc6, 0x6c, 0x38, 0x00,
- 0x76, 0xdc, 0x38, 0x6c, 0xc6, 0x6c, 0x38, 0x00,
- 0xc6, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x00,
- 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, 0x00,
- 0x3a, 0x6c, 0xce, 0xd6, 0xe6, 0x6c, 0xb8, 0x00,
- 0x60, 0x30, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
- 0x18, 0x30, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
- 0x7c, 0x82, 0x00, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
- 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
- 0x0c, 0x18, 0x66, 0x66, 0x3c, 0x18, 0x3c, 0x00,
- 0xf0, 0x60, 0x7c, 0x66, 0x7c, 0x60, 0xf0, 0x00,
- 0x78, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xcc, 0x00,
- 0x30, 0x18, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00,
- 0x18, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00,
- 0x7c, 0x82, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00,
- 0x76, 0xdc, 0x7c, 0x06, 0x7e, 0xc6, 0x7e, 0x00,
- 0xc6, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00,
- 0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00,
- 0x00, 0x00, 0x7e, 0x12, 0xfe, 0x90, 0xfe, 0x00,
- 0x00, 0x00, 0x7e, 0xc0, 0xc0, 0x7e, 0x0c, 0x38,
- 0x30, 0x18, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00,
- 0x0c, 0x18, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00,
- 0x7c, 0x82, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00,
- 0xc6, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0x7c, 0x00,
- 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
- 0x0c, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
- 0x7c, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00,
- 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00,
- 0x30, 0x7e, 0x0c, 0x7c, 0xcc, 0xcc, 0x78, 0x00,
- 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x00,
- 0x30, 0x18, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
- 0x0c, 0x18, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
- 0x7c, 0x82, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
- 0x76, 0xdc, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
- 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
- 0x00, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x00, 0x00,
- 0x00, 0x02, 0x7c, 0xce, 0xd6, 0xe6, 0x7c, 0x80,
- 0x60, 0x30, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00,
- 0x18, 0x30, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00,
- 0x78, 0x84, 0x00, 0xcc, 0xcc, 0xcc, 0x76, 0x00,
- 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00,
- 0x18, 0x30, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0xfc,
- 0xe0, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x60, 0xf0,
- 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0xfc
-};
-
-#endif /* !WANT_CONSOLE */
diff --git a/engines/sci/include/conf_summary.h b/engines/sci/include/conf_summary.h
deleted file mode 100644
index c2a1f8e16e..0000000000
--- a/engines/sci/include/conf_summary.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/***************************************************************************
- conf_summary.h Copyright (C) 2007 Christoph Reichenbach
-
-
- This program may be modified and copied freely according to the terms of
- the GNU general public license (GPL), as long as the above copyright
- notice and the licensing information contained herein are preserved.
-
- Please refer to www.gnu.org for licensing details.
-
- This work is provided AS IS, without warranty of any kind, expressed or
- implied, including but not limited to the warranties of merchantibility,
- noninfringement, and fitness for a specific purpose. The author will not
- be held liable for any damage caused by this work or derivatives of it.
-
- By using this source code, you agree to the licensing terms as stated
- above.
-
-
- Please contact the maintainer for bug reports or inquiries.
-
- Current Maintainer:
-
- Christoph Reichenbach (CR) <jameson@linuxgames.com>
-
-***************************************************************************/
-
-#ifndef CONF_SUMMARY_H_
-#define CONF_SUMMARY_H_
-
-#include<conf_parse.h>
-#include<conf_driver.h>
-
-typedef struct {
- conf_option_t *option; /* NULL if this is a terminator */
- conf_parse_t *parse; /* Source location we got this information from,
- ** or NULL for command-line or default */
- union { char *str;
- int nr } choice;
- int origin;
- int flags;
-} conf_option_choice_t;
-
-#define CONF_CHOICE_ORIGIN_DEFAULT 0 /* Built-in default */
-#define CONF_CHOICE_ORIGIN_CONFDEFAULT 1 /* Config file option */
-#define CONF_CHOICE_ORIGIN_CONFGAME 2 /* Game-specific option */
-#define CONF_CHOICE_ORIGIN_COMMANDLINE 3
-
-#define CONF_CHOICE_FLAG_WRITEABLE (1<<0) /* 'parse' can be written to */
-#define CONF_CHOICE_FLAG_DISABLED (1<<1) /* Option isn't set, only listed for completeness */
-
-typedef struct {
- conf_option_choice_t *options; /* Driver-specific */
- conf_driver_t *driver;
-} conf_driver_choice_t;
-
-typedef struct {
- conf_option_choice_t *options; /* Subsystem-specific */
- int driver_origin; /* CONF_CHOICE_ORIGIN_* */
- conf_driver_choice_t *driver; /* The particular driver selected */
- conf_driver_choice_t *drivers; /* All available drivers, with their options */
-} conf_subsystem_choice_t;
-
-typedef struct {
- char *game_id; /* NULL for default */
- conf_option_choice_t *options; /* Global */
- int flags;
- conf_parse_t **append_location; /* Into here we can add new configuration options to override */
-
- conf_subsystem_choice_t[CONF_SUBSYSTEMS_NR] subsystems;
-} conf_game_choice_t;
-
-#define CONF_GAME_CHOICE_FLAG_OVERRIDE_IN_SECTION (1<<0) /* Override section already exists, need not be re-created */
-
-typedef struct {
- conf_game_choice_t *default;
-
- int game_choices_nr;
- conf_game_choice_t *game_choices;
-} conf_summary_t;
-
-
-conf_summary_t *
-conf_summary(conf_parse_t *raw_config);
-/* Summarises a config parse in a conf_summary_t
-** Parameters: (conf_parse_t *) raw_config: The parse to summarise
-** Returns : (conf_summary_t *) A summarised configuration
-** The summary includes (default) values for all driver/subsystem options
-*/
-
-void
-conf_free_summary(conf_summary_t *summary);
-/* Deallocates a configuration summary
-** Parameters: (conf_summary_t *) summary: The summary to deallocate
-** This only affects the summary, not the underlying parse.
-*/
-
-conf_game_choice_t *
-conf_find_choice(conf_summary_t *choices, char *game_id);
-/* Finds the correct game choice by game ID
-** Parameters: (conf_summary_t *) summary: The summary to peruse
-** (char *) game_id: Identified game ID.
-** We search by exact match or otherwise default.
-*/
-
-#endif /* !defined (CONF_SUMMARY_H_) */
diff --git a/engines/sci/include/modules.h b/engines/sci/include/modules.h
deleted file mode 100644
index 9a64956326..0000000000
--- a/engines/sci/include/modules.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/***************************************************************************
- modules.h Copyright (C) 2001 Christoph Reichenbach
-
-
- This program may be modified and copied freely according to the terms of
- the GNU general public license (GPL), as long as the above copyright
- notice and the licensing information contained herein are preserved.
-
- Please refer to www.gnu.org for licensing details.
-
- This work is provided AS IS, without warranty of any kind, expressed or
- implied, including but not limited to the warranties of merchantibility,
- noninfringement, and fitness for a specific purpose. The author will not
- be held liable for any damage caused by this work or derivatives of it.
-
- By using this source code, you agree to the licensing terms as stated
- above.
-
-
- Please contact the maintainer for bug reports or inquiries.
-
- Current Maintainer:
-
- Christoph Reichenbach (CR) <jameson@linuxgames.com>
-
-***************************************************************************/
-
-#ifndef _FREESCI_MODULES_H_
-#define _FREESCI_MODULES_H_
-
-#include <sciresource.h>
-
-#ifdef _WIN32
-# define MODULE_NAME_SUFFIX ".dll"
-#else
-# define MODULE_NAME_SUFFIX ".so"
-#endif
-
-
-/* Modules must sub-type this structure. Oh, wait, C doesn't do sub-typing.
-** Well, they have to start the same, anyway... */
-typedef struct {
- char *module_name; /* Module name */
- char *module_version; /* Module version */
- int class_magic; /* Magic ID to identify drivers of certain types */
- int class_version; /* Version of that particular driver class */
-
- /* More entries might be added later, but won't be checked if magic or
- ** version don't match. */
-
-} sci_module_t;
-
-
-void *
-sci_find_module(char *path, char *name, char *type, char *struct_prefix,
- char *file_suffix, int magic, int version, void **handle);
-/* Attempts to open a module with the specified parameters in the path
-** Parameters: (char *) path: The path to look in; supports several directories
-** (char *) name: Module name
-** (char *) type: Module type string (see below)
-** (char *) struct_prefix: see below
-** (char *) file_suffix: see below
-** (int) magic: Magic number to identify the module type
-** (int) version: The only version to support
-** (void **) handle: Pointer to a void * which a handle is written
-** to (for use with sci_close_module()).
-** Returns : (void *) NULL if no module was found, a pointer to the structure
-** otherwise
-** This function looks for the structure 'struct_prefix + name' in a file called
-** 'name + file_suffix + MODULE_NAME_SUFFIX' in the 'type' subdirectory.
-** It only success if both the magic and the version number match.
-*/
-
-void
-sci_close_module(void *module, char *type, char *name);
-/* Closes a previously found module
-** Parameters: (void *) module: Reference to the module to close
-** (char *) type: Type of the module (for debugging)
-** (char *) name: Module name (for debugging)
-** Returns : (void)
-*/
-
-
-#endif /* !_FREESCI_MODULES_H_ */
diff --git a/engines/sci/include/sci_conf.h b/engines/sci/include/sci_conf.h
deleted file mode 100644
index da411226ed..0000000000
--- a/engines/sci/include/sci_conf.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/***************************************************************************
- sci_conf.h Copyright (C) 1999,2000,01 Christoph Reichenbach
-
-
- This program may be modified and copied freely according to the terms of
- the GNU general public license (GPL), as long as the above copyright
- notice and the licensing information contained herein are preserved.
-
- Please refer to www.gnu.org for licensing details.
-
- This work is provided AS IS, without warranty of any kind, expressed or
- implied, including but not limited to the warranties of merchantibility,
- noninfringement, and fitness for a specific purpose. The author will not
- be held liable for any damage caused by this work or derivatives of it.
-
- By using this source code, you agree to the licensing terms as stated
- above.
-
-
- Please contact the maintainer for bug reports or inquiries.
-
- Current Maintainer:
-
- Christoph Reichenbach (CJR) [jameson@linuxgames.com]
-
-***************************************************************************/
-/* Configuration and setup stuff for FreeSCI */
-
-#ifndef _SCI_CONFIG_H_
-#define _SCI_CONFIG_H_
-
-#include <versions.h>
-#include <gfx_options.h>
-
-#define FREESCI_DRIVER_SUBSYSTEMS_NR 1
-
-#define FREESCI_DRIVER_SUBSYSTEM_GFX 0
-#define FREESCI_DRIVER_SUBSYSTEM_PCM 1
-#define FREESCI_DRIVER_SUBSYSTEM_MIDIOUT 2
-
-#ifdef _WIN32
-# define SCI_DEFAULT_MODULE_PATH "."
-#else
-# define SCI_DEFAULT_MODULE_PATH "/usr/local/lib/freesci/:/usr/lib/freesci/"
-#endif
-
-typedef struct _driver_option {
- char *option;
- char *value;
- struct _driver_option *next;
-} driver_option_t;
-
-typedef struct _subsystem_options {
- char *name; /* Driver name */
- driver_option_t *options;
- struct _subsystem_options *next; /* next driver */
-} subsystem_options_t;
-
-typedef struct {
- /* IMPORTANT: these values correspond directly to what's specified in
- ** config.l. Where an option is of type OPTION_TYPE_NVP or
- ** OPTION_TYPE_INVERSE_NVP, it is cast as an _integer_. Therefore it
- ** should not be any other type except for int here.
- */
-
- char *name; /* Game identifier */
- sci_version_t version; /* The version to emulate */
-
- gfx_options_t gfx_options;
-
- subsystem_options_t *driver_options[FREESCI_DRIVER_SUBSYSTEMS_NR];
-
- int x_scale, y_scale, scale, color_depth; /* GFX subsystem initialization values */
-
- int animation_delay; /* Number of microseconds to wait between each pic transition animation cycle */
- int animation_granularity; /* Granularity for pic transition animations */
- int alpha_threshold; /* Crossblitting alpha threshold */
- int unknown_count; /* The number of "unknown" kernel functions */
- char *resource_dir; /* Resource directory */
- char *gfx_driver_name; /* The graphics driver to use */
- char *console_log; /* The file to which console output should be echoed */
- char *menu_dir; /* Directory where the game menu searches for games */
- char debug_mode [80]; /* Characters specifying areas for which debug output should be enabled */
- int mouse; /* Whether the mouse should be active */
- int reverse_stereo;
- int res_version;
-
-#ifdef __GNUC__
-# warning "Re-enable sound stuff"
-#endif
-#if 0
- midiout_driver_t *midiout_driver; /* the midiout method to use */
- midi_device_t *midi_device; /* the midi device to use */
-
- pcmout_driver_t *pcmout_driver; /* the pcm driver to use */
- sound_server_t *sound_server; /* The sound server */
-#endif
- guint16 pcmout_rate; /* Sample rate */
- guint8 pcmout_stereo; /* Stereo? */
-
- char *module_path; /* path to directories modules are loaded from */
- void *dummy; /* This is sad... */
-} config_entry_t;
-
-int
-config_init(config_entry_t **conf, char *conffil);
-/* Initializes the config entry structurre based on information found in the config file.
-** Parameters: (config_entry_t **) conf: See below
-** (char *) conffile: Filename of the config file, or NULL to use the default name
-** Returns : (int) The number of config file entries found
-** This function reads the ~/.freesci/config file, parses it, and inserts the appropriate
-** data into *conf. *conf will be malloc'd to be an array containing default information in [0]
-** and game-specific data in each of the subsequent record entries.
-** Not threadsafe. Uses flex-generated code.
-*/
-
-void
-config_free(config_entry_t **conf, int entries);
-/* Frees a config entry structure
-** Parameters: (config_entry_t **) conf: Pointer to the pointer to the first entry of the list
-** (int) entries: Number of entries to free
-** Returns : (void)
-*/
-
-
-void *
-parse_gfx_driver(char *driver_name);
-/* Parses a string and looks up an appropriate driver structure
-** Parameters: (char *) driver_name: Name of the driver to look up
-** Returns : (void *) A matching driver, or NULL on failure
-*/
-
-void *
-parse_midiout_driver(char *driver_name);
-/* Parses a string and looks up an appropriate driver structure
-** Parameters: (char *) driver_name: Name of the driver to look up
-** Returns : (void *) A matching driver, or NULL on failure
-*/
-
-void *
-parse_midi_device(char *driver_name);
-/* Parses a string and looks up an appropriate driver structure
-** Parameters: (char *) driver_name: Name of the driver to look up
-** Returns : (void *) A matching driver, or NULL on failure
-*/
-
-void *
-parse_pcmout_driver(char *driver_name);
-/* Parses a string and looks up an appropriate driver structure
-** Parameters: (char *) driver_name: Name of the driver to look up
-** Returns : (void *) A matching driver, or NULL on failure
-*/
-
-void *
-parse_sound_server(char *driver_name);
-/* Parses a string and looks up an appropriate driver structure
-** Parameters: (char *) driver_name: Name of the driver to look up
-** Returns : (void *) A matching sound server, or NULL on failure
-*/
-
-driver_option_t *
-get_driver_options(config_entry_t *config, int subsystem, const char *name);
-/* Retreives the driver options for one specific driver in a subsystem
-** Parameters: (config_entry_t *) config: The config entry to search in
-** (int) subsystem: Any of the FREESCI_DRIVER_SUBSYSTEMs
-** (const char *) name: Name of the driver to look for
-** Returns : (driver_option_t *) A pointer to the first option in
-** a singly-linked list of options, or NULL if none was
-** found
-*/
-
-#if 0
-void *
-find_module(char *path, char *module_name, char *module_suffix);
-/* Tries to find a module in the specified path
-** Parameters: (char *) path: The path to search in (specified in config)
-** (char *) module_name: Name of the module to look for
-** (char *) module_suffix: Module structure to look for
-** More precisely, the module "module_name" + MODULE_NAME_SUFFIX is
-** looked for in all members of the path. If it is found,
-
-** FIXME: First need to add generic module architecture
-
-*/
-#endif
-
-#endif /* !_SCI_CONFIG_H */
diff --git a/engines/sci/main.c b/engines/sci/main.c
deleted file mode 100644
index 2da6a550be..0000000000
--- a/engines/sci/main.c
+++ /dev/null
@@ -1,1840 +0,0 @@
-/***************************************************************************
- main.c Copyright (C) 1999,2000,01,02 Christoph Reichenbach
-
-
- This program may be modified and copied freely according to the terms of
- the GNU general public license (GPL), as long as the above copyright
- notice and the licensing information contained herein are preserved.
-
- Please refer to www.gnu.org for licensing details.
-
- This work is provided AS IS, without warranty of any kind, expressed or
- implied, including but not limited to the warranties of merchantibility,
- noninfringement, and fitness for a specific purpose. The author will not
- be held liable for any damage caused by this work or derivatives of it.
-
- By using this source code, you agree to the licensing terms as stated
- above.
-
-
- Please contact the maintainer for bug reports or inquiries.
-
- Current Maintainer:
-
- Christoph Reichenbach (CJR) [jameson@linuxgames.com]
-
-***************************************************************************/
-
-#include <sciresource.h>
-#include <engine.h>
-#include <uinput.h>
-#include <console.h>
-#include <gfx_operations.h>
-#include <sci_conf.h>
-#include <kdebug.h>
-#include <sys/types.h>
-#include <game_select.h>
-#include "list.h"
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#ifdef HAVE_FORK
-# include <sys/wait.h>
-#endif
-
-#if defined(HAVE_SDL) && defined(MACOSX)
-# include <SDL.h>
-/* On OS X, SDL must #define main to something else in order to function */
-#endif
-
-#ifdef _MSC_VER
-#define extern __declspec(dllimport) extern
-#include <win32/getopt.h>
-#endif
-
-#ifdef HAVE_READLINE_READLINE_H
-#include <readline/readline.h>
-#ifdef HAVE_READLINE_HISTORY_H
-#include <readline/history.h>
-#endif /* HAVE_READLINE_HISTORY_H */
-#endif /* HAVE_READLINE_READLINE_H */
-
-#ifdef HAVE_GETOPT_H
-# ifndef _MSC_VER
-# include <getopt.h>
-# else
-# include <win32\getopt.h>
-# endif
-#endif /* HAVE_GETOPT_H */
-
-#ifdef HAVE_GETOPT_LONG
-#define EXPLAIN_OPTION(longopt, shortopt, description) " " longopt "\t" shortopt "\t" description "\n"
-#else /* !HAVE_GETOPT_H */
-#define EXPLAIN_OPTION(longopt, shortopt, description) " " shortopt "\t" description "\n"
-#endif /* !HAVE_GETOPT_H */
-
-
-#ifdef _WIN32
-# ifdef _MSC_VER
-# include <direct.h>
-# define PATH_MAX 255
-# endif
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
-#endif
-
-#ifdef _DREAMCAST
-# include <selectgame.h>
-#endif
-
-#ifdef _MSC_VER
-# define MSVC_FUNCTYPECAST_KLUDGE (void *)
-#else
-# define MSVC_FUNCTYPECAST_KLUDGE
-#endif
-
-#define ACTION_PLAY 0
-#define ACTION_LIST_SAVEGAMES 1
-
-static int sciv_action = ACTION_PLAY;
-
-/*** HW/OS-dependant features ***/
-
-static void
-check_features()
-{
-#ifdef HAVE_ALPHA_EV6_SUPPORT
- int helper;
- printf("Checking for MVI instruction-set extension: ");
-
- helper = 0x100;
-#ifdef __DECC
- axp_have_mvi = asm("amask %0, %v0", helper);
-#else
- __asm__ ("amask %1, %0"
- : "=r"(axp_have_mvi)
- : "r"(helper));
-#endif
-
- axp_have_mvi = !axp_have_mvi;
-
- if (axp_have_mvi)
- printf("found\n");
- else
- printf("not present\n");
-#endif
-}
-
-
-static gfx_state_t static_gfx_state; /* see below */
-static gfx_options_t static_gfx_options; /* see below */
-
-static state_t *gamestate; /* The main game state */
-static gfx_state_t *gfx_state = &static_gfx_state; /* The graphics state */
-static gfx_options_t *gfx_options = &static_gfx_options; /* Graphics options */
-static char *commandline_config_file = NULL;
-
-int
-c_quit(state_t *s)
-{
- script_abort_flag = 1; /* Terminate VM */
- _debugstate_valid = 0;
- _debug_seeking = 0;
- _debug_step_running = 0;
- return 0;
-}
-
-int
-c_die(state_t *s)
-{
- exit(0); /* Die */
- return 0; /* ;-P (fixes warning) */
-}
-
-
-char *old_input = NULL;
-
-#ifdef HAVE_READLINE_READLINE_H
-const char *
-get_readline_input(void)
-{
- char *input;
-
- fflush(NULL);
- input = readline("> ");
-
- if (!input) { /* ^D */
- c_quit(NULL);
- return "";
- }
-
- if (strlen(input) == 0) {
- free (input);
- } else {
-
-#ifdef HAVE_READLINE_HISTORY_H
- add_history(input);
-#endif /* HAVE_READLINE_HISTORY_H */
-
- if (old_input) {
- free(old_input);
- }
- old_input = input;
- }
-
- return old_input? old_input : "";
-}
-#endif /* HAVE_READLINE_READLINE_H */
-
-
-int
-init_directories(char *work_dir, char *game_id)
-{
- char *homedir = sci_get_homedir();
-
- printf("Initializing directories...\n");
- if (!homedir) { /* We're probably not under UNIX if this happens */
-
- if (!getcwd(work_dir, PATH_MAX)) {
- fprintf(stderr,"Cannot get the working directory!\n");
- return 1;
- }
-
- return 0;
- }
-
- /* So we've got a home directory */
-
- if (chdir(homedir)) {
-
-#ifdef _WIN32
- if (!getcwd(work_dir, PATH_MAX)) {
- fprintf(stderr,"Cannot get the working directory: %s\n", work_dir);
- return 1;
- }
-#else /* Assume UNIX-ish environment */
- fprintf(stderr,"Error: Could not enter home directory %s.\n", homedir);
- perror("Reason");
- return 1; /* If we get here, something really bad is happening */
-#endif
- }
-
- if (strlen(homedir) > MAX_HOMEDIR_SIZE) {
- fprintf(stderr, "Your home directory path is too long. Re-compile FreeSCI with "
- "MAX_HOMEDIR_SIZE set to at least %i and try again.\n", (int)(strlen(homedir)));
- return 1;
- }
-
- if (chdir(FREESCI_GAMEDIR)) {
- if (scimkdir(FREESCI_GAMEDIR, 0700)) {
-
- fprintf(stderr, "Warning: Could not enter ~/"FREESCI_GAMEDIR"; save files"
- " will be written to ~/\n");
-
- getcwd(work_dir, PATH_MAX);
- return 0;
-
- }
- else /* mkdir() succeeded */
- chdir(FREESCI_GAMEDIR);
- }
-
- if (chdir(game_id)) {
- if (scimkdir(game_id, 0700)) {
-
- fprintf(stderr,"Warning: Could not enter ~/"FREESCI_GAMEDIR"/%s; "
- "save files will be written to ~/"FREESCI_GAMEDIR"\n", game_id);
-
- getcwd(work_dir, PATH_MAX);
- return 0;
- }
- else /* mkdir() succeeded */
- chdir(game_id);
- }
-
- getcwd(work_dir, PATH_MAX);
-
- return 0;
-}
-
-
-const char *
-get_gets_input(void)
-{
- static char input[1024] = "";
-
- putchar('>');
-
- fflush(NULL);
- while (!strchr(input, '\n'))
- fgets(input, 1024, stdin);
-
- if (!input) {
- c_quit(NULL);
- return "";
- }
-
- if (strlen(input))
- if (input[strlen(input)-1] == '\n');
- input[strlen(input)-1] = 0; /* Remove trailing '\n' */
-
- if (strlen(input) == 0) {
- return old_input? old_input : "";
- }
-
- if (old_input)
- free(old_input);
-
- old_input = (char *) sci_malloc(1024);
- strcpy(old_input, input);
- return input;
-}
-
-
-
-
-static void
-list_graphics_drivers()
-{
- int i = 0;
- while (gfx_get_driver_name(i)) {
- if (i != 0)
- printf(", ");
-
- printf(gfx_get_driver_name(i));
-
- i++;
- }
- printf("\n");
-}
-
-#ifdef __GNUC__
-#warning "Re-enable sound stuff"
-#endif
-#if 0
-static void
-list_pcmout_drivers()
-{
- int i = 0;
- while (pcmout_drivers[i]) {
- if (i != 0)
- printf(", ");
- printf(pcmout_drivers[i]->name);
- i++;
- }
- printf("\n");
-}
-
-static void
-list_midiout_drivers()
-{
- int i = 0;
- while (midiout_drivers[i]) {
- if (i != 0)
- printf(", ");
- printf(midiout_drivers[i]->name);
- i++;
- }
- printf("\n");
-}
-
-
-static void
-list_midi_devices()
-{
- int i = 0;
- while (midi_devices[i]) {
- if (i != 0)
- printf(", ");
- printf(midi_devices[i]->name);
- i++;
- }
- printf("\n");
-}
-
-static void
-list_sound_servers()
-{
- int i = 0;
- while (sound_servers[i]) {
- if (i != 0)
- printf(", ");
- printf(sound_servers[i]->name);
- i++;
- }
- printf("\n");
-}
-#endif
-
-
-/**********************************************************/
-/* Startup and config management */
-/**********************************************************/
-
-typedef struct {
- int script_debug_flag;
- int scale_x, scale_y, color_depth;
- int mouse;
- int master_sound; /* on or off */
- int show_rooms;
- sci_version_t version;
- int res_version;
- char *gfx_driver_name;
- char *gamedir;
- char *gamemenu;
- char *midiout_driver_name;
- char *midi_device_name;
- char *sound_server_name;
- char *pcmout_driver_name;
-} cl_options_t;
-
-#define ON 1
-#define OFF 0
-#define DONTCARE -1
-
-static int game_select(cl_options_t cl_options, config_entry_t *confs, int conf_entries, const char* freesci_dir, const char *games_dir);
-static int game_select_resource_found();
-
-static char *
-parse_arguments(int argc, char **argv, cl_options_t *cl_options, char **savegame_name)
-{
- int c;
-#ifdef HAVE_GETOPT_LONG
- int optindex;
-
- struct option options[] = {
- {"run", no_argument, NULL, 0 },
- {"debug", no_argument, NULL, 1 },
- {"gamedir", required_argument, 0, 'd'},
- {"menudir", required_argument, 0, 'G'},
- {"no-sound", required_argument, 0, 'q'},
- {"sci-version", required_argument, 0, 'V'},
- {"graphics", required_argument, 0, 'g'},
- {"midiout", required_argument, 0, 'O'},
- {"pcmout", required_argument, 0, 'P'},
- {"sound-server", required_argument, 0, 'S'},
- {"mididevice", required_argument, 0, 'M'},
- {"version", no_argument, 0, 'v'},
- {"help", no_argument, 0, 'h'},
- {"scale-x", required_argument, 0, 'x'},
- {"scale-y", required_argument, 0, 'y'},
- {"color-depth", required_argument, 0, 'c'},
- {"disable-mouse", no_argument, 0, 'm'},
- {"list-savegames", no_argument, 0, 'l'},
- {"show-rooms", no_argument, 0, 's'},
- {"config-file", required_argument, 0, 'f'},
- {0,0,0,0}
- };
-
- options[0].flag = &(cl_options->script_debug_flag);
- options[1].flag = &(cl_options->script_debug_flag);
-#endif /* HAVE_GETOPT_H */
-
- cl_options->scale_x = cl_options->scale_y = cl_options->color_depth = 0;
- cl_options->version = 0;
- cl_options->script_debug_flag = 0;
- cl_options->gfx_driver_name = NULL;
- cl_options->gamedir = NULL;
- cl_options->gamemenu = NULL;
- cl_options->midiout_driver_name = NULL;
- cl_options->pcmout_driver_name = NULL;
- cl_options->midi_device_name = NULL;
- cl_options->sound_server_name = NULL;
- cl_options->mouse = ON;
- cl_options->master_sound = ON;
- cl_options->res_version = SCI_VERSION_AUTODETECT;
- cl_options->show_rooms = 0;
-
-#ifdef HAVE_GETOPT_LONG
- while ((c = getopt_long(argc, argv, "qlvhmsDr:d:G:V:g:x:y:c:M:O:S:P:f:", options, &optindex)) > -1) {
-#else /* !HAVE_GETOPT_LONG */
- while ((c = getopt(argc, argv, "qlvhmsDr:d:G:V:g:x:y:c:M:O:S:P:f:")) > -1) {
-#endif /* !HAVE_GETOPT_LONG */
- switch (c) {
-
- case 'r':
- cl_options->res_version = atoi(optarg);
- break;
-
- case 's':
- cl_options->show_rooms = 1;
- break;
-
- case 'D':
- cl_options->script_debug_flag = 1;
- break;
-
- case 'd':
- if (cl_options->gamedir)
- free(cl_options->gamedir);
-
- cl_options->gamedir = sci_strdup(optarg);
- break;
-
- case 'G':
- if (cl_options->gamemenu)
- free(cl_options->gamemenu);
-
- cl_options->gamemenu = sci_strdup(optarg);
- break;
-
- case 'f':
- commandline_config_file = sci_strdup(optarg);
- break;
-
- case 'V': {
- int major = *optarg - '0'; /* One version digit */
- int minor = atoi(optarg + 2);
- int patchlevel = atoi(optarg + 6);
-
- cl_options->version = SCI_VERSION(major, minor, patchlevel);
- }
- break;
-
- case 'g':
- if (cl_options->gfx_driver_name)
- free(cl_options->gfx_driver_name);
- cl_options->gfx_driver_name = sci_strdup(optarg);
- break;
- case 'O':
- if (cl_options->midiout_driver_name)
- free(cl_options->midiout_driver_name);
- cl_options->midiout_driver_name = sci_strdup(optarg);
- break;
- case 'P':
- if (cl_options->pcmout_driver_name)
- free(cl_options->pcmout_driver_name);
- cl_options->pcmout_driver_name = sci_strdup(optarg);
- break;
- case 'M':
- if (cl_options->midi_device_name)
- free(cl_options->midi_device_name);
- cl_options->midi_device_name = sci_strdup(optarg);
- break;
- case 'S':
- if (cl_options->sound_server_name)
- free(cl_options->sound_server_name);
- cl_options->sound_server_name = sci_strdup(optarg);
- break;
- case '?':
- /* getopt_long already printed an error message. */
- exit(1);
-
- case 'x':
- cl_options->scale_x = atoi(optarg);
- break;
-
- case 'y':
- cl_options->scale_y = atoi(optarg);
- break;
-
- case 'c':
- cl_options->color_depth = (atoi(optarg) +7) >> 3;
- break;
-
- case 'm':
- cl_options->mouse = OFF;
- break;
-
- case 'q':
- cl_options->master_sound = OFF;
- break;
-
- case 0: /* getopt_long already did this for us */
- break;
-
- case 'v':
- printf("This is FreeSCI, version %s\n", VERSION);
-
- printf("Supported graphics drivers: ");
- list_graphics_drivers();
-
-#ifdef __GNUC__
-#warning "Re-enable sound stuff"
-#endif
-#if 0
- printf("Supported sound servers: ");
- list_sound_servers();
-
- printf("Supported midiout drivers: ");
- list_midiout_drivers();
-
- printf("Supported midi 'devices': ");
- list_midi_devices();
-
- printf("Supported pcmout drivers: ");
- list_pcmout_drivers();
-#endif
-
- printf("\n");
- exit(0);
-
- case 'h':
- printf("Usage: freesci [options] [game name] [savegame ID]\n"
- "Runs a Sierra SCI game.\n"
- "\n"
- EXPLAIN_OPTION("--gamedir dir\t", "-ddir", "read game resources from dir")
- EXPLAIN_OPTION("--menudir dir\t", "-Gdir", "display menu for all games under dir")
- EXPLAIN_OPTION("--run\t\t", "-r", "do not start the debugger")
- EXPLAIN_OPTION("--sci-version ver", "-Vver", "set the version for freesci to emulate")
- EXPLAIN_OPTION("--version\t", "-v", "display version number and exit")
- EXPLAIN_OPTION("--debug\t", "-D", "start up in debug mode")
- EXPLAIN_OPTION("--help\t", "-h", "display this help text and exit")
- EXPLAIN_OPTION("--graphics gfx", "-ggfx", "use the 'gfx' graphics driver")
- EXPLAIN_OPTION("--scale-x\t", "-x", "Set horizontal scale factor")
- EXPLAIN_OPTION("--scale-y\t", "-y", "Set vertical scale factor")
- EXPLAIN_OPTION("--color-depth\t", "-c", "Specify color depth in bpp")
- EXPLAIN_OPTION("--disable-mouse", "-m", "Disable support for pointing device")
- EXPLAIN_OPTION("--midiout drv\t", "-Odrv", "use the 'drv' midiout driver")
- EXPLAIN_OPTION("--mididevice drv", "-Mdrv", "use the 'drv' midi device (eg mt32 or adlib)")
- EXPLAIN_OPTION("--pcmout drv\t", "-Pdrv", "use the 'drv' pcmout driver")
- EXPLAIN_OPTION("--sound-server srv", "-Ssrv", "Specifies the asynchronous sound server to use")
- EXPLAIN_OPTION("--no-sound\t", "-q", "disable sound output")
- EXPLAIN_OPTION("--list-savegames", "-l", "Lists all savegame IDs")
- EXPLAIN_OPTION("--show-rooms\t", "-s","Displays room numbers on the game console")
- "\n"
- "The game name, if provided, must be equal to a game name as specified in the\n"
- "FreeSCI config file.\n"
- "It is overridden by --gamedir.\n"
- "\n"
- );
- exit(0);
-
- case 'l':
- sciv_action = ACTION_LIST_SAVEGAMES;
- break;
-
- default:
- exit(1);
- }
- }
-#if 0
- } /* Work around EMACS paren matching bug */
-#endif
-
- if (optind+1 >= argc)
- *savegame_name = NULL;
- else
- *savegame_name = argv[optind + 1];
-
- if (optind == argc)
- return NULL;
-
- return
- argv[optind];
-}
-
-static int
-find_config(char *game_name, config_entry_t *conf, int conf_entries,
- sci_version_t *version)
-{
- int i, conf_nr = 0;
-
- for (i = 1; i < conf_entries; i++)
- if (!strcasecmp(conf[i].name, game_name)) {
- conf_nr = i;
- if (version)
- *version = conf[i].version;
- }
-
- return conf_nr;
-}
-
-static void
-init_console()
-{
-#ifdef WANT_CONSOLE
- con_gfx_init();
-#endif
- con_hook_command(&c_quit, "quit", "", "console: Quits gracefully");
- con_hook_command(&c_die, "die", "", "console: Quits ungracefully");
-
- con_hook_int(&(gfx_options->buffer_pics_nr), "buffer_pics_nr",
- "Number of pics to buffer in LRU storage\n");
- con_hook_int(&(gfx_options->pic0_dither_mode), "pic0_dither_mode",
- "Mode to use for pic0 dithering\n");
- con_hook_int(&(gfx_options->pic0_dither_pattern), "pic0_dither_pattern",
- "Pattern to use for pic0 dithering\n");
- con_hook_int(&(gfx_options->pic0_unscaled), "pic0_unscaled",
- "Whether pic0 should be drawn unscaled\n");
- con_hook_int(&(gfx_options->dirty_frames), "dirty_frames",
- "Dirty frames management\n");
- con_hook_int(&gfx_crossblit_alpha_threshold, "alpha_threshold",
- "Alpha threshold for crossblitting\n");
- con_hook_int(&sci0_palette, "sci0_palette",
- "SCI0 palette- 0: EGA, 1:AGI/Amiga, 2:Grayscale\n");
- con_hook_int(&sci01_priority_table_flags, "sci01_priority_table_flags",
- "SCI01 priority table debugging flags: 1:Disable, 2:Print on change\n");
-
- con_passthrough = 1; /* enables all sciprintf data to be sent to stdout */
-
-#ifdef HAVE_READLINE_HISTORY_H
- using_history(); /* Activate history for readline */
-#endif /* HAVE_READLINE_HISTORY_H */
-
-#ifdef HAVE_READLINE_READLINE_H
- _debug_get_input = get_readline_input; /* Use readline for debugging input */
-#else /* !HAVE_READLINE_READLINE_H */
- _debug_get_input = get_gets_input; /* Use gets for debug input */
-#endif /* !HAVE_READLINE_READLINE_H */
-}
-
-
-static int
-init_gamestate(state_t *gamestate, resource_mgr_t *resmgr, sci_version_t version)
-{
- int errc;
- gamestate->resmgr = resmgr;
-
- if ((errc = script_init_engine(gamestate, version))) { /* Initialize game state */
- int recovered = 0;
-
- if (errc == SCI_ERROR_INVALID_SCRIPT_VERSION) {
- int tversion = SCI_VERSION_FTU_NEW_SCRIPT_HEADER - ((version < SCI_VERSION_FTU_NEW_SCRIPT_HEADER)? 0 : 1);
-
- while (!recovered && tversion) {
- printf("Trying version %d.%03x.%03d instead\n", SCI_VERSION_MAJOR(tversion),
- SCI_VERSION_MINOR(tversion), SCI_VERSION_PATCHLEVEL(tversion));
-
- errc = script_init_engine(gamestate, tversion);
-
- if ((recovered = !errc))
- version = tversion;
-
- if (errc != SCI_ERROR_INVALID_SCRIPT_VERSION)
- break;
-
- switch (tversion) {
-
- case SCI_VERSION_FTU_NEW_SCRIPT_HEADER - 1:
- if (version >= SCI_VERSION_FTU_NEW_SCRIPT_HEADER)
- tversion = 0;
- else
- tversion = SCI_VERSION_FTU_NEW_SCRIPT_HEADER;
- break;
-
- case SCI_VERSION_FTU_NEW_SCRIPT_HEADER:
- tversion = 0;
- break;
- }
- }
- if (recovered)
- printf("Success.\n");
- }
-
- if (!recovered) {
- fprintf(stderr,"Script initialization failed. Aborting...\n");
- return 1;
- }
- }
- return 0;
-}
-
-static int
-init_gfx(config_entry_t *conf, cl_options_t *cl_options, gfx_driver_t *driver, resource_mgr_t *resmgr)
-{
- int scale_x = 0, scale_y = 0, color_depth = 0;
-
- if (conf) {
- if (conf->scale)
- scale_x = scale_y = conf->scale;
-
- if (conf->x_scale)
- scale_x = conf->x_scale;
-
- if (conf->y_scale)
- scale_y = conf->y_scale;
-
- if (conf->color_depth)
- color_depth = conf->color_depth >> 3; /* In there it's bpp */
- }
-
- gfx_state->driver = driver;
- gamestate->gfx_state = gfx_state;
- gfx_state->version = resmgr->sci_version;
-
- if (cl_options->scale_x > 0) {
- scale_x = cl_options->scale_x;
-
- if (!scale_y)
- scale_y = cl_options->scale_x;
- }
-
- if (cl_options->scale_y > 0) {
- scale_y = cl_options->scale_y;
-
- if (!scale_x)
- scale_x = cl_options->scale_y;
- }
-
- if (cl_options->color_depth > 0)
- color_depth = cl_options->color_depth;
-
- if (cl_options->color_depth > 0 && scale_x == 0)
- scale_x = scale_y = 2; /* Some default setting */
-
- if (scale_x > 0) {
-
- if (color_depth > 0) {
- if (gfxop_init(gfx_state, scale_x,
- scale_y, (gfx_color_mode_t) color_depth,
- gfx_options, resmgr)) {
- fprintf(stderr,"Graphics initialization failed. Aborting...\n");
- return 1;
- }
- } else {
- color_depth = 4;
- while (gfxop_init(gfx_state, scale_x,
- scale_y, (gfx_color_mode_t) color_depth,
- gfx_options, resmgr) && --color_depth);
-
- if (!color_depth) {
- fprintf(stderr,"Could not find a matching color depth. Aborting...\n");
- return 1;
- }
- }
-
- } else if (gfxop_init_default(gfx_state, gfx_options, resmgr)) {
- fprintf(stderr,"Graphics initialization failed. Aborting...\n");
- return 1;
- }
-
- return 0;
-}
-
-
-typedef void *old_lookup_funct_t(char *name);
-
-typedef void *lookup_funct_t(const char *path, const char *name);
-
-
-static void *
-lookup_driver(lookup_funct_t lookup_func, void explain_func(void),
- const char *driver_class, const char *driver_name, const char *path)
-{
- void *retval = lookup_func(path, driver_name);
-
- if (!retval) {
- if (!driver_name)
- sciprintf("The default %s is not available; please choose"
- " one explicitly.\n", driver_class);
- else
- sciprintf("The %s you requested, '%s', is not available.\n"
-/* "Please choose one among the following: " */
- ,
- driver_class, driver_name);
-/* explain_func(); */
- exit(1);
- }
-
- return retval;
-}
-
-
-/*static void *
-old_lookup_driver(old_lookup_funct_t lookup_func, void explain_func(void),
- char *driver_class, char *driver_name)
-{
- void *retval = lookup_func(driver_name);
-
- if (!retval) {
- sciprintf("The %s you requested, '%s', is not available.\n"
- "Please choose one among the following: ",
- driver_class, driver_name);
- explain_func();
- exit(1);
- }
-
- return retval;
-}*/
-
-#define NAMEBUF_LEN 30
-static void
-list_savegames(state_t *s)
-{
- sci_dir_t dir;
- char *filename = NULL;
-
- sci_init_dir(&dir);
-
- filename = sci_find_first(&dir, "*");
-
- sciprintf("\nSavegame listing:\n"
- "-----------------\n");
- while (filename) {
- char namebuf[NAMEBUF_LEN + 1];
- if (test_savegame(s, filename, namebuf, NAMEBUF_LEN)) {
- if (namebuf[0])
- sciprintf("%s:\t\"%s\"\n", filename, namebuf);
- else
- sciprintf("%s\n", filename);
- }
- filename = sci_find_next(&dir);
- }
- sciprintf("-----------------\n");
-}
-
-void
-get_file_directory(char* directory, const char* file)
-{
- char* end;
-
- strcpy(directory, file);
-
- end = directory + strlen(directory) - 1;
- while ((end >= directory) && (end != 0))
- {
- if (*end == G_DIR_SEPARATOR)
- {
- *end = 0;
- break;
- }
- else
- {
- end--;
- }
- }
-}
-
-static void
-detect_versions(sci_version_t *version, int *res_version, cl_options_t *options, config_entry_t *conf)
-{
- sci_version_t exe_version;
- sci_version_t hash_version;
- int hash_res_version;
- guint32 code;
- int got_exe_version;
- const char *game_name;
-
- sciprintf("Detecting interpreter and resource versions...\n");
-
- got_exe_version = !version_detect_from_executable(&exe_version);
-
- if (got_exe_version) {
- sciprintf("Interpreter version: %d.%03d.%03d (by executable scan)\n",
- SCI_VERSION_MAJOR(exe_version),
- SCI_VERSION_MINOR(exe_version),
- SCI_VERSION_PATCHLEVEL(exe_version));
-
- if (SCI_VERSION_MAJOR(exe_version) >= 1) {
- sciprintf("FIXME: Implement version mapping (results of executable scan ignored)\n");
- got_exe_version = 0;
- }
-
- }
-
- game_name = version_guess_from_hashcode(&hash_version, &hash_res_version, &code);
-
- if (game_name) {
- sciprintf("Interpreter version: %d.%03d.%03d (by hash code %08X)\n",
- SCI_VERSION_MAJOR(hash_version),
- SCI_VERSION_MINOR(hash_version),
- SCI_VERSION_PATCHLEVEL(hash_version), code);
- if (got_exe_version && exe_version != hash_version)
- sciprintf("UNEXPECTED INCONSISTENCY: Hash code %08X indicates interpreter version\n"
- " %d.%03d.%03d, but analysis of the executable yields %d.%03d.%03d (for game\n"
- " '%s'). Please report this!\n",
- code,
- SCI_VERSION_MAJOR(hash_version),
- SCI_VERSION_MINOR(hash_version),
- SCI_VERSION_PATCHLEVEL(hash_version),
- SCI_VERSION_MAJOR(exe_version),
- SCI_VERSION_MINOR(exe_version),
- SCI_VERSION_PATCHLEVEL(exe_version), game_name);
-
- if (hash_res_version != SCI_VERSION_AUTODETECT)
- sciprintf("Resource version: %d (by hash code)\n", hash_res_version);
-
- sciprintf("Game identified as '%s'\n", game_name);
- } else {
- sciprintf("Could not identify game by hash code: %08X\n", code);
-
- if (got_exe_version)
- sciprintf("Please report the preceding two lines and the name of the game you were trying\n"
- "to run to the FreeSCI development team to help other users!\n",
- code);
- }
-
- if (options->version)
- *version = options->version;
- else if (conf && conf->version)
- *version = conf->version;
- else if (game_name)
- *version = hash_version;
- else if (got_exe_version)
- *version = exe_version;
- else
- *version = 0;
-
- if (options->res_version != SCI_VERSION_AUTODETECT)
- *res_version = options->res_version;
- else if (conf && conf->res_version != SCI_VERSION_AUTODETECT)
- *res_version = conf->res_version;
- else if (game_name)
- *res_version = hash_res_version;
- else
- *res_version = SCI_VERSION_AUTODETECT;
-
- if (*version)
- sciprintf("Using interpreter version %d.%03d.%03d\n",
- SCI_VERSION_MAJOR(*version),
- SCI_VERSION_MINOR(*version),
- SCI_VERSION_PATCHLEVEL(*version));
-
- if (*res_version != SCI_VERSION_AUTODETECT)
- sciprintf("Using resource version %d\n", *res_version);
-}
-
-int
-main(int argc, char** argv)
-{
- config_entry_t *active_conf = NULL; /* Active configuration used */
- config_entry_t *confs = {0}; /* Configuration read from config file (if it exists) */
- cl_options_t cl_options; /* Command line options */
- int conf_entries = -1; /* Number of config entries */
- int conf_nr = -1; /* Element of conf to use */
-/* FILE *console_logfile = NULL; */
- char freesci_dir[PATH_MAX+1] = "";
- char startdir[PATH_MAX+1] = "";
- char resource_dir[PATH_MAX+1] = "";
- char work_dir[PATH_MAX+1] = "";
- char *cwd;
- char *gfx_driver_name = NULL;
-/* char *midiout_driver_name = NULL;
- char *midi_device_name = NULL;
- char *pcm_driver_name = NULL; */
- char *game_name = NULL;
- char *savegame_name = NULL;
- sci_version_t version;
- int res_version;
- gfx_driver_t *gfx_driver = NULL;
-#if 0
- sound_server_t *sound_server = NULL;
-#endif
- const char *module_path = SCI_DEFAULT_MODULE_PATH;
- resource_mgr_t *resmgr;
-#ifdef _DREAMCAST
- /* Fake command line arguments. */
- char *args[] = {"/cd/freesci.bin", "-f/ram/config", NULL};
- argv = args;
- argc = 2;
- chdir("/ram");
-#endif
-
- init_console(); /* So we can get any output */
-
- game_name = parse_arguments(argc, argv, &cl_options, &savegame_name);
-
- /* remember where freesci executable is located */
- get_file_directory(freesci_dir, argv[0]);
-
- getcwd(startdir, PATH_MAX);
- script_debug_flag = cl_options.script_debug_flag;
-
- printf("FreeSCI %s Copyright (C) 1999-2007\n", VERSION);
- printf(" Dmitry Jemerov, Christopher T. Lansdown, Sergey Lapin, Rickard Lind,\n"
- " Carl Muckenhoupt, Christoph Reichenbach, Magnus Reftel, Lars Skovlund,\n"
- " Rink Springer, Petr Vyhnak, Solomon Peachy, Matt Hargett, Alex Angas\n"
- " Walter van Niftrik, Rainer Canavan, Ruediger Hanke, Hugues Valois\n"
- "This program is free software. You can copy and/or modify it freely\n"
- "according to the terms of the GNU general public license, v2.0\n"
- "or any later version, at your option.\n"
- "It comes with ABSOLUTELY NO WARRANTY.\n");
-
-#ifdef _DREAMCAST
- choose_game();
- game_name = "game";
-#endif
-
- conf_entries = config_init(&confs, commandline_config_file);
-
- /* working directory was changed by config_init so restore it */
- chdir(startdir);
-
- if (game_name) {
-
- conf_nr = find_config(game_name, confs, conf_entries, &version);
- active_conf = confs + conf_nr;
-
- if (!cl_options.gamedir)
- if (chdir(active_conf->resource_dir)) {
- if (conf_nr)
- fprintf(stderr,"Error entering '%s' to load resource data\n", active_conf->resource_dir);
- else
- fprintf(stderr,"Game '%s' isn't registered in your config file.\n", game_name);
- exit(1);
- }
- }
-
- if (cl_options.gamedir)
- {
- if (chdir(cl_options.gamedir)) {
- printf ("Error changing to game directory '%s'\n", cl_options.gamedir);
- exit(1);
- }
- free(cl_options.gamedir);
- }
-
- /* by now, if the user specified a game name or a game directory, the working dir has been changed */
- /* so if no resource are found in the working dir, invoke the game selection screen */
- if (!game_name && !game_select_resource_found())
- {
- char *menu_dir;
-
- if (cl_options.gamemenu)
- menu_dir = cl_options.gamemenu;
- else
- menu_dir = confs->menu_dir;
-
- chdir(startdir);
- conf_nr = game_select(cl_options, confs, conf_entries, freesci_dir, menu_dir);
- if (conf_nr < 0)
- return 1;
- if (conf_nr > 0)
- /* A game from the config file was chosen */
- active_conf = confs + conf_nr;
- }
-
- detect_versions(&version, &res_version, &cl_options, active_conf);
-
- getcwd(resource_dir, PATH_MAX); /* Store resource directory */
-
- sciprintf("Loading resources...\n");
-
- resmgr = scir_new_resource_manager(resource_dir, res_version, 1, 256*1024);
-
- if (!resmgr) {
- printf("No resources found in '%s'.\nAborting...\n",
- resource_dir);
- exit(1);
- }
-
- script_adjust_opcode_formats(resmgr->sci_version);
-
- check_features();
-
- chdir(startdir);
-
-#ifdef __GNUC__
-#warning "sound"
-#endif
-#if 0
- printf("Mapping instruments to General Midi\n");
-
- map_MIDI_instruments(resmgr);
-#endif
-
- sciprintf("FreeSCI, version "VERSION"\n");
-
- gamestate = (state_t *) sci_calloc(sizeof(state_t), 1);
-
- if (init_gamestate(gamestate, resmgr, version))
- return 1;
-
- gamestate->gfx_state = NULL;
- if (game_init(gamestate)) { /* Initialize */
- fprintf(stderr,"Game initialization failed: Aborting...\n");
- return 1;
- }
-
- if (init_directories(work_dir, (char *) gamestate->game_name)) {
- fprintf(stderr,"Error resolving the working directory\n");
- exit(1);
- }
-
- /* Set the CWD as the savegame dir */
- cwd = sci_getcwd();
- script_set_gamestate_save_dir(gamestate, cwd);
- sci_free(cwd);
-
- if (sciv_action == ACTION_LIST_SAVEGAMES) {
- list_savegames(gamestate);
- exit(0);
- }
- gamestate->resource_dir = resource_dir;
- gamestate->work_dir = work_dir;
- gamestate->port_serial = 0;
-
- if (!game_name)
- game_name = (char *) gamestate->game_name;
-
- /* If no game-specific configuration has been read, then read the non-specific config from file */
- if (!active_conf) {
- conf_nr = find_config(game_name, confs, conf_entries, &version);
- active_conf = confs + conf_nr;
- }
-
- /* gcc doesn't warn about (void *)s being typecast. If your compiler doesn't like these
- ** implicit casts, don't hesitate to typecast appropriately. */
- if (cl_options.gfx_driver_name) {
- gfx_driver_name = sci_strdup(cl_options.gfx_driver_name);
- free(cl_options.gfx_driver_name);
- } /* else it's still NULL */
-
-#ifdef __GNUC__
-#warning "sound"
-#endif
-#if 0
- if (cl_options.pcmout_driver_name)
- pcmout_driver = old_lookup_driver((old_lookup_funct_t *)pcmout_find_driver,
- MSVC_FUNCTYPECAST_KLUDGE list_pcmout_drivers,
- "pcmout driver", cl_options.pcmout_driver_name);
-
- if (cl_options.midiout_driver_name)
- {
- midiout_driver = old_lookup_driver((old_lookup_funct_t *)midiout_find_driver,
- MSVC_FUNCTYPECAST_KLUDGE list_midiout_drivers,
- "midiout driver", cl_options.midiout_driver_name);
- free(cl_options.midiout_driver_name);
- }
-
- if (cl_options.midi_device_name)
- {
- midi_device = old_lookup_driver((old_lookup_funct_t *)midi_find_device,
- MSVC_FUNCTYPECAST_KLUDGE list_midi_devices,
- "MIDI device", cl_options.midi_device_name);
- free(cl_options.midi_device_name);
- }
-
- if (cl_options.sound_server_name)
- {
- sound_server = old_lookup_driver((old_lookup_funct_t *)sound_server_find_driver,
- MSVC_FUNCTYPECAST_KLUDGE list_sound_servers,
- "sound server", cl_options.sound_server_name);
- free(cl_options.sound_server_name);
- }
-#endif
-
- if (confs) {
- memcpy(gfx_options, &(active_conf->gfx_options), sizeof(gfx_options_t)); /* memcpy so that console works */
- if (!gfx_driver_name)
- gfx_driver_name = active_conf->gfx_driver_name;
-#ifdef __GNUC__
-#warning "sound"
-#endif
-#if 0
- if (!sound_server)
- sound_server = active_conf->sound_server;
-
- /* make sure we have sound drivers */
- if (!midiout_driver)
- midiout_driver = active_conf->midiout_driver;
- if (!midi_device)
- midi_device = active_conf->midi_device;
- if (!pcmout_driver)
- pcmout_driver = active_conf->pcmout_driver;
-#endif
- }
-
- if (confs) {
- module_path = active_conf->module_path;
-
- if (!gfx_driver_name)
- gfx_driver_name = active_conf->gfx_driver_name;
- }
-
- gfx_driver = (gfx_driver_t *)
- lookup_driver((lookup_funct_t *)gfx_find_driver,
- MSVC_FUNCTYPECAST_KLUDGE list_graphics_drivers,
- "graphics driver", gfx_driver_name, module_path);
-
- if (!gfx_driver) {
- if (gfx_driver_name)
- fprintf(stderr,"Failed to find graphics driver \"%s\"\n"
- "Please run 'freesci -v' to get a list of all "
- "available drivers.\n", gfx_driver_name);
- else
- fprintf(stderr,"No default gfx driver available.\n");
-
- return 1;
- }
-
- if (!gamestate->version_lock_flag)
- if (active_conf->version)
- gamestate->version = active_conf->version;
-
- if (strlen (active_conf->debug_mode))
- set_debug_mode (gamestate, 1, active_conf->debug_mode);
-
-
-#if 0
- {
- int j;
- for (j =0; j < conf_entries; j++) {
- int i;
- config_entry_t *c = conf + j;
- fprintf(stderr, "[%s]\n", c->name);
- for (i = 0; i < 2; i++) {
- subsystem_options_t *subsys = c->driver_options[i];
- fprintf(stderr, " <%s>\n", i? "midiout" : "gfx");
-
- while (subsys) {
- driver_option_t *opt;
- fprintf(stderr, " {%p,%s}\n", subsys->name,subsys->name);
- opt = subsys->options;
- while (opt) {
- fprintf(stderr, "\t%p'%s' = %p'%s'\n", opt->option, opt->option, opt->value,opt->value);
- opt = opt->next;
- }
- subsys = subsys->next;
- }
- }
- }
- }
-#endif /* 0 */
-
- /* Now configure the graphics driver with the specified options */
- {
- driver_option_t *option = get_driver_options(active_conf, FREESCI_DRIVER_SUBSYSTEM_GFX, gfx_driver->name);
- while (option) {
- if ((gfx_driver->set_parameter)(gfx_driver, option->option, option->value)) {
- fprintf(stderr, "Fatal error occured in graphics driver while processing \"%s = %s\"\n",
- option->option, option->value);
- exit(1);
- }
-
- option = option->next;
- }
- }
-
-#ifdef __GNUC__
-#warning "sound"
-#endif
-#if 0
- /* Configure the pcmout driver */
- {
- pcmout_sample_rate = active_conf->pcmout_rate;
- pcmout_stereo = active_conf->pcmout_stereo;
- }
-
- /* Configure the midiout driver */
- {
- driver_option_t *option = get_driver_options(active_conf, FREESCI_DRIVER_SUBSYSTEM_MIDIOUT, midiout_driver->name);
- while (option) {
- if ((midiout_driver->set_parameter)(midiout_driver, option->option, option->value)) {
- fprintf(stderr, "Fatal error occured in midiout driver while processing \"%s = %s\"\n",
- option->option, option->value);
- exit(1);
- }
-
- option = option->next;
- }
- }
-#endif
-
- /* Allows drivers to access files in the resource directory. */
- if (chdir(gamestate->resource_dir)) {
- fprintf(stderr,"Error entering resource directory '%s'\n",
- gamestate->resource_dir);
- exit(1);
- }
-
- if (init_gfx(active_conf, &cl_options, gfx_driver, resmgr))
- return 1;
-
-
- if (game_init_graphics(gamestate)) { /* Init interpreter graphics */
- fprintf(stderr,"Game initialization failed: Error in GFX subsystem. Aborting...\n");
- return 1;
- }
-
- if (game_init_sound(gamestate, (cl_options.master_sound == OFF)? SFX_STATE_FLAG_NOSOUND : 0)) {
- fprintf(stderr,"Game initialization failed: Error in sound subsystem. Aborting...\n");
- return 1;
- }
-
- if (chdir(gamestate->work_dir)) {
- fprintf(stderr,"Error entering working directory '%s'\n",
- gamestate->work_dir);
- exit(1);
- }
-
-#ifdef __GNUC__
-#warning "sound"
-#endif
-#if 0
- if (!sound_server)
- sound_server = sound_server_find_driver(NULL);
-#endif
-
- if (cl_options.show_rooms)
- set_debug_mode(gamestate, 1, "r");
-
-#ifdef __GNUC__
-#warning "sound"
-#endif
-#if 0
- gamestate->sound_server = sound_server;
-
- if (gamestate->sound_server) {
- int poly;
- if (gamestate->sound_server->init(
- gamestate,
- ((active_conf->reverse_stereo) ? SOUNDSERVER_INIT_FLAG_REVERSE_STEREO : 0)))
- {
-
- fprintf(stderr,"Sound server initialization failed- aborting.\n");
- return 1;
- }
- sci_sched_yield();
-
- if (!soundserver_dead) {
- poly = gamestate->sound_server->command(gamestate, get_msg_value("SOUND_COMMAND_TEST"), 0, 0);
-
- printf("Sound server reports polyphony %d\n", poly);
-
- gamestate->sound_server->command(gamestate, get_msg_value("SOUND_COMMAND_SET_VOLUME"), 0, 0xc);
-
- }
-
- gamestate->sound_server->get_event(gamestate); /* Get init message */
- /* FIXME: memory allocated that is not freed */
- }
-#endif
-
- if (active_conf && active_conf->console_log)
- open_console_file (active_conf->console_log);
- gamestate->animation_delay = active_conf->animation_delay;
- gamestate->animation_granularity = active_conf->animation_granularity;
- gfx_crossblit_alpha_threshold = active_conf->alpha_threshold;
-
- printf("Emulating SCI version %d.%03d.%03d\n",
- SCI_VERSION_MAJOR(gamestate->version),
- SCI_VERSION_MINOR(gamestate->version),
- SCI_VERSION_PATCHLEVEL(gamestate->version));
-
- printf("Graphics: Using the %s driver %s\n",
- gfx_driver->name, gfx_driver->version);
-#ifdef __GNUC__
-#warning "sound"
-#endif
-#if 0
- printf("MIDI-out: Using the %s driver %s\n",
- midiout_driver->name, midiout_driver->version);
- printf("MIDI-device: Using the %s driver %s\n",
- midi_device->name, midi_device->version);
- printf("PCM-out: Using the %s driver %s\n",
- pcmout_driver->name, pcmout_driver->version);
-
- if (sound_server)
- printf("Sound server: Using the %s sound server %s\n",
- sound_server->name, sound_server->version);
- else
- printf("Sound server: Disabled.\n");
-#endif
-
- gamestate->have_mouse_flag = (cl_options.mouse == DONTCARE)?
- active_conf->mouse : cl_options.mouse;
-
- if (savegame_name)
- game_restore(&gamestate, savegame_name);
- else
- game_run(&gamestate); /* Run the game */
-#ifdef __GNUC__
-#warning "sound"
-#endif
-#if 0
- if (gamestate->sound_server)
- gamestate->sound_server->exit(gamestate); /* Shutdown sound daemon first */
-#endif
-
- game_exit(gamestate);
- script_free_engine(gamestate); /* Uninitialize game state */
- script_free_breakpoints(gamestate);
-
- scir_free_resource_manager(resmgr);
-
- if (conf_entries >= 0)
- config_free(&confs, conf_entries);
-
- close_console_file();
-
- chdir (startdir); /* ? */
-
-#ifdef HAVE_FORK
- printf("Waiting for sound server to die...");
- wait(NULL); /* Wait for sound server process to die, if neccessary */
- printf(" OK.\n");
-#endif
-
- gfxop_exit(gfx_state);
-
- sci_free(gamestate);
-
- if (commandline_config_file)
- sci_free(commandline_config_file);
-
-#ifdef WITH_DMALLOC
- fprintf(stderr,"--- Everything but the two console buffers should have been freed now ---\n");
- dmalloc_log_unfreed();
-/* BREAKPOINT(); */
- ((*(int *)NULL) = 42);
-#endif
- return 0;
-}
-
-
-static int
-game_select_resource_found()
-{
- int fd;
-
- fd = sci_open("resource.map", O_RDONLY | O_BINARY);
- if (IS_VALID_FD(fd))
- {
- close(fd);
- return 1;
- }
-
- return 0;
-}
-
-static int
-game_select_init_gfx(config_entry_t *conf, cl_options_t *cl_options, gfx_driver_t *driver, sci_version_t sci_version)
-{
- int scale_x = 0, scale_y = 0;
- int color_depth = 0;
-
- if (conf) {
- if (conf->scale)
- scale_x = scale_y = conf->scale;
-
- if (conf->x_scale)
- scale_x = conf->x_scale;
-
- if (conf->y_scale)
- scale_y = conf->y_scale;
-
- if (conf->color_depth)
- color_depth = conf->color_depth >> 3; /* In there it's bpp */
- }
-
- gfx_state->driver = driver;
- gfx_state->version = sci_version;
-
- if (cl_options->scale_x > 0) {
- scale_x = cl_options->scale_x;
-
- if (!scale_y)
- scale_y = cl_options->scale_x;
- }
-
- if (cl_options->scale_y > 0) {
- scale_y = cl_options->scale_y;
-
- if (!scale_x)
- scale_x = cl_options->scale_y;
- }
-
- if (cl_options->color_depth > 0)
- color_depth = cl_options->color_depth;
-
- if (color_depth > 0 && scale_x == 0)
- scale_x = scale_y = 2; /* Some default setting */
-
-/* fprintf(stderr, "cd-conf=%d, cd-cl=%d, cd=%d\n",
- conf->color_depth, cl_options->color_depth, color_depth); */
-
- fprintf(stderr, "Checking byte depth %d\n", color_depth);
-
- if (scale_x > 0) {
-
- if (color_depth > 0) {
- if (game_select_gfxop_init(gfx_state, scale_x,
- scale_y, (gfx_color_mode_t) color_depth,
- gfx_options, 0)) {
- fprintf(stderr,"Graphics initialization failed. Aborting...\n");
- return 1;
- }
- } else {
- color_depth = 4;
- while (game_select_gfxop_init(gfx_state, scale_x,
- scale_y, (gfx_color_mode_t) color_depth,
- gfx_options, 0) && --color_depth);
-
- if (!color_depth) {
- fprintf(stderr,"Could not find a matching color depth. Aborting...\n");
- return 1;
- }
- }
-
- } else if (game_select_gfxop_init_default(gfx_state, gfx_options, 0)) {
- fprintf(stderr,"Graphics initialization failed. Aborting...\n");
- return 1;
- }
-
- return 0;
-}
-
-static int compare_games(const void* arg1, const void* arg2)
-{
- game_t* game1 = (game_t *)arg1;
- game_t* game2 = (game_t *)arg2;
-
- return strcmp(game1->name, game2->name);
-}
-
-static gfx_bitmap_font_t* load_font(const char* font_dir, const char* filename)
-{
- gfx_bitmap_font_t* font = NULL;
- int fh;
- int fsize;
- byte* buffer;
- char work_dir[256];
-
- getcwd(work_dir, 256);
-
- /* change to the font directory */
- chdir(font_dir);
-
- fh = sci_open(filename, O_RDONLY|O_BINARY);
-
- if (!IS_VALID_FD(fh))
- return NULL;
-
- fsize = sci_fd_size(fh);
-
- buffer = (byte *) sci_malloc(fsize);
-
- /* skip the header information, is present by default when using sciunpack */
- read(fh, buffer, 2);
-
- /* read the font data */
- read(fh, buffer, fsize);
-
- font = gfxr_read_font(0, buffer, fsize);
-
- sci_free(buffer);
-
- close(fh);
-
- chdir(work_dir);
-
- return font;
-}
-
-#define FONT_DEFAULT "default.fnt"
-#define FONT_SMALL "small.fnt"
-
-static void
-add_games(const char *dir_name, games_list_head_t *head, int *games, gfx_driver_t *driver,
- gfx_bitmap_font_t* font_default, gfx_bitmap_font_t* font_small)
-{
- sci_dir_t dir;
- char *filename;
- int fd;
-
- if (chdir(dir_name))
- return;
-
- fd = sci_open("resource.map", O_RDONLY);
-
- if (IS_VALID_FD(fd)) {
- games_list_t *list;
- sci_version_t result;
- int res_version;
- const char *game_name;
- guint32 code;
-
- close(fd);
-
- list = (games_list_t*)sci_malloc(sizeof(games_list_t));
- getcwd(list->game.dir, PATH_MAX);
- game_name = version_guess_from_hashcode(&result, &res_version, &code);
-
- if (game_name)
- list->game.name = sci_strdup(game_name);
- else
- list->game.name = sci_strdup(dir_name);
-
- list->game.conf_nr = 0;
- LIST_INSERT_HEAD(head, list, entries);
- (*games)++;
-
- game_select_scan_info(driver, font_default, font_small, list->game.name, *games);
- }
-
- sci_init_dir(&dir);
-
- filename = sci_find_first(&dir, "*");
-
- while (filename) {
- add_games(filename, head, games, driver, font_default, font_small);
- filename = sci_find_next(&dir);
- }
-
- sci_finish_find(&dir);
- chdir("..");
-
- return;
-}
-
-static int
-find_games(const char* dir, game_t **games, gfx_driver_t *driver, gfx_bitmap_font_t* font_default, gfx_bitmap_font_t* font_small)
-{
- games_list_head_t head;
- int games_nr = 0;
- games_list_t *list;
- int i;
-
- game_select_scan_info(driver, font_default, font_small, NULL, 0);
-
- LIST_INIT(&head);
- add_games(dir, &head, &games_nr, driver, font_default, font_small);
-
- if (!games_nr)
- return 0;
-
- *games = (game_t*)sci_malloc(sizeof(game_t) * games_nr);
-
- i = 0;
- while ((list = LIST_FIRST(&head))) {
- (*games)[i++] = list->game;
- LIST_REMOVE(list, entries);
- sci_free(list);
- }
-
- return games_nr;
-}
-
-static int game_select(cl_options_t cl_options, config_entry_t *confs, int conf_entries, const char* freesci_dir, const char *games_dir) {
- char start_dir[PATH_MAX+1] = "";
- char *gfx_driver_name = NULL;
- gfx_driver_t *gfx_driver = NULL;
- const char *module_path = SCI_DEFAULT_MODULE_PATH;
- int selected_game = -1;
- gfx_bitmap_font_t* font_default;
- gfx_bitmap_font_t* font_small;
- int font_default_allocated = 0;
- int font_small_allocated = 0;
- game_t *games = NULL;
- int games_nr;
- int i;
-
- getcwd(start_dir, PATH_MAX);
- script_debug_flag = cl_options.script_debug_flag;
-
- /* gcc doesn't warn about (void *)s being typecast. If your compiler doesn't like these
- ** implicit casts, don't hesitate to typecast appropriately. */
- if (cl_options.gfx_driver_name) {
- gfx_driver_name = sci_strdup(cl_options.gfx_driver_name);
- /* free(cl_options.gfx_driver_name); */
- } /* else it's still NULL */
-
- if (confs) {
- memcpy(gfx_options, &(confs->gfx_options), sizeof(gfx_options_t)); /* memcpy so that console works */
- if (!gfx_driver_name)
- gfx_driver_name = confs->gfx_driver_name;
- }
-
- if (confs) {
- module_path = confs->module_path;
-
- if (!gfx_driver_name)
- gfx_driver_name = confs->gfx_driver_name;
- }
-
- gfx_driver = (gfx_driver_t *)
- lookup_driver((lookup_funct_t *)gfx_find_driver,
- MSVC_FUNCTYPECAST_KLUDGE list_graphics_drivers,
- "graphics driver", gfx_driver_name, module_path);
-
- if (!gfx_driver) {
- if (gfx_driver_name)
- fprintf(stderr,"Failed to find graphics driver \"%s\"\n"
- "Please run 'freesci -v' to get a list of all "
- "available drivers.\n", gfx_driver_name);
- else
- fprintf(stderr,"No default gfx driver available.\n");
-
- return -2;
- }
-
-
- /* Now configure the graphics driver with the specified options */
- {
- driver_option_t *option = get_driver_options(confs, FREESCI_DRIVER_SUBSYSTEM_GFX, gfx_driver->name);
- while (option) {
- if ((gfx_driver->set_parameter)(gfx_driver, option->option, option->value)) {
- fprintf(stderr, "Fatal error occured in graphics driver while processing \"%s = %s\"\n",
- option->option, option->value);
- exit(1);
- }
-
- option = option->next;
- }
- }
-
- if (game_select_init_gfx(confs, &cl_options, gfx_driver, 0))
- return -2;
-
- /* load user supplied font from disk, if not found then use built-in font */
- font_default = load_font(freesci_dir, FONT_DEFAULT);
- if (!font_default)
- font_default = gfxr_get_font(NULL, GFX_FONT_BUILTIN_6x10, 0);
- else
- font_default_allocated = 1;
-
- /* load user supplied font from disk, if not found then use built-in font */
- font_small = load_font(freesci_dir, FONT_SMALL);
- if (!font_small)
- font_small = gfxr_get_font(NULL, GFX_FONT_BUILTIN_5x8, 0);
- else
- font_small_allocated = 1;
-
- chdir(start_dir);
-
- if (games_dir)
- games_nr = find_games(games_dir, &games, gfx_driver, font_default, font_small);
- else
- games_nr = 0;
-
- games = (game_t*)sci_realloc(games, sizeof(game_t) * (games_nr + conf_entries));
-
- for (i = 0; i < conf_entries; i++) {
- if (confs[i].name) {
- char *c;
-
- games[games_nr].name = sci_strdup(confs[i].name);
- games[games_nr].conf_nr = i;
- /* Replace all '_'with ' ' */
-
- c = games[games_nr].name;
- while (*c != 0)
- {
- if (*c == '_')
- *c = ' ';
- c++;
- }
- strncpy(games[games_nr].dir, confs[i].resource_dir, PATH_MAX - 1);
- games[games_nr++].dir[PATH_MAX - 1] = 0;
- }
- }
-
- /* Sort game list */
- qsort(games, games_nr, sizeof(game_t), compare_games);
-
- /* Index of game selected is returned - -1 means no selection (quit) */
- selected_game = game_select_display(gfx_driver, games, games_nr, font_default, font_small);
- if (selected_game >= 0)
- {
- chdir(games[selected_game].dir);
- }
-
- if (font_default_allocated == 1)
- gfxr_free_font(font_default);
-
- if (font_small_allocated == 1)
- gfxr_free_font(font_small);
-
- if (selected_game >= 0)
- selected_game = games[selected_game].conf_nr;
-
- for (i = 0; i < games_nr; i++)
- sci_free(games[i].name);
- sci_free(games);
-
- gfx_driver->exit(gfx_driver);
-
- return selected_game;
-}
diff --git a/engines/sci/module.mk b/engines/sci/module.mk
index 18fa897aaa..3b58b0b053 100644
--- a/engines/sci/module.mk
+++ b/engines/sci/module.mk
@@ -16,6 +16,7 @@ MODULE_OBJS = \
engine/kscripts.o \
engine/ksound.o \
engine/kstring.o \
+ engine/message.o \
engine/said.o \
engine/savegame.o \
engine/scriptconsole.o \
@@ -83,7 +84,6 @@ MODULE_OBJS = \
sfx/player/realtime.o \
sfx/seq/sequencers.o \
sfx/softseq/amiga.o \
- sfx/softseq/fmopl.o \
sfx/softseq/opl2.o \
sfx/softseq/pcspeaker.o \
sfx/softseq/SN76496.o \
diff --git a/engines/sci/scicore/sci_dos.c b/engines/sci/scicore/sci_dos.c
deleted file mode 100644
index 0435afa32b..0000000000
--- a/engines/sci/scicore/sci_dos.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/***************************************************************************
- sci_dos.c Copyright (C) 1999 Rink Springer
-
- This program may be modified and copied freely according to the terms of
- the GNU general public license (GPL), as long as the above copyright
- notice and the licensing information contained herein are preserved.
-
- Please refer to www.gnu.org for licensing details.
-
- This work is provided AS IS, without warranty of any kind, expressed or
- implied, including but not limited to the warranties of merchantibility,
- noninfringement, and fitness for a specific purpose. The author will not
- be held liable for any damage caused by this work or derivatives of it.
-
- By using this source code, you agree to the licensing terms as stated
- above.
-
-
- Please contact the maintainer for bug reports or inquiries.
-
- Current Maintainer:
-
- Rink Springer [rink@springer.cx]
-
-***************************************************************************/
-
-#include <stdlib.h>
-#include <sci_dos.h>
-#include <string.h>
-
-#define G_VA_COPY(ap1, ap2) ((ap1) = (ap2))
-
-gpointer
-malloc0(guint32 size) {
- char* ptr;
-
- /* allocate the buffer, return NULL if no buffer */
- if((ptr= sci_malloc(size))==NULL) return NULL;
-
- /* clear it to zeros */
- memset(ptr,0,size);
-
- /* return the pointer */
- return ptr;
-}
-
-guint
-g_printf_string_upper_bound (const gchar* format,
- va_list args)
-{
- guint len = 1;
-
- while (*format)
- {
- gboolean long_int = FALSE;
- gboolean extra_long = FALSE;
- gchar c;
-
- c = *format++;
-
- if (c == '%')
- {
- gboolean done = FALSE;
-
- while (*format && !done)
- {
- switch (*format++)
- {
- gchar *string_arg;
-
- case '*':
- len += va_arg (args, int);
- break;
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- /* add specified format length, since it might exceed the
- * size we assume it to have.
- */
- format -= 1;
- len += strtol (format, (char**) &format, 10);
- break;
- case 'h':
- /* ignore short int flag, since all args have at least the
- * same size as an int
- */
- break;
- case 'l':
- if (long_int)
- extra_long = TRUE; /* linux specific */
- else
- long_int = TRUE;
- break;
- case 'q':
- case 'L':
- long_int = TRUE;
- extra_long = TRUE;
- break;
- case 's':
- string_arg = va_arg (args, char *);
- if (string_arg)
- len += strlen (string_arg);
- else
- {
- /* add enough padding to hold "(null)" identifier */
- len += 16;
- }
- done = TRUE;
- break;
- case 'd':
- case 'i':
- case 'o':
- case 'u':
- case 'x':
- case 'X':
- {
- if (long_int)
- (void) va_arg (args, long);
- else
- (void) va_arg (args, int);
- }
- len += extra_long ? 64 : 32;
- done = TRUE;
- break;
- case 'D':
- case 'O':
- case 'U':
- (void) va_arg (args, long);
- len += 32;
- done = TRUE;
- break;
- case 'e':
- case 'E':
- case 'f':
- case 'g':
- (void) va_arg (args, double);
- len += extra_long ? 64 : 32;
- done = TRUE;
- break;
- case 'c':
- (void) va_arg (args, int);
- len += 1;
- done = TRUE;
- break;
- case 'p':
- case 'n':
- (void) va_arg (args, void*);
- len += 32;
- done = TRUE;
- break;
- case '%':
- len += 1;
- done = TRUE;
- break;
- default:
- /* ignore unknow/invalid flags */
- break;
- }
- }
- }
- else
- len += 1;
- }
-
-return len;
-}
-
-gchar*
-g_strdup_vprintf (const gchar *format,
- va_list args1) {
- gchar *buffer;
- va_list args2;
-
- G_VA_COPY (args2, args1);
-
- buffer = g_new (gchar, g_printf_string_upper_bound (format, args1));
-
- vsprintf (buffer, format, args2);
- va_end (args2);
-
- return buffer;
-}
-
-gint
-g_vsnprintf (gchar *str,
- gulong n,
- gchar const *fmt,
- va_list args) {
- gchar* printed;
-
-
- printed = g_strdup_vprintf (fmt, args);
- strncpy (str, printed, n);
- str[n-1] = '\0';
-
- free (printed);
-
- return strlen (str);
-}
-
-gpointer
-g_memdup (gpointer mem, guint byte_size) {
- gpointer new_mem;
-
- if (mem) {
- new_mem = sci_malloc (byte_size);
- memcpy (new_mem, mem, byte_size);
- } else {
- new_mem = NULL;
- }
-
- return new_mem;
-}
diff --git a/engines/sci/sfx/old/Makefile b/engines/sci/sfx/old/Makefile
deleted file mode 100644
index f7235d945b..0000000000
--- a/engines/sci/sfx/old/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-CC = gcc
-CFLAGS = -O2 -Wall
-LIBS = -L/usr/lib -lasound
-objects = main.o midi_mt32.o midiout.o midiout_unixraw.o midiout_alsaraw.o
-
-sciplaymidi: $(objects)
- $(CC) $(LIBS) -o sciplaymidi $(objects)
-
-main.o: main.c
- $(CC) $(CFLAGS) -c main.c
-midi_mt32.o: midi_mt32.c midi_mt32.h midiout.h
- $(CC) $(CFLAGS) -c midi_mt32.c
-midiout.o: midiout.c midiout.h midiout_unixraw.h midiout_alsaraw.h
- $(CC) $(CFLAGS) -c midiout.c
-midiout_unixraw.o: midiout_unixraw.c midiout_unixraw.h
- $(CC) $(CFLAGS) -c midiout_unixraw.c
-midiout_alsaraw.o: midiout_alsaraw.c midiout_alsaraw.h
- $(CC) $(CFLAGS) -c midiout_alsaraw.c
-
-.PHONY: clean distclean
-clean:
- rm -f sciplaymidi $(objects)
-distclean:
- rm -f sciplaymidi $(objects) *~
diff --git a/engines/sci/sfx/old/README b/engines/sci/sfx/old/README
deleted file mode 100644
index c652175761..0000000000
--- a/engines/sci/sfx/old/README
+++ /dev/null
@@ -1,6 +0,0 @@
-type 'make' and './sciplaymidi' to program your MT-32 with the file
-'patch.001' in the current directory
-
-Only tested with Linux and ALSA...
-
-Rickard Lind <rpl@dd.chalmers.se>
diff --git a/engines/sci/sfx/old/ROADMAP b/engines/sci/sfx/old/ROADMAP
deleted file mode 100644
index 9a6ec1b4da..0000000000
--- a/engines/sci/sfx/old/ROADMAP
+++ /dev/null
@@ -1,72 +0,0 @@
-The way I would have made things if I had the time to do it
-Rickard Lind <rpl@dd.chalmers.se>, 2000-12-30
--------------------------------------------------------------------------------
-
-Step 1:
-
-D rename "src/sound/midi.c" in freesci to "oldmidi.c" and still use it
-D move my "midi*" and "midiout*" to "src/sound"
-D change all "glib.h" to the real thing
-
-Step 2:
-
-D implement all note-playing, volume changing, reverb etc in "midi_mt32.*"
- use disassembled sierra SCI1.1 driver as the main source of inspiration
-D change "soundserver_null.c" to use the new device driver for MT-32
-* use "~/.freesci/config" to set ALSA/OSS and other options
-
-Step 3:
-
-* Implement a GM translation driver "midi_gm.*" using a parsed textfile
- for instrument mapping
-* Improve instrument mappings using new features such as keyshift,
- volume adjust and velocity remap
-
-Step 4:
-
-* Reimplement a SCI0 soundserver using the new sound sub sytem
-* PCM support (samples) with ALSA and possibly DirectX
-* MPU-401 UART midiout driver for DOS/Windows
-
-Step 5:
-
-* SCI01, SCI1, SCI32 soundserver
-* Adlib support "midi_opl2.*", "oplout_alsaraw.*", "oplout_pcmemu.*"
-* PCM support Sound Blaster DOS
-
-Step 6:
-
-* Make it possible to play samples and use opl2 emulation (found in MAME
- I think) at the same time through the same sound device
-
-Step 7:
-
-* All those other little nifty things...
-
--------------------------------------------------------------------------------
-
-My idea concerning naming of the files:
-
-src/sound/midi.* wrapper for MIDI device drivers
-src/sound/midiout.* wrapper for different methods to output
- MIDI data
-src/sound/pcm.* wrapper for PCM device drivers
-src/sound/pcmout.* wrapper for different methods to output
- PCM data
-src/sound/midi_mt32.* Roland MT-32 device driver
-src/sound/midi_opl2.* Adlib/OPL2 device driver
-src/sound/midiout_alsaraw.* rawmidi output using alsalib
-src/sound/midiout_unixraw.* rawmidi output using unix filesystem
-src/sound/oplout_alsaraw.* opl output using alsa
-
--------------------------------------------------------------------------------
-
-Use Linux and ALSA 0.5.x (or later) and Roland MT-32 while developing.
-Don't implement supremely stupid abstract frameworks without consulting
-experienced people on the mailinglist first. There are infinite ways to
-implement the sound subsystem the VERY VERY WRONG way. Don't make
-everything too much of a hack either.
-
-Use the files is in "lists/" when doing text output for debugging purposes.
-
-Good luck!
diff --git a/engines/sci/sfx/old/main.c b/engines/sci/sfx/old/main.c
deleted file mode 100644
index 73daebd1bb..0000000000
--- a/engines/sci/sfx/old/main.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/***************************************************************************
- main.c Copyright (C) 2000 Rickard Lind
-
-
- This program may be modified and copied freely according to the terms of
- the GNU general public license (GPL), as long as the above copyright
- notice and the licensing information contained herein are preserved.
-
- Please refer to www.gnu.org for licensing details.
-
- This work is provided AS IS, without warranty of any kind, expressed or
- implied, including but not limited to the warranties of merchantibility,
- noninfringement, and fitness for a specific purpose. The author will not
- be held liable for any damage caused by this work or derivatives of it.
-
- By using this source code, you agree to the licensing terms as stated
- above.
-
-***************************************************************************/
-
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include "midi_mt32.h"
-
-int main()
-{
- int fd;
- unsigned char *patch;
- unsigned int length;
-
- patch = (unsigned char *)sci_malloc(65536);
-
- fd = open("patch.001", O_RDONLY);
- length = read(fd, patch, 65536);
- close(fd);
-
- if (patch[0] == 0x89 && patch[1] == 0x00)
- midi_mt32_open(patch + 2, length - 2);
- else
- midi_mt32_open(patch, length);
-
- midi_mt32_close();
-
- free(patch);
- return 0;
-}
diff --git a/engines/sci/sfx/old/midi.c b/engines/sci/sfx/old/midi.c
deleted file mode 100644
index 1be951befb..0000000000
--- a/engines/sci/sfx/old/midi.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/***************************************************************************
- midi.c Copyright (C) 2000 Rickard Lind
-
-
- This program may be modified and copied freely according to the terms of
- the GNU general public license (GPL), as long as the above copyright
- notice and the licensing information contained herein are preserved.
-
- Please refer to www.gnu.org for licensing details.
-
- This work is provided AS IS, without warranty of any kind, expressed or
- implied, including but not limited to the warranties of merchantibility,
- noninfringement, and fitness for a specific purpose. The author will not
- be held liable for any damage caused by this work or derivatives of it.
-
- By using this source code, you agree to the licensing terms as stated
- above.
-
-***************************************************************************/
-
-#ifndef _MIDI_MT32_H_
-#define _MIDI_MT32_H_
-
-int midi_mt32_open(guint8 *data_ptr, unsigned int data_length);
-int midi_mt32_close();
-
-int midi_mt32_noteoff(guint8 channel, guint8 note);
-int midi_mt32_noteon(guint8 channel, guint8 note, guint8 velocity);
-
-#endif /* _MIDI_MT32_H_ */
diff --git a/engines/sci/sfx/old/midi.h b/engines/sci/sfx/old/midi.h
deleted file mode 100644
index 9a816781d3..0000000000
--- a/engines/sci/sfx/old/midi.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/***************************************************************************
- midi.h Copyright (C) 2000 Rickard Lind
-
-
- This program may be modified and copied freely according to the terms of
- the GNU general public license (GPL), as long as the above copyright
- notice and the licensing information contained herein are preserved.
-
- Please refer to www.gnu.org for licensing details.
-
- This work is provided AS IS, without warranty of any kind, expressed or
- implied, including but not limited to the warranties of merchantibility,
- noninfringement, and fitness for a specific purpose. The author will not
- be held liable for any damage caused by this work or derivatives of it.
-
- By using this source code, you agree to the licensing terms as stated
- above.
-
-***************************************************************************/
-
-#ifndef _MIDI_H_
-#define _MIDI_H_
-
-int midi_open(guint8 *data_ptr, unsigned int data_length);
-int midi_close();
-
-int midi_noteoff(guint8 channel, guint8 note);
-int midi_noteon(guint8 channel, guint8 note, guint8 velocity);
-
-#endif /* _MIDI_H_ */
diff --git a/engines/sci/sfx/old/midi_mt32.c b/engines/sci/sfx/old/midi_mt32.c
deleted file mode 100644
index be5550bd93..0000000000
--- a/engines/sci/sfx/old/midi_mt32.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/***************************************************************************
- midi_mt32.c Copyright (C) 2000 Rickard Lind
-
-
- This program may be modified and copied freely according to the terms of
- the GNU general public license (GPL), as long as the above copyright
- notice and the licensing information contained herein are preserved.
-
- Please refer to www.gnu.org for licensing details.
-
- This work is provided AS IS, without warranty of any kind, expressed or
- implied, including but not limited to the warranties of merchantibility,
- noninfringement, and fitness for a specific purpose. The author will not
- be held liable for any damage caused by this work or derivatives of it.
-
- By using this source code, you agree to the licensing terms as stated
- above.
-
-***************************************************************************/
-
-#include "glib.h"
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include "midi_mt32.h"
-#include "midiout.h"
-
-#define RHYTHM_CHANNEL 9
-
-int midi_mt32_poke(guint32 address, guint8 *data, unsigned int n);
-int midi_mt32_poke_gather(guint32 address, guint8 *data1, unsigned int count1,
- guint8 *data2, unsigned int count2);
-int midi_mt32_write_block(guint8 *data, unsigned int count);
-int midi_mt32_patch001_type(guint8 *data, unsigned int length);
-int midi_mt32_patch001_type0_length(guint8 *data, unsigned int length);
-int midi_mt32_patch001_type1_length(guint8 *data, unsigned int length);
-int midi_mt32_sysex_delay();
-
-static guint8 *data;
-static unsigned int length;
-static int type;
-static guint8 sysex_buffer[266] = {0xF0, 0x41, 0x10, 0x16, 0x12};
-
-static gint8 patch_map[128] = {
- 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
- 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
- 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
- 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
- 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
- 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
- 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
- 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127};
-static gint8 keyshift[128] = {
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-static gint8 volume_adjust[128] = {
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-static guint8 velocity_map_index[128] = {
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-static guint8 velocity_map[4][128] = {
- {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
- 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
- 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
- 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
- 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
- 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
- 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
- 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127},
- {0,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,
- 39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,
- 47,48,48,49,49,50,50,51,51,52,52,53,53,54,54,55,
- 55,56,56,57,57,58,58,59,59,60,60,61,61,62,62,63,
- 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
- 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
- 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
- 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127},
- {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
- 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
- 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
- 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
- 64,65,66,66,67,67,68,68,69,69,70,70,71,71,72,72,
- 73,73,74,74,75,75,76,76,77,77,78,78,79,79,80,80,
- 81,81,82,82,83,83,84,84,85,85,86,86,87,87,88,88,
- 89,89,90,90,91,91,92,92,93,93,94,94,95,95,96,96},
- {0,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,
- 39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,
- 47,48,48,49,49,50,50,51,51,52,52,53,53,54,54,55,
- 55,56,56,57,57,58,58,59,59,60,60,61,61,62,62,63,
- 64,65,66,66,67,67,68,68,69,69,70,70,71,71,72,72,
- 73,73,74,74,75,75,76,76,77,77,78,78,79,79,80,80,
- 81,81,82,82,83,83,84,84,85,85,86,86,87,87,88,88,
- 89,89,90,90,91,91,92,92,93,93,94,94,95,95,96,96}};
-static gint8 rhythmkey_map[128] = {
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,35,36,37,38,39,40,41,42,43,44,45,46,47,
- 48,49,50,51,-1,-1,54,-1,56,-1,-1,-1,60,61,62,63,
- 64,65,66,67,68,69,70,71,72,73,-1,75,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
-/* static struct {
- gint8 sci_patch;
- gint8 sci_volume;
- gint8 sci_pitchwheel;
- gint8 patch;
- gint8 keyshift;
- gint8 volume_adjust;
- guint8 velocity_map_index;
- guint8
-} channel[16]; */
-static guint8 master_volume;
-
-int midi_mt32_open(guint8 *data_ptr, unsigned int data_length)
-{
- guint8 unknown_sysex[6] = {0x16, 0x16, 0x16, 0x16, 0x16, 0x16};
- guint8 i, memtimbres;
- unsigned int block2, block3;
-
- if (midiout_open() < 0)
- return -1;
-
- data = data_ptr;
- length = data_length;
-
- type = midi_mt32_patch001_type(data, length);
- printf("MT-32: Programming Roland MT-32 with patch.001 (v%i)\n", type);
-
- if (type == 0) {
- /* Display MT-32 initialization message */
- printf("MT-32: Displaying Text: \"%.20s\"\n", data + 20);
- midi_mt32_poke(0x200000, data + 20, 20);
- midi_mt32_sysex_delay();
-
- /* Write Patches (48 or 96) */
- memtimbres = data[491];
- block2 = (memtimbres * 246) + 492;
- printf("MT-32: Writing Patches #01 - #32\n");
- midi_mt32_poke(0x050000, data + 107, 256);
- midi_mt32_sysex_delay();
- if ((length > block2) &&
- data[block2] == 0xAB &&
- data[block2 + 1] == 0xCD) {
- printf("MT-32: Writing Patches #33 - #64\n");
- midi_mt32_poke_gather(0x050200, data + 363, 128, data + block2 + 2, 128);
- midi_mt32_sysex_delay();
- printf("MT-32: Writing Patches #65 - #96\n");
- midi_mt32_poke(0x050400, data + block2 + 130, 256);
- midi_mt32_sysex_delay();
- block3 = block2 + 386;
- } else {
- printf("MT-32: Writing Patches #33 - #48\n");
- midi_mt32_poke(0x050200, data + 363, 128);
- midi_mt32_sysex_delay();
- block3 = block2;
- }
- /* Write Memory Timbres */
- for (i = 0; i < memtimbres; i++) {
- printf("MT-32: Writing Memory Timbre #%02d: \"%.10s\"\n",
- i + 1, data + 492 + i * 246);
- midi_mt32_poke(0x080000 + (i << 9), data + 492 + i * 246, 246);
- midi_mt32_sysex_delay();
- }
- /* Write Rhythm key map and Partial Reserve */
- if ((length > block3) &&
- data[block3] == 0xDC &&
- data[block3 + 1] == 0xBA) {
- printf("MT-32: Writing Rhythm key map\n");
- midi_mt32_poke(0x030110, data + block3 + 2, 256);
- midi_mt32_sysex_delay();
- printf("MT-32: Writing Partial Reserve\n");
- midi_mt32_poke(0x100004, data + block3 + 258, 9);
- midi_mt32_sysex_delay();
- }
- /* Display MT-32 initialization done message */
- printf("MT-32: Displaying Text: \"%.20s\"\n", data);
- midi_mt32_poke(0x200000, data, 20);
- midi_mt32_sysex_delay();
- /* Write undocumented MT-32(?) SysEx */
- printf("MT-32: Writing {F0 41 10 16 12 52 00 0A 16 16 16 16 16 16 20 F7}\n");
- midi_mt32_poke(0x52000A, unknown_sysex, 6);
- midi_mt32_sysex_delay();
- return 0;
- } else if (type == 1) {
- midi_mt32_write_block(data + 1155, (data[1154] << 8) + data[1153]);
- memcpy(patch_map, data, 128);
- memcpy(keyshift, data + 128, 128);
- memcpy(volume_adjust, data + 256, 128);
- memcpy(velocity_map_index, data + 513, 128);
- for (i = 0; i < 4; i++)
- memcpy(velocity_map[i], data + 641 + i * 128, 128);
- memcpy(rhythmkey_map, data + 384, 128);
- return 0;
- }
- return -1;
-}
-
-int midi_mt32_close()
-{
-if (type == 0) {
- printf("MT-32: Displaying Text: \"%.20s\"\n", data + 40);
- midi_mt32_poke(0x200000, data + 40, 20);
- midi_mt32_sysex_delay();
-}
-return midiout_close();
-}
-
-int midi_mt32_noteoff(guint8 channel, guint8 note)
-{
- return 0;
-}
-
-int midi_mt32_noteon(guint8 channel, guint8 note, guint8 velocity)
-{
-/* guint8 buffer[3] = {0x90};
- if (channel == RHYTHM_CHANNEL)
- if (rhythmkey_map[note] == -1)
- return 0;
- else {
- buffer[0] |= channel
- buffer[1] = rhythmkey_map[note];
- buffer[2] = velo
- midi_write_event(buffer, 3);
- }; */
- return 0;
-}
-
-int midi_mt32_poke(guint32 address, guint8 *data, unsigned int count)
-{
- guint8 checksum = 0;
- unsigned int i;
-
- if (count > 256) return -1;
-
- checksum -= (sysex_buffer[5] = (char)((address >> 16) & 0x7F));
- checksum -= (sysex_buffer[6] = (char)((address >> 8) & 0x7F));
- checksum -= (sysex_buffer[7] = (char)(address & 0x7F));
-
- for (i = 0; i < count; i++)
- checksum -= (sysex_buffer[i + 8] = data[i]);
-
- sysex_buffer[count + 8] = checksum & 0x7F;
- sysex_buffer[count + 9] = 0xF7;
-
- return midiout_write_block(sysex_buffer, count + 10);
-}
-
-int midi_mt32_poke_gather(guint32 address, guint8 *data1, unsigned int count1,
- guint8 *data2, unsigned int count2)
-{
- guint8 checksum = 0;
- unsigned int i;
-
- if ((count1 + count2) > 256) return -1;
-
- checksum -= (sysex_buffer[5] = (char)((address >> 16) & 0x7F));
- checksum -= (sysex_buffer[6] = (char)((address >> 8) & 0x7F));
- checksum -= (sysex_buffer[7] = (char)(address & 0x7F));
-
- for (i = 0; i < count1; i++)
- checksum -= (sysex_buffer[i + 8] = data1[i]);
- for (i = 0; i < count2; i++)
- checksum -= (sysex_buffer[i + 8 + count1] = data2[i]);
-
- sysex_buffer[count1 + count2 + 8] = checksum & 0x7F;
- sysex_buffer[count1 + count2 + 9] = 0xF7;
-
- return midiout_write_block(sysex_buffer, count1 + count2 + 10);
-}
-
-int midi_mt32_write_block(guint8 *data, unsigned int count)
-{
- unsigned int block_start = 0;
- unsigned int i = 0;
-
- while (i < count) {
- if ((data[i] == 0xF0) && (i != block_start)) {
- midiout_write_block(data + block_start, i - block_start);
- block_start = i;
- }
- if (data[i] == 0xF7) {
- midiout_write_block(data + block_start, i - block_start + 1);
- midi_mt32_sysex_delay();
- block_start = i + 1;
- }
- i++;
- }
- if (count >= block_start)
- midiout_write_block(data + block_start, count - block_start);
- return 0;
-}
-
-int midi_mt32_patch001_type(guint8 *data, unsigned int length)
-{
- /* length test */
- if (length < 1155)
- return 0;
- if (length > 16889)
- return 1;
- if (midi_mt32_patch001_type0_length(data, length) &&
- !midi_mt32_patch001_type1_length(data, length))
- return 0;
- if (midi_mt32_patch001_type1_length(data, length) &&
- !midi_mt32_patch001_type0_length(data, length))
- return 1;
- return -1;
-}
-
-int midi_mt32_patch001_type0_length(guint8 *data, unsigned int length)
-{
- unsigned int pos = 492 + 246 * data[491];
-
- if ((length >= (pos + 386)) && (data[pos] == 0xAB) && (data[pos + 1] == 0xCD))
- pos += 386;
- if ((length >= (pos + 267)) && (data[pos] == 0xDC) && (data[pos + 1] == 0xBA))
- pos += 267;
- if (pos == length)
- return 1;
- return 0;
-}
-
-int midi_mt32_patch001_type1_length(guint8 *data, unsigned int length)
-{
- if ((length >= 1155) && (((data[1154] << 8) + data[1153] + 1155) == length))
- return 1;
- return 0;
-}
-
-int midi_mt32_sysex_delay()
-{
- usleep(320 * 63); /* One MIDI byte is 320us, 320us * 63 > 20ms */
- return 0;
-}
diff --git a/engines/sci/sfx/old/midi_mt32.h b/engines/sci/sfx/old/midi_mt32.h
deleted file mode 100644
index 0e14efd41d..0000000000
--- a/engines/sci/sfx/old/midi_mt32.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/***************************************************************************
- midi_mt32.h Copyright (C) 2000 Rickard Lind
-
-
- This program may be modified and copied freely according to the terms of
- the GNU general public license (GPL), as long as the above copyright
- notice and the licensing information contained herein are preserved.
-
- Please refer to www.gnu.org for licensing details.
-
- This work is provided AS IS, without warranty of any kind, expressed or
- implied, including but not limited to the warranties of merchantibility,
- noninfringement, and fitness for a specific purpose. The author will not
- be held liable for any damage caused by this work or derivatives of it.
-
- By using this source code, you agree to the licensing terms as stated
- above.
-
-***************************************************************************/
-
-#ifndef _MIDI_MT32_H_
-#define _MIDI_MT32_H_
-
-#include "glib.h"
-
-int midi_mt32_open(guint8 *data_ptr, unsigned int data_length);
-int midi_mt32_close();
-
-#endif /* _MIDI_MT32_H_ */
diff --git a/engines/sci/sfx/old/midiout.c b/engines/sci/sfx/old/midiout.c
deleted file mode 100644
index 262836baba..0000000000
--- a/engines/sci/sfx/old/midiout.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/***************************************************************************
- midiout.c Copyright (C) 2000 Rickard Lind
-
-
- This program may be modified and copied freely according to the terms of
- the GNU general public license (GPL), as long as the above copyright
- notice and the licensing information contained herein are preserved.
-
- Please refer to www.gnu.org for licensing details.
-
- This work is provided AS IS, without warranty of any kind, expressed or
- implied, including but not limited to the warranties of merchantibility,
- noninfringement, and fitness for a specific purpose. The author will not
- be held liable for any damage caused by this work or derivatives of it.
-
- By using this source code, you agree to the licensing terms as stated
- above.
-
-***************************************************************************/
-
-#include "glib.h"
-#include "midiout.h"
-#include "midiout_alsaraw.h"
-#include "midiout_unixraw.h"
-
-static int (*midiout_ptr_close)();
-static int (*midiout_ptr_write)(guint8 *, unsigned int);
-
-static unsigned char running_status = 0;
-
-int midiout_open()
-{
- midiout_ptr_close = midiout_alsaraw_close;
- midiout_ptr_write = midiout_alsaraw_write;
- return midiout_alsaraw_open(0, 0);
-
- /*
- midiout_ptr_close = midiout_unixraw_close;
- midiout_ptr_write = midiout_unixraw_write;
- return midiout_unixraw_open("/dev/midi00");
- */
-}
-
-int midiout_close()
-{
- return midiout_ptr_close();
-}
-
-int midiout_write_event(guint8 *buffer, unsigned int count)
-{
- if (buffer[0] == running_status)
- return midiout_ptr_write(buffer + 1, count - 1);
- else {
- running_status = buffer[0];
- return midiout_ptr_write(buffer, count);
- }
-}
-
-int midiout_write_block(guint8 *buffer, unsigned int count)
-{
- running_status = 0;
- return midiout_ptr_write(buffer, count);
-}
diff --git a/engines/sci/sfx/old/midiout.h b/engines/sci/sfx/old/midiout.h
deleted file mode 100644
index e0ce3915ae..0000000000
--- a/engines/sci/sfx/old/midiout.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/***************************************************************************
- midiout.h Copyright (C) 2000 Rickard Lind
-
-
- This program may be modified and copied freely according to the terms of
- the GNU general public license (GPL), as long as the above copyright
- notice and the licensing information contained herein are preserved.
-
- Please refer to www.gnu.org for licensing details.
-
- This work is provided AS IS, without warranty of any kind, expressed or
- implied, including but not limited to the warranties of merchantibility,
- noninfringement, and fitness for a specific purpose. The author will not
- be held liable for any damage caused by this work or derivatives of it.
-
- By using this source code, you agree to the licensing terms as stated
- above.
-
-***************************************************************************/
-
-#ifndef _MIDIOUT_H_
-#define _MIDIOUT_H_
-
-int midiout_open();
-int midiout_close();
-int midiout_write_event(guint8 *buffer, unsigned int count);
-int midiout_write_block(guint8 *buffer, unsigned int count);
-
-#endif /* _MIDIOUT_H_ */
diff --git a/engines/sci/sfx/old/midiout_alsaraw.c b/engines/sci/sfx/old/midiout_alsaraw.c
deleted file mode 100644
index e95aa28425..0000000000
--- a/engines/sci/sfx/old/midiout_alsaraw.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/***************************************************************************
- midiout_alsaraw.c Copyright (C) 2000 Rickard Lind
-
-
- This program may be modified and copied freely according to the terms of
- the GNU general public license (GPL), as long as the above copyright
- notice and the licensing information contained herein are preserved.
-
- Please refer to www.gnu.org for licensing details.
-
- This work is provided AS IS, without warranty of any kind, expressed or
- implied, including but not limited to the warranties of merchantibility,
- noninfringement, and fitness for a specific purpose. The author will not
- be held liable for any damage caused by this work or derivatives of it.
-
- By using this source code, you agree to the licensing terms as stated
- above.
-
-***************************************************************************/
-
-#include "glib.h"
-#include <stdio.h>
-#include <sys/asoundlib.h>
-#include "midiout_alsaraw.h"
-
-static snd_rawmidi_t *handle;
-
-int midiout_alsaraw_open(int card, int device)
-{
- int err;
-
- if ((err = snd_rawmidi_open(&handle, card, device, SND_RAWMIDI_OPEN_OUTPUT)) < 0) {
- fprintf(stderr, "Open failed (%i): /dev/snd/midiC%iD%i\n", err, card, device);
- return -1;
- }
- return 0;
-}
-
-int midiout_alsaraw_close()
-{
- if (snd_rawmidi_close(handle) < 0)
- return -1;
- return 0;
-}
-
-int midiout_alsaraw_write(guint8 *buffer, unsigned int count)
-{
- if (snd_rawmidi_write(handle, buffer, count) != count)
- return -1;
- return 0;
-}
diff --git a/engines/sci/sfx/old/midiout_alsaraw.h b/engines/sci/sfx/old/midiout_alsaraw.h
deleted file mode 100644
index cbf9da44c1..0000000000
--- a/engines/sci/sfx/old/midiout_alsaraw.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/***************************************************************************
- midiout_alsaraw.h Copyright (C) 2000 Rickard Lind
-
-
- This program may be modified and copied freely according to the terms of
- the GNU general public license (GPL), as long as the above copyright
- notice and the licensing information contained herein are preserved.
-
- Please refer to www.gnu.org for licensing details.
-
- This work is provided AS IS, without warranty of any kind, expressed or
- implied, including but not limited to the warranties of merchantibility,
- noninfringement, and fitness for a specific purpose. The author will not
- be held liable for any damage caused by this work or derivatives of it.
-
- By using this source code, you agree to the licensing terms as stated
- above.
-
-***************************************************************************/
-
-#ifndef _MIDIOUT_ALSARAW_H_
-#define _MIDIOUT_ALSARAW_H_
-
-int midiout_alsaraw_open(int card, int device);
-int midiout_alsaraw_close();
-int midiout_alsaraw_write(guint8 *buffer, unsigned int count);
-
-#endif /* _MIDIOUT_ALSARAW_H_ */
diff --git a/engines/sci/sfx/old/midiout_unixraw.c b/engines/sci/sfx/old/midiout_unixraw.c
deleted file mode 100644
index a0dc85955f..0000000000
--- a/engines/sci/sfx/old/midiout_unixraw.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/***************************************************************************
- midiout_unixraw.c Copyright (C) 2000 Rickard Lind
-
-
- This program may be modified and copied freely according to the terms of
- the GNU general public license (GPL), as long as the above copyright
- notice and the licensing information contained herein are preserved.
-
- Please refer to www.gnu.org for licensing details.
-
- This work is provided AS IS, without warranty of any kind, expressed or
- implied, including but not limited to the warranties of merchantibility,
- noninfringement, and fitness for a specific purpose. The author will not
- be held liable for any damage caused by this work or derivatives of it.
-
- By using this source code, you agree to the licensing terms as stated
- above.
-
-***************************************************************************/
-
-#include "glib.h"
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include "midiout_unixraw.h"
-
-static int fd;
-
-int midiout_unixraw_open(char *devicename)
-{
- if (!IS_VALID_FD(fd = open(devicename, O_WRONLY|O_SYNC))) {
- fprintf(stderr, "Open failed (%i): %s\n", fd, devicename);
- return -1;
- }
- return 0;
-}
-
-int midiout_unixraw_close()
-{
- if (close(fd) < 0)
- return -1;
- return 0;
-}
-
-int midiout_unixraw_write(guint8 *buffer, unsigned int count)
-{
- if (write(fd, buffer, count) != count)
- return -1;
- return 0;
-}
diff --git a/engines/sci/sfx/old/midiout_unixraw.h b/engines/sci/sfx/old/midiout_unixraw.h
deleted file mode 100644
index c5980696e9..0000000000
--- a/engines/sci/sfx/old/midiout_unixraw.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/***************************************************************************
- midiout_unixraw.h Copyright (C) 2000 Rickard Lind
-
-
- This program may be modified and copied freely according to the terms of
- the GNU general public license (GPL), as long as the above copyright
- notice and the licensing information contained herein are preserved.
-
- Please refer to www.gnu.org for licensing details.
-
- This work is provided AS IS, without warranty of any kind, expressed or
- implied, including but not limited to the warranties of merchantibility,
- noninfringement, and fitness for a specific purpose. The author will not
- be held liable for any damage caused by this work or derivatives of it.
-
- By using this source code, you agree to the licensing terms as stated
- above.
-
-***************************************************************************/
-
-#ifndef _MIDIOUT_UNIXRAW_H_
-#define _MIDIOUT_UNIXRAW_H_
-
-int midiout_unixraw_open(char *devicename);
-int midiout_unixraw_close();
-int midiout_unixraw_write(guint8 *buffer, unsigned int count);
-
-#endif /* _MIDIOUT_UNIXRAW_H_ */
diff --git a/engines/sci/sfx/softseq/fmopl.c b/engines/sci/sfx/softseq/fmopl.c
deleted file mode 100644
index 6ea777c667..0000000000
--- a/engines/sci/sfx/softseq/fmopl.c
+++ /dev/null
@@ -1,1144 +0,0 @@
-/***************************************************************************
- fmopl.c Copyright (C) 1999-2000 Tatsuyuki Satoh
- 2001-2004 The ScummVM project
- 2002 Solomon Peachy
- 2004 Walter van Niftrik
-
- This program may be modified and copied freely according to the terms of
- the GNU general public license (GPL), as long as the above copyright
- notice and the licensing information contained herein are preserved.
-
- Please refer to www.gnu.org for licensing details.
-
- This work is provided AS IS, without warranty of any kind, expressed or
- implied, including but not limited to the warranties of merchantibility,
- noninfringement, and fitness for a specific purpose. The author will not
- be held liable for any damage caused by this work or derivatives of it.
-
- By using this source code, you agree to the licensing terms as stated
- above.
-
- LGPL licensed version of MAMEs fmopl (V0.37a modified) by
- Tatsuyuki Satoh. Included from LGPL'ed AdPlug.
-
-***************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif /* HAVE_CONFIG_H */
-
-#ifndef INLINE
-# ifdef _MSC_VER
-# define INLINE __inline
-# else
-# define INLINE inline
-# endif
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <math.h>
-
-#include "fmopl.h"
-
-#ifndef PI
-#define PI 3.14159265358979323846
-#endif
-
-/* -------------------- preliminary define section --------------------- */
-/* attack/decay rate time rate */
-#define OPL_ARRATE 141280 /* RATE 4 = 2826.24ms @ 3.6MHz */
-#define OPL_DRRATE 1956000 /* RATE 4 = 39280.64ms @ 3.6MHz */
-
-#define FREQ_BITS 24 /* frequency turn */
-
-/* counter bits = 20 , octerve 7 */
-#define FREQ_RATE (1<<(FREQ_BITS-20))
-#define TL_BITS (FREQ_BITS+2)
-
-/* final output shift , limit minimum and maximum */
-#define OPL_OUTSB (TL_BITS+3-16) /* OPL output final shift 16bit */
-#define OPL_MAXOUT (0x7fff<<OPL_OUTSB)
-#define OPL_MINOUT (-0x8000<<OPL_OUTSB)
-
-/* -------------------- quality selection --------------------- */
-
-/* sinwave entries */
-/* used static memory = SIN_ENT * 4 (byte) */
-#define SIN_ENT 2048
-
-/* output level entries (envelope,sinwave) */
-/* envelope counter lower bits */
-int ENV_BITS;
-/* envelope output entries */
-int EG_ENT;
-
-/* used dynamic memory = EG_ENT*4*4(byte)or EG_ENT*6*4(byte) */
-/* used static memory = EG_ENT*4 (byte) */
-int EG_OFF; /* OFF */
-int EG_DED;
-int EG_DST; /* DECAY START */
-int EG_AED;
-#define EG_AST 0 /* ATTACK START */
-
-#define EG_STEP (96.0/EG_ENT) /* OPL is 0.1875 dB step */
-
-/* LFO table entries */
-#define VIB_ENT 512
-#define VIB_SHIFT (32-9)
-#define AMS_ENT 512
-#define AMS_SHIFT (32-9)
-
-#define VIB_RATE 256
-
-/* -------------------- local defines , macros --------------------- */
-
-/* register number to channel number , slot offset */
-#define SLOT1 0
-#define SLOT2 1
-
-/* envelope phase */
-#define ENV_MOD_RR 0x00
-#define ENV_MOD_DR 0x01
-#define ENV_MOD_AR 0x02
-
-/* -------------------- tables --------------------- */
-static const int slot_array[32]=
-{
- 0, 2, 4, 1, 3, 5,-1,-1,
- 6, 8,10, 7, 9,11,-1,-1,
- 12,14,16,13,15,17,-1,-1,
-#ifdef TWELVE_VOICE
- 18,20,22,19,21,23,-1,-1
-#else
- -1,-1,-1,-1,-1,-1,-1,-1
-#endif
-};
-
-static guint32 KSL_TABLE[8 * 16];
-
-static const double KSL_TABLE_SEED[8 * 16] = {
- /* OCT 0 */
- 0.000, 0.000, 0.000, 0.000,
- 0.000, 0.000, 0.000, 0.000,
- 0.000, 0.000, 0.000, 0.000,
- 0.000, 0.000, 0.000, 0.000,
- /* OCT 1 */
- 0.000, 0.000, 0.000, 0.000,
- 0.000, 0.000, 0.000, 0.000,
- 0.000, 0.750, 1.125, 1.500,
- 1.875, 2.250, 2.625, 3.000,
- /* OCT 2 */
- 0.000, 0.000, 0.000, 0.000,
- 0.000, 1.125, 1.875, 2.625,
- 3.000, 3.750, 4.125, 4.500,
- 4.875, 5.250, 5.625, 6.000,
- /* OCT 3 */
- 0.000, 0.000, 0.000, 1.875,
- 3.000, 4.125, 4.875, 5.625,
- 6.000, 6.750, 7.125, 7.500,
- 7.875, 8.250, 8.625, 9.000,
- /* OCT 4 */
- 0.000, 0.000, 3.000, 4.875,
- 6.000, 7.125, 7.875, 8.625,
- 9.000, 9.750, 10.125, 10.500,
- 10.875, 11.250, 11.625, 12.000,
- /* OCT 5 */
- 0.000, 3.000, 6.000, 7.875,
- 9.000, 10.125, 10.875, 11.625,
- 12.000, 12.750, 13.125, 13.500,
- 13.875, 14.250, 14.625, 15.000,
- /* OCT 6 */
- 0.000, 6.000, 9.000, 10.875,
- 12.000, 13.125, 13.875, 14.625,
- 15.000, 15.750, 16.125, 16.500,
- 16.875, 17.250, 17.625, 18.000,
- /* OCT 7 */
- 0.000, 9.000, 12.000, 13.875,
- 15.000, 16.125, 16.875, 17.625,
- 18.000, 18.750, 19.125, 19.500,
- 19.875, 20.250, 20.625, 21.000
-};
-
-/* sustain lebel table (3db per step) */
-/* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
-
-static int SL_TABLE[16];
-
-static const guint32 SL_TABLE_SEED[16] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 31
-};
-
-#define TL_MAX (EG_ENT * 2) /* limit(tl + ksr + envelope) + sinwave */
-/* TotalLevel : 48 24 12 6 3 1.5 0.75 (dB) */
-/* TL_TABLE[ 0 to TL_MAX ] : plus section */
-/* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */
-static int *TL_TABLE;
-
-/* pointers to TL_TABLE with sinwave output offset */
-static int **SIN_TABLE;
-
-/* LFO table */
-static int *AMS_TABLE;
-static int *VIB_TABLE;
-
-/* envelope output curve table */
-/* attack + decay + OFF */
-//static int ENV_CURVE[2*EG_ENT+1];
-static int ENV_CURVE[2 * 4096 + 1]; // to keep it static ...
-
-/* multiple table */
-#define ML(a) (int)(a * 2)
-static const guint32 MUL_TABLE[16]= {
-/* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */
- ML(0.50), ML(1.00), ML(2.00), ML(3.00), ML(4.00), ML(5.00), ML(6.00), ML(7.00),
- ML(8.00), ML(9.00), ML(10.00), ML(10.00),ML(12.00),ML(12.00),ML(15.00),ML(15.00)
-};
-#undef ML
-
-/* dummy attack / decay rate ( when rate == 0 ) */
-static int RATE_0[16]=
-{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-
-/* -------------------- static state --------------------- */
-
-/* lock level of common table */
-static int num_lock = 0;
-
-/* work table */
-static void *cur_chip = NULL; /* current chip point */
-/* currenct chip state */
-/* static OPLSAMPLE *bufL,*bufR; */
-static OPL_CH *S_CH;
-static OPL_CH *E_CH;
-OPL_SLOT *SLOT7_1, *SLOT7_2, *SLOT8_1, *SLOT8_2;
-
-static int outd[1];
-static int ams;
-static int vib;
-int *ams_table;
-int *vib_table;
-static int amsIncr;
-static int vibIncr;
-static int feedback2; /* connect for SLOT 2 */
-
-/* --------------------- rebuild tables ------------------- */
-
-#define SC_KSL(mydb) ((guint32) (mydb / (EG_STEP / 2)))
-#define SC_SL(db) (int)(db * ((3 / EG_STEP) * (1 << ENV_BITS))) + EG_DST
-
-void OPLBuildTables(int ENV_BITS_PARAM, int EG_ENT_PARAM) {
- int i;
-
- ENV_BITS = ENV_BITS_PARAM;
- EG_ENT = EG_ENT_PARAM;
- EG_OFF = ((2 * EG_ENT)<<ENV_BITS); /* OFF */
- EG_DED = EG_OFF;
- EG_DST = (EG_ENT << ENV_BITS); /* DECAY START */
- EG_AED = EG_DST;
- //EG_STEP = (96.0/EG_ENT);
-
- for (i = 0; i < (int)(sizeof(KSL_TABLE_SEED) / sizeof(double)); i++)
- KSL_TABLE[i] = SC_KSL(KSL_TABLE_SEED[i]);
-
- for (i = 0; i < (int)(sizeof(SL_TABLE_SEED) / sizeof(guint32)); i++)
- SL_TABLE[i] = SC_SL(SL_TABLE_SEED[i]);
-}
-
-#undef SC_KSL
-#undef SC_SL
-
-/* --------------------- subroutines --------------------- */
-
-INLINE int Limit(int val, int max, int min) {
- if ( val > max )
- val = max;
- else if ( val < min )
- val = min;
-
- return val;
-}
-
-/* status set and IRQ handling */
-INLINE void OPL_STATUS_SET(FM_OPL *OPL, int flag) {
- /* set status flag */
- OPL->status |= flag;
- if(!(OPL->status & 0x80)) {
- if(OPL->status & OPL->statusmask) { /* IRQ on */
- OPL->status |= 0x80;
- /* callback user interrupt handler (IRQ is OFF to ON) */
- if(OPL->IRQHandler)
- (OPL->IRQHandler)(OPL->IRQParam,1);
- }
- }
-}
-
-/* status reset and IRQ handling */
-INLINE void OPL_STATUS_RESET(FM_OPL *OPL, int flag) {
- /* reset status flag */
- OPL->status &= ~flag;
- if((OPL->status & 0x80)) {
- if (!(OPL->status & OPL->statusmask)) {
- OPL->status &= 0x7f;
- /* callback user interrupt handler (IRQ is ON to OFF) */
- if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0);
- }
- }
-}
-
-/* IRQ mask set */
-INLINE void OPL_STATUSMASK_SET(FM_OPL *OPL, int flag) {
- OPL->statusmask = flag;
- /* IRQ handling check */
- OPL_STATUS_SET(OPL,0);
- OPL_STATUS_RESET(OPL,0);
-}
-
-/* ----- key on ----- */
-INLINE void OPL_KEYON(OPL_SLOT *SLOT) {
- /* sin wave restart */
- SLOT->Cnt = 0;
- /* set attack */
- SLOT->evm = ENV_MOD_AR;
- SLOT->evs = SLOT->evsa;
- SLOT->evc = EG_AST;
- SLOT->eve = EG_AED;
-}
-/* ----- key off ----- */
-INLINE void OPL_KEYOFF(OPL_SLOT *SLOT) {
- if( SLOT->evm > ENV_MOD_RR) {
- /* set envelope counter from envleope output */
- SLOT->evm = ENV_MOD_RR;
- if( !(SLOT->evc & EG_DST) )
- //SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST;
- SLOT->evc = EG_DST;
- SLOT->eve = EG_DED;
- SLOT->evs = SLOT->evsr;
- }
-}
-
-/* ---------- calcrate Envelope Generator & Phase Generator ---------- */
-/* return : envelope output */
-INLINE guint32 OPL_CALC_SLOT(OPL_SLOT *SLOT) {
- /* calcrate envelope generator */
- if((SLOT->evc += SLOT->evs) >= SLOT->eve) {
- switch( SLOT->evm ){
- case ENV_MOD_AR: /* ATTACK -> DECAY1 */
- /* next DR */
- SLOT->evm = ENV_MOD_DR;
- SLOT->evc = EG_DST;
- SLOT->eve = SLOT->SL;
- SLOT->evs = SLOT->evsd;
- break;
- case ENV_MOD_DR: /* DECAY -> SL or RR */
- SLOT->evc = SLOT->SL;
- SLOT->eve = EG_DED;
- if(SLOT->eg_typ) {
- SLOT->evs = 0;
- } else {
- SLOT->evm = ENV_MOD_RR;
- SLOT->evs = SLOT->evsr;
- }
- break;
- case ENV_MOD_RR: /* RR -> OFF */
- SLOT->evc = EG_OFF;
- SLOT->eve = EG_OFF + 1;
- SLOT->evs = 0;
- break;
- }
- }
- /* calcrate envelope */
- return SLOT->TLL + ENV_CURVE[SLOT->evc>>ENV_BITS] + (SLOT->ams ? ams : 0);
-}
-
-/* set algorythm connection */
-static void set_algorythm(OPL_CH *CH) {
- int *carrier = &outd[0];
- CH->connect1 = CH->CON ? carrier : &feedback2;
- CH->connect2 = carrier;
-}
-
-/* ---------- frequency counter for operater update ---------- */
-INLINE void CALC_FCSLOT(OPL_CH *CH, OPL_SLOT *SLOT) {
- int ksr;
-
- /* frequency step counter */
- SLOT->Incr = CH->fc * SLOT->mul;
- ksr = CH->kcode >> SLOT->KSR;
-
- if( SLOT->ksr != ksr )
- {
- SLOT->ksr = ksr;
- /* attack , decay rate recalcration */
- SLOT->evsa = SLOT->AR[ksr];
- SLOT->evsd = SLOT->DR[ksr];
- SLOT->evsr = SLOT->RR[ksr];
- }
- SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
-}
-
-/* set multi,am,vib,EG-TYP,KSR,mul */
-INLINE void set_mul(FM_OPL *OPL, int slot, int v) {
- OPL_CH *CH = &OPL->P_CH[slot / 2];
- OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
-
- SLOT->mul = MUL_TABLE[v & 0x0f];
- SLOT->KSR = (v & 0x10) ? 0 : 2;
- SLOT->eg_typ = (v & 0x20) >> 5;
- SLOT->vib = (v & 0x40);
- SLOT->ams = (v & 0x80);
- CALC_FCSLOT(CH, SLOT);
-}
-
-/* set ksl & tl */
-INLINE void set_ksl_tl(FM_OPL *OPL, int slot, int v) {
- OPL_CH *CH = &OPL->P_CH[slot / 2];
- OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
- int ksl = v >> 6; /* 0 / 1.5 / 3 / 6 db/OCT */
-
- SLOT->ksl = ksl ? 3-ksl : 31;
- SLOT->TL = (int)((v & 0x3f) * (0.75 / EG_STEP)); /* 0.75db step */
-
- if(!(OPL->mode & 0x80)) { /* not CSM latch total level */
- SLOT->TLL = SLOT->TL + (CH->ksl_base >> SLOT->ksl);
- }
-}
-
-/* set attack rate & decay rate */
-INLINE void set_ar_dr(FM_OPL *OPL, int slot, int v) {
- OPL_CH *CH = &OPL->P_CH[slot / 2];
- OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
- int ar = v >> 4;
- int dr = v & 0x0f;
-
- SLOT->AR = ar ? &OPL->AR_TABLE[ar << 2] : RATE_0;
- SLOT->evsa = SLOT->AR[SLOT->ksr];
- if(SLOT->evm == ENV_MOD_AR)
- SLOT->evs = SLOT->evsa;
-
- SLOT->DR = dr ? &OPL->DR_TABLE[dr<<2] : RATE_0;
- SLOT->evsd = SLOT->DR[SLOT->ksr];
- if(SLOT->evm == ENV_MOD_DR)
- SLOT->evs = SLOT->evsd;
-}
-
-/* set sustain level & release rate */
-INLINE void set_sl_rr(FM_OPL *OPL, int slot, int v) {
- OPL_CH *CH = &OPL->P_CH[slot / 2];
- OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
- int sl = v >> 4;
- int rr = v & 0x0f;
-
- SLOT->SL = SL_TABLE[sl];
- if(SLOT->evm == ENV_MOD_DR)
- SLOT->eve = SLOT->SL;
- SLOT->RR = &OPL->DR_TABLE[rr<<2];
- SLOT->evsr = SLOT->RR[SLOT->ksr];
- if(SLOT->evm == ENV_MOD_RR)
- SLOT->evs = SLOT->evsr;
-}
-
-/* operator output calcrator */
-#define OP_OUT(slot,env,con) slot->wavetable[((slot->Cnt + con) / (0x1000000 / SIN_ENT)) & (SIN_ENT-1)][env]
-/* ---------- calcrate one of channel ---------- */
-INLINE void OPL_CALC_CH(OPL_CH *CH) {
- guint32 env_out;
- OPL_SLOT *SLOT;
-
- feedback2 = 0;
- /* SLOT 1 */
- SLOT = &CH->SLOT[SLOT1];
- env_out=OPL_CALC_SLOT(SLOT);
- if(env_out < (guint32)(EG_ENT - 1)) {
- /* PG */
- if(SLOT->vib)
- SLOT->Cnt += (SLOT->Incr * vib / VIB_RATE);
- else
- SLOT->Cnt += SLOT->Incr;
- /* connectoion */
- if(CH->FB) {
- int feedback1 = (CH->op1_out[0] + CH->op1_out[1]) >> CH->FB;
- CH->op1_out[1] = CH->op1_out[0];
- *CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT, env_out, feedback1);
- }
- else {
- *CH->connect1 += OP_OUT(SLOT, env_out, 0);
- }
- }else {
- CH->op1_out[1] = CH->op1_out[0];
- CH->op1_out[0] = 0;
- }
- /* SLOT 2 */
- SLOT = &CH->SLOT[SLOT2];
- env_out=OPL_CALC_SLOT(SLOT);
- if(env_out < (guint32)(EG_ENT - 1)) {
- /* PG */
- if(SLOT->vib)
- SLOT->Cnt += (SLOT->Incr * vib / VIB_RATE);
- else
- SLOT->Cnt += SLOT->Incr;
- /* connectoion */
- outd[0] += OP_OUT(SLOT, env_out, feedback2);
- }
-}
-
-/* ---------- calcrate rythm block ---------- */
-#define WHITE_NOISE_db 6.0
-INLINE void OPL_CALC_RH(OPL_CH *CH) {
- guint32 env_tam, env_sd, env_top, env_hh;
- int whitenoise = (int)((rand()&1) * (WHITE_NOISE_db / EG_STEP));
- int tone8;
-
- OPL_SLOT *SLOT;
- int env_out;
-
- /* BD : same as FM serial mode and output level is large */
- feedback2 = 0;
- /* SLOT 1 */
- SLOT = &CH[6].SLOT[SLOT1];
- env_out = OPL_CALC_SLOT(SLOT);
- if(env_out < EG_ENT-1) {
- /* PG */
- if(SLOT->vib)
- SLOT->Cnt += (SLOT->Incr * vib / VIB_RATE);
- else
- SLOT->Cnt += SLOT->Incr;
- /* connectoion */
- if(CH[6].FB) {
- int feedback1 = (CH[6].op1_out[0] + CH[6].op1_out[1]) >> CH[6].FB;
- CH[6].op1_out[1] = CH[6].op1_out[0];
- feedback2 = CH[6].op1_out[0] = OP_OUT(SLOT, env_out, feedback1);
- }
- else {
- feedback2 = OP_OUT(SLOT, env_out, 0);
- }
- }else {
- feedback2 = 0;
- CH[6].op1_out[1] = CH[6].op1_out[0];
- CH[6].op1_out[0] = 0;
- }
- /* SLOT 2 */
- SLOT = &CH[6].SLOT[SLOT2];
- env_out = OPL_CALC_SLOT(SLOT);
- if(env_out < EG_ENT-1) {
- /* PG */
- if(SLOT->vib)
- SLOT->Cnt += (SLOT->Incr * vib / VIB_RATE);
- else
- SLOT->Cnt += SLOT->Incr;
- /* connectoion */
- outd[0] += OP_OUT(SLOT, env_out, feedback2) * 2;
- }
-
- // SD (17) = mul14[fnum7] + white noise
- // TAM (15) = mul15[fnum8]
- // TOP (18) = fnum6(mul18[fnum8]+whitenoise)
- // HH (14) = fnum7(mul18[fnum8]+whitenoise) + white noise
- env_sd = OPL_CALC_SLOT(SLOT7_2) + whitenoise;
- env_tam =OPL_CALC_SLOT(SLOT8_1);
- env_top = OPL_CALC_SLOT(SLOT8_2);
- env_hh = OPL_CALC_SLOT(SLOT7_1) + whitenoise;
-
- /* PG */
- if(SLOT7_1->vib)
- SLOT7_1->Cnt += (2 * SLOT7_1->Incr * vib / VIB_RATE);
- else
- SLOT7_1->Cnt += 2 * SLOT7_1->Incr;
- if(SLOT7_2->vib)
- SLOT7_2->Cnt += ((CH[7].fc * 8) * vib / VIB_RATE);
- else
- SLOT7_2->Cnt += (CH[7].fc * 8);
- if(SLOT8_1->vib)
- SLOT8_1->Cnt += (SLOT8_1->Incr * vib / VIB_RATE);
- else
- SLOT8_1->Cnt += SLOT8_1->Incr;
- if(SLOT8_2->vib)
- SLOT8_2->Cnt += ((CH[8].fc * 48) * vib / VIB_RATE);
- else
- SLOT8_2->Cnt += (CH[8].fc * 48);
-
- tone8 = OP_OUT(SLOT8_2,whitenoise,0 );
-
- /* SD */
- if(env_sd < (guint32)(EG_ENT - 1))
- outd[0] += OP_OUT(SLOT7_1, env_sd, 0) * 8;
- /* TAM */
- if(env_tam < (guint32)(EG_ENT - 1))
- outd[0] += OP_OUT(SLOT8_1, env_tam, 0) * 2;
- /* TOP-CY */
- if(env_top < (guint32)(EG_ENT - 1))
- outd[0] += OP_OUT(SLOT7_2, env_top, tone8) * 2;
- /* HH */
- if(env_hh < (guint32)(EG_ENT-1))
- outd[0] += OP_OUT(SLOT7_2, env_hh, tone8) * 2;
-}
-
-/* ----------- initialize time tabls ----------- */
-static void init_timetables(FM_OPL *OPL, int ARRATE, int DRRATE) {
- int i;
- double rate;
-
- /* make attack rate & decay rate tables */
- for (i = 0; i < 4; i++)
- OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0;
- for (i = 4; i <= 60; i++){
- rate = OPL->freqbase; /* frequency rate */
- if(i < 60)
- rate *= 1.0 + (i & 3) * 0.25; /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
- rate *= 1 << ((i >> 2) - 1); /* b2-5 : shift bit */
- rate *= (double)(EG_ENT << ENV_BITS);
- OPL->AR_TABLE[i] = (int)(rate / ARRATE);
- OPL->DR_TABLE[i] = (int)(rate / DRRATE);
- }
- for (i = 60; i < 75; i++) {
- OPL->AR_TABLE[i] = EG_AED-1;
- OPL->DR_TABLE[i] = OPL->DR_TABLE[60];
- }
-}
-
-/* ---------- generic table initialize ---------- */
-static int OPLOpenTable(void) {
- int s,t;
- double rate;
- int i,j;
- double pom;
-
- /* allocate dynamic tables */
- if((TL_TABLE = (int *)malloc(TL_MAX * 2 * sizeof(int))) == NULL)
- return 0;
- if((SIN_TABLE = (int **)malloc(SIN_ENT * 4 * sizeof(int *))) == NULL) {
- free(TL_TABLE);
- return 0;
- }
- if((AMS_TABLE = (int *)malloc(AMS_ENT * 2 * sizeof(int))) == NULL) {
- free(TL_TABLE);
- free(SIN_TABLE);
- return 0;
- }
- if((VIB_TABLE = (int *)malloc(VIB_ENT * 2 * sizeof(int))) == NULL) {
- free(TL_TABLE);
- free(SIN_TABLE);
- free(AMS_TABLE);
- return 0;
- }
- /* make total level table */
- for (t = 0; t < EG_ENT - 1 ; t++){
- rate = ((1 << TL_BITS) - 1) / pow(10.0, EG_STEP * t / 20); /* dB -> voltage */
- TL_TABLE[ t] = (int)rate;
- TL_TABLE[TL_MAX + t] = -TL_TABLE[t];
- }
- /* fill volume off area */
- for (t = EG_ENT - 1; t < TL_MAX; t++){
- TL_TABLE[t] = TL_TABLE[TL_MAX + t] = 0;
- }
-
- /* make sinwave table (total level offet) */
- /* degree 0 = degree 180 = off */
- SIN_TABLE[0] = SIN_TABLE[SIN_ENT /2 ] = &TL_TABLE[EG_ENT - 1];
- for (s = 1;s <= SIN_ENT / 4; s++){
- pom = sin(2 * PI * s / SIN_ENT); /* sin */
- pom = 20 * log10(1 / pom); /* decibel */
- j = (int)(pom / EG_STEP); /* TL_TABLE steps */
-
- /* degree 0 - 90 , degree 180 - 90 : plus section */
- SIN_TABLE[ s] = SIN_TABLE[SIN_ENT / 2 - s] = &TL_TABLE[j];
- /* degree 180 - 270 , degree 360 - 270 : minus section */
- SIN_TABLE[SIN_ENT / 2 + s] = SIN_TABLE[SIN_ENT - s] = &TL_TABLE[TL_MAX + j];
- }
- for (s = 0;s < SIN_ENT; s++) {
- SIN_TABLE[SIN_ENT * 1 + s] = s < (SIN_ENT / 2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT];
- SIN_TABLE[SIN_ENT * 2 + s] = SIN_TABLE[s % (SIN_ENT / 2)];
- SIN_TABLE[SIN_ENT * 3 + s] = (s / (SIN_ENT / 4)) & 1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT * 2 + s];
- }
-
- /* envelope counter -> envelope output table */
- for (i=0; i < EG_ENT; i++) {
- /* ATTACK curve */
- pom = pow(((double)(EG_ENT - 1 - i) / EG_ENT), 8) * EG_ENT;
- /* if( pom >= EG_ENT ) pom = EG_ENT-1; */
- ENV_CURVE[i] = (int)pom;
- /* DECAY ,RELEASE curve */
- ENV_CURVE[(EG_DST >> ENV_BITS) + i]= i;
- }
- /* off */
- ENV_CURVE[EG_OFF >> ENV_BITS]= EG_ENT - 1;
- /* make LFO ams table */
- for (i=0; i < AMS_ENT; i++) {
- pom = (1.0 + sin(2 * PI * i / AMS_ENT)) / 2; /* sin */
- AMS_TABLE[i] = (int)((1.0 / EG_STEP) * pom); /* 1dB */
- AMS_TABLE[AMS_ENT + i] = (int)((4.8 / EG_STEP) * pom); /* 4.8dB */
- }
- /* make LFO vibrate table */
- for (i=0; i < VIB_ENT; i++) {
- /* 100cent = 1seminote = 6% ?? */
- pom = (double)VIB_RATE * 0.06 * sin(2 * PI * i / VIB_ENT); /* +-100sect step */
- VIB_TABLE[i] = (int)(VIB_RATE + (pom * 0.07)); /* +- 7cent */
- VIB_TABLE[VIB_ENT + i] = (int)(VIB_RATE + (pom * 0.14)); /* +-14cent */
- }
- return 1;
-}
-
-static void OPLCloseTable(void) {
- free(TL_TABLE);
- free(SIN_TABLE);
- free(AMS_TABLE);
- free(VIB_TABLE);
-}
-
-/* CSM Key Controll */
-INLINE void CSMKeyControll(OPL_CH *CH) {
- OPL_SLOT *slot1 = &CH->SLOT[SLOT1];
- OPL_SLOT *slot2 = &CH->SLOT[SLOT2];
- /* all key off */
- OPL_KEYOFF(slot1);
- OPL_KEYOFF(slot2);
- /* total level latch */
- slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
- slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
- /* key on */
- CH->op1_out[0] = CH->op1_out[1] = 0;
- OPL_KEYON(slot1);
- OPL_KEYON(slot2);
-}
-
-/* ---------- opl initialize ---------- */
-static void OPL_initalize(FM_OPL *OPL) {
- int fn;
-
- /* frequency base */
- OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / OPL->rate) / 72 : 0;
- /* Timer base time */
- OPL->TimerBase = 1.0/((double)OPL->clock / 72.0 );
- /* make time tables */
- init_timetables(OPL, OPL_ARRATE, OPL_DRRATE);
- /* make fnumber -> increment counter table */
- for( fn=0; fn < 1024; fn++) {
- OPL->FN_TABLE[fn] = (guint32)(OPL->freqbase * fn * FREQ_RATE * (1<<7) / 2);
- }
- /* LFO freq.table */
- OPL->amsIncr = (int)(OPL->rate ? (double)AMS_ENT * (1 << AMS_SHIFT) / OPL->rate * 3.7 * ((double)OPL->clock/3600000) : 0);
- OPL->vibIncr = (int)(OPL->rate ? (double)VIB_ENT * (1 << VIB_SHIFT) / OPL->rate * 6.4 * ((double)OPL->clock/3600000) : 0);
-}
-
-/* ---------- write a OPL registers ---------- */
-void OPLWriteReg(FM_OPL *OPL, int r, int v) {
- OPL_CH *CH;
- int slot;
- guint32 block_fnum;
-
- switch(r & 0xe0) {
- case 0x00: /* 00-1f:controll */
- switch(r & 0x1f) {
- case 0x01:
- /* wave selector enable */
- if(OPL->type&OPL_TYPE_WAVESEL) {
- OPL->wavesel = v & 0x20;
- if(!OPL->wavesel) {
- /* preset compatible mode */
- int c;
- for(c=0; c<OPL->max_ch; c++) {
- OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0];
- OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0];
- }
- }
- }
- return;
- case 0x02: /* Timer 1 */
- OPL->T[0] = (256-v) * 4;
- break;
- case 0x03: /* Timer 2 */
- OPL->T[1] = (256-v) * 16;
- return;
- case 0x04: /* IRQ clear / mask and Timer enable */
- if(v & 0x80) { /* IRQ flag clear */
- OPL_STATUS_RESET(OPL, 0x7f);
- }
- else { /* set IRQ mask ,timer enable*/
- guint8 st1 = v & 1;
- guint8 st2 = (v >> 1) & 1;
- /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */
- OPL_STATUS_RESET(OPL, v & 0x78);
- OPL_STATUSMASK_SET(OPL,((~v) & 0x78) | 0x01);
- /* timer 2 */
- if(OPL->st[1] != st2) {
- double interval = st2 ? (double)OPL->T[1] * OPL->TimerBase : 0.0;
- OPL->st[1] = st2;
- if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam + 1, interval);
- }
- /* timer 1 */
- if(OPL->st[0] != st1) {
- double interval = st1 ? (double)OPL->T[0] * OPL->TimerBase : 0.0;
- OPL->st[0] = st1;
- if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam + 0, interval);
- }
- }
- return;
- }
- break;
- case 0x20: /* am,vib,ksr,eg type,mul */
- slot = slot_array[r&0x1f];
- if(slot == -1)
- return;
- set_mul(OPL,slot,v);
- return;
- case 0x40:
- slot = slot_array[r&0x1f];
- if(slot == -1)
- return;
- set_ksl_tl(OPL,slot,v);
- return;
- case 0x60:
- slot = slot_array[r&0x1f];
- if(slot == -1)
- return;
- set_ar_dr(OPL,slot,v);
- return;
- case 0x80:
- slot = slot_array[r&0x1f];
- if(slot == -1)
- return;
- set_sl_rr(OPL,slot,v);
- return;
- case 0xa0:
- switch(r) {
- case 0xbd:
- /* amsep,vibdep,r,bd,sd,tom,tc,hh */
- {
- guint8 rkey = OPL->rythm ^ v;
- OPL->ams_table = &AMS_TABLE[v & 0x80 ? AMS_ENT : 0];
- OPL->vib_table = &VIB_TABLE[v & 0x40 ? VIB_ENT : 0];
- OPL->rythm = v & 0x3f;
- if(OPL->rythm & 0x20) {
- /* BD key on/off */
- if(rkey & 0x10) {
- if(v & 0x10) {
- OPL->P_CH[6].op1_out[0] = OPL->P_CH[6].op1_out[1] = 0;
- OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT1]);
- OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT2]);
- }
- else {
- OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1]);
- OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2]);
- }
- }
- /* SD key on/off */
- if(rkey & 0x08) {
- if(v & 0x08)
- OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT2]);
- else
- OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2]);
- }/* TAM key on/off */
- if(rkey & 0x04) {
- if(v & 0x04)
- OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT1]);
- else
- OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1]);
- }
- /* TOP-CY key on/off */
- if(rkey & 0x02) {
- if(v & 0x02)
- OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT2]);
- else
- OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2]);
- }
- /* HH key on/off */
- if(rkey & 0x01) {
- if(v & 0x01)
- OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT1]);
- else
- OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1]);
- }
- }
- }
- return;
- }
- /* keyon,block,fnum */
- if((r & 0x0f) >= ADLIB_VOICES)
- return;
- CH = &OPL->P_CH[r & 0x0f];
- if(!(r&0x10)) { /* a0-a8 */
- block_fnum = (CH->block_fnum & 0x1f00) | v;
- }
- else { /* b0-b8 */
- int keyon = (v >> 5) & 1;
- block_fnum = ((v & 0x1f) << 8) | (CH->block_fnum & 0xff);
- if(CH->keyon != keyon) {
- if((CH->keyon=keyon)) {
- CH->op1_out[0] = CH->op1_out[1] = 0;
- OPL_KEYON(&CH->SLOT[SLOT1]);
- OPL_KEYON(&CH->SLOT[SLOT2]);
- }
- else {
- OPL_KEYOFF(&CH->SLOT[SLOT1]);
- OPL_KEYOFF(&CH->SLOT[SLOT2]);
- }
- }
- }
- /* update */
- if(CH->block_fnum != block_fnum) {
- int blockRv = 7 - (block_fnum >> 10);
- int fnum = block_fnum & 0x3ff;
- CH->block_fnum = block_fnum;
- CH->ksl_base = KSL_TABLE[block_fnum >> 6];
- CH->fc = OPL->FN_TABLE[fnum] >> blockRv;
- CH->kcode = CH->block_fnum >> 9;
- if((OPL->mode & 0x40) && CH->block_fnum & 0x100)
- CH->kcode |=1;
- CALC_FCSLOT(CH,&CH->SLOT[SLOT1]);
- CALC_FCSLOT(CH,&CH->SLOT[SLOT2]);
- }
- return;
- case 0xc0:
- /* FB,C */
- if((r & 0x0f) >= ADLIB_VOICES)
- return;
- CH = &OPL->P_CH[r&0x0f];
- {
- int feedback = (v >> 1) & 7;
- CH->FB = feedback ? (8 + 1) - feedback : 0;
- CH->CON = v & 1;
- set_algorythm(CH);
- }
- return;
- case 0xe0: /* wave type */
- slot = slot_array[r & 0x1f];
- if(slot == -1)
- return;
- CH = &OPL->P_CH[slot / 2];
- if(OPL->wavesel) {
- CH->SLOT[slot&1].wavetable = &SIN_TABLE[(v & 0x03) * SIN_ENT];
- }
- return;
- }
-}
-
-/* lock/unlock for common table */
-static int OPL_LockTable(void)
-{
- num_lock++;
- if(num_lock>1)
- return 0;
- /* first time */
- cur_chip = NULL;
- /* allocate total level table (128kb space) */
- if(!OPLOpenTable()) {
- num_lock--;
- return -1;
- }
- return 0;
-}
-
-static void OPL_UnLockTable(void) {
- if(num_lock)
- num_lock--;
- if(num_lock)
- return;
- /* last time */
- cur_chip = NULL;
- OPLCloseTable();
-}
-
-/*******************************************************************************/
-/* YM3812 local section */
-/*******************************************************************************/
-
-/* ---------- update one of chip ----------- */
-void YM3812UpdateOne(FM_OPL *OPL, gint16 *buffer, int length, int interleave) {
- int i;
- int data;
- gint16 *buf = buffer;
- guint32 amsCnt = OPL->amsCnt;
- guint32 vibCnt = OPL->vibCnt;
- guint8 rythm = OPL->rythm & 0x20;
- OPL_CH *CH, *R_CH;
-
- if((void *)OPL != cur_chip){
- cur_chip = (void *)OPL;
- /* channel pointers */
- S_CH = OPL->P_CH;
- E_CH = &S_CH[9];
- /* rythm slot */
- SLOT7_1 = &S_CH[7].SLOT[SLOT1];
- SLOT7_2 = &S_CH[7].SLOT[SLOT2];
- SLOT8_1 = &S_CH[8].SLOT[SLOT1];
- SLOT8_2 = &S_CH[8].SLOT[SLOT2];
- /* LFO state */
- amsIncr = OPL->amsIncr;
- vibIncr = OPL->vibIncr;
- ams_table = OPL->ams_table;
- vib_table = OPL->vib_table;
- }
- R_CH = rythm ? &S_CH[6] : E_CH;
- for(i = 0; i < length; i++) {
- /* channel A channel B channel C */
- /* LFO */
- ams = ams_table[(amsCnt += amsIncr) >> AMS_SHIFT];
- vib = vib_table[(vibCnt += vibIncr) >> VIB_SHIFT];
- outd[0] = 0;
- /* FM part */
- for(CH=S_CH; CH < R_CH; CH++)
- OPL_CALC_CH(CH);
- /* Rythn part */
- if(rythm)
- OPL_CALC_RH(S_CH);
-#ifdef TWELVE_VOICE
- for(CH=&S_CH[9]; CH < &S_CH[ADLIB_VOICES]; CH++)
- OPL_CALC_CH(CH);
-#endif
- /* limit check */
- data = Limit(outd[0], OPL_MAXOUT, OPL_MINOUT);
- /* store to sound buffer */
- buf[i << interleave] = data >> OPL_OUTSB;
- }
-
- OPL->amsCnt = amsCnt;
- OPL->vibCnt = vibCnt;
-}
-
-/* ---------- reset a chip ---------- */
-void OPLResetChip(FM_OPL *OPL) {
- int c,s;
- int i;
-
- /* reset chip */
- OPL->mode = 0; /* normal mode */
- OPL_STATUS_RESET(OPL, 0x7f);
- /* reset with register write */
- OPLWriteReg(OPL, 0x01,0); /* wabesel disable */
- OPLWriteReg(OPL, 0x02,0); /* Timer1 */
- OPLWriteReg(OPL, 0x03,0); /* Timer2 */
- OPLWriteReg(OPL, 0x04,0); /* IRQ mask clear */
- for(i = 0xff; i >= 0x20; i--)
- OPLWriteReg(OPL,i,0);
- /* reset OPerator parameter */
- for(c = 0; c < OPL->max_ch ;c++ ) {
- OPL_CH *CH = &OPL->P_CH[c];
- /* OPL->P_CH[c].PAN = OPN_CENTER; */
- for(s = 0; s < 2; s++ ) {
- /* wave table */
- CH->SLOT[s].wavetable = &SIN_TABLE[0];
- /* CH->SLOT[s].evm = ENV_MOD_RR; */
- CH->SLOT[s].evc = EG_OFF;
- CH->SLOT[s].eve = EG_OFF + 1;
- CH->SLOT[s].evs = 0;
- }
- }
-}
-
-/* ---------- Create a virtual YM3812 ---------- */
-/* 'rate' is sampling rate and 'bufsiz' is the size of the */
-FM_OPL *OPLCreate(int type, int clock, int rate) {
- char *ptr;
- FM_OPL *OPL;
- int state_size;
-#ifdef TWELVE_VOICE
- int max_ch = 12;
-#else
- int max_ch = 9; /* normaly 9 channels */
-#endif
-
- if( OPL_LockTable() == -1)
- return NULL;
- /* allocate OPL state space */
- state_size = sizeof(FM_OPL);
- state_size += sizeof(OPL_CH) * max_ch;
-
- /* allocate memory block */
- ptr = (char *)calloc(state_size, 1);
- if(ptr == NULL)
- return NULL;
-
- /* clear */
- memset(ptr, 0, state_size);
- OPL = (FM_OPL *)ptr; ptr += sizeof(FM_OPL);
- OPL->P_CH = (OPL_CH *)ptr; ptr += sizeof(OPL_CH) * max_ch;
-
- /* set channel state pointer */
- OPL->type = type;
- OPL->clock = clock;
- OPL->rate = rate;
- OPL->max_ch = max_ch;
-
- /* init grobal tables */
- OPL_initalize(OPL);
-
- /* reset chip */
- OPLResetChip(OPL);
- return OPL;
-}
-
-/* ---------- Destroy one of vietual YM3812 ---------- */
-void OPLDestroy(FM_OPL *OPL) {
- OPL_UnLockTable();
- free(OPL);
-}
-
-/* ---------- Option handlers ---------- */
-
-void OPLSetTimerHandler(FM_OPL *OPL, OPL_TIMERHANDLER TimerHandler,int channelOffset) {
- OPL->TimerHandler = TimerHandler;
- OPL->TimerParam = channelOffset;
-}
-
-void OPLSetIRQHandler(FM_OPL *OPL, OPL_IRQHANDLER IRQHandler, int param) {
- OPL->IRQHandler = IRQHandler;
- OPL->IRQParam = param;
-}
-void OPLSetUpdateHandler(FM_OPL *OPL, OPL_UPDATEHANDLER UpdateHandler,int param) {
- OPL->UpdateHandler = UpdateHandler;
- OPL->UpdateParam = param;
-}
-
-/* ---------- YM3812 I/O interface ---------- */
-int OPLWrite(FM_OPL *OPL,int a,int v) {
- if(!(a & 1)) { /* address port */
- OPL->address = v & 0xff;
- }
- else { /* data port */
- if(OPL->UpdateHandler)
- OPL->UpdateHandler(OPL->UpdateParam,0);
- OPLWriteReg(OPL, OPL->address,v);
- }
- return OPL->status >> 7;
-}
-
-unsigned char OPLRead(FM_OPL *OPL,int a) {
- if(!(a & 1)) { /* status port */
- return OPL->status & (OPL->statusmask | 0x80);
- }
- /* data port */
- switch(OPL->address) {
- case 0x05: /* KeyBoard IN */
- fprintf(stderr, "OPL:read unmapped KEYBOARD port\n");
- return 0;
- case 0x19: /* I/O DATA */
- fprintf(stderr, "OPL:read unmapped I/O port\n");
- return 0;
- case 0x1a: /* PCM-DATA */
- return 0;
- }
- return 0;
-}
-
-int OPLTimerOver(FM_OPL *OPL, int c) {
- if(c) { /* Timer B */
- OPL_STATUS_SET(OPL, 0x20);
- }
- else { /* Timer A */
- OPL_STATUS_SET(OPL, 0x40);
- /* CSM mode key,TL controll */
- if(OPL->mode & 0x80) { /* CSM mode total level latch and auto key on */
- int ch;
- if(OPL->UpdateHandler)
- OPL->UpdateHandler(OPL->UpdateParam,0);
- for(ch = 0; ch < 9; ch++)
- CSMKeyControll(&OPL->P_CH[ch]);
- }
- }
- /* reload timer */
- if (OPL->TimerHandler)
- (OPL->TimerHandler)(OPL->TimerParam + c, (double)OPL->T[c] * OPL->TimerBase);
- return OPL->status >> 7;
-}
diff --git a/engines/sci/sfx/softseq/mt32/freeverb.cpp b/engines/sci/sfx/softseq/mt32/freeverb.cpp
deleted file mode 100644
index 1c3aab0494..0000000000
--- a/engines/sci/sfx/softseq/mt32/freeverb.cpp
+++ /dev/null
@@ -1,310 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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.
- *
- * $URL$
- * $Id$
- *
- */
-
-// Comb filter implementation
-//
-// Written by
-// http://www.dreampoint.co.uk
-// This code is public domain
-
-#include "freeverb.h"
-
-comb::comb() {
- filterstore = 0;
- bufidx = 0;
-}
-
-void comb::setbuffer(float *buf, int size) {
- buffer = buf;
- bufsize = size;
-}
-
-void comb::mute() {
- for (int i = 0; i < bufsize; i++)
- buffer[i] = 0;
-}
-
-void comb::setdamp(float val) {
- damp1 = val;
- damp2 = 1 - val;
-}
-
-float comb::getdamp() {
- return damp1;
-}
-
-void comb::setfeedback(float val) {
- feedback = val;
-}
-
-float comb::getfeedback() {
- return feedback;
-}
-
-// Allpass filter implementation
-
-allpass::allpass() {
- bufidx = 0;
-}
-
-void allpass::setbuffer(float *buf, int size) {
- buffer = buf;
- bufsize = size;
-}
-
-void allpass::mute() {
- for (int i = 0; i < bufsize; i++)
- buffer[i] = 0;
-}
-
-void allpass::setfeedback(float val) {
- feedback = val;
-}
-
-float allpass::getfeedback() {
- return feedback;
-}
-
-// Reverb model implementation
-
-revmodel::revmodel() {
- // Tie the components to their buffers
- combL[0].setbuffer(bufcombL1,combtuningL1);
- combR[0].setbuffer(bufcombR1,combtuningR1);
- combL[1].setbuffer(bufcombL2,combtuningL2);
- combR[1].setbuffer(bufcombR2,combtuningR2);
- combL[2].setbuffer(bufcombL3,combtuningL3);
- combR[2].setbuffer(bufcombR3,combtuningR3);
- combL[3].setbuffer(bufcombL4,combtuningL4);
- combR[3].setbuffer(bufcombR4,combtuningR4);
- combL[4].setbuffer(bufcombL5,combtuningL5);
- combR[4].setbuffer(bufcombR5,combtuningR5);
- combL[5].setbuffer(bufcombL6,combtuningL6);
- combR[5].setbuffer(bufcombR6,combtuningR6);
- combL[6].setbuffer(bufcombL7,combtuningL7);
- combR[6].setbuffer(bufcombR7,combtuningR7);
- combL[7].setbuffer(bufcombL8,combtuningL8);
- combR[7].setbuffer(bufcombR8,combtuningR8);
- allpassL[0].setbuffer(bufallpassL1,allpasstuningL1);
- allpassR[0].setbuffer(bufallpassR1,allpasstuningR1);
- allpassL[1].setbuffer(bufallpassL2,allpasstuningL2);
- allpassR[1].setbuffer(bufallpassR2,allpasstuningR2);
- allpassL[2].setbuffer(bufallpassL3,allpasstuningL3);
- allpassR[2].setbuffer(bufallpassR3,allpasstuningR3);
- allpassL[3].setbuffer(bufallpassL4,allpasstuningL4);
- allpassR[3].setbuffer(bufallpassR4,allpasstuningR4);
-
- // Set default values
- allpassL[0].setfeedback(0.5f);
- allpassR[0].setfeedback(0.5f);
- allpassL[1].setfeedback(0.5f);
- allpassR[1].setfeedback(0.5f);
- allpassL[2].setfeedback(0.5f);
- allpassR[2].setfeedback(0.5f);
- allpassL[3].setfeedback(0.5f);
- allpassR[3].setfeedback(0.5f);
- setwet(initialwet);
- setroomsize(initialroom);
- setdry(initialdry);
- setdamp(initialdamp);
- setwidth(initialwidth);
- setmode(initialmode);
-
- // Buffer will be full of rubbish - so we MUST mute them
- mute();
-}
-
-void revmodel::mute() {
- int i;
-
- if (getmode() >= freezemode)
- return;
-
- for (i = 0; i < numcombs; i++) {
- combL[i].mute();
- combR[i].mute();
- }
-
- for (i = 0; i < numallpasses; i++) {
- allpassL[i].mute();
- allpassR[i].mute();
- }
-}
-
-void revmodel::processreplace(float *inputL, float *inputR, float *outputL, float *outputR, long numsamples, int skip) {
- float outL, outR, input;
-
- while (numsamples-- > 0) {
- int i;
-
- outL = outR = 0;
- input = (*inputL + *inputR) * gain;
-
- // Accumulate comb filters in parallel
- for (i = 0; i < numcombs; i++) {
- outL += combL[i].process(input);
- outR += combR[i].process(input);
- }
-
- // Feed through allpasses in series
- for (i = 0; i < numallpasses; i++) {
- outL = allpassL[i].process(outL);
- outR = allpassR[i].process(outR);
- }
-
- // Calculate output REPLACING anything already there
- *outputL = outL * wet1 + outR * wet2 + *inputL * dry;
- *outputR = outR * wet1 + outL * wet2 + *inputR * dry;
-
- // Increment sample pointers, allowing for interleave (if any)
- inputL += skip;
- inputR += skip;
- outputL += skip;
- outputR += skip;
- }
-}
-
-void revmodel::processmix(float *inputL, float *inputR, float *outputL, float *outputR, long numsamples, int skip) {
- float outL, outR, input;
-
- while (numsamples-- > 0) {
- int i;
-
- outL = outR = 0;
- input = (*inputL + *inputR) * gain;
-
- // Accumulate comb filters in parallel
- for (i = 0; i < numcombs; i++) {
- outL += combL[i].process(input);
- outR += combR[i].process(input);
- }
-
- // Feed through allpasses in series
- for (i = 0; i < numallpasses; i++) {
- outL = allpassL[i].process(outL);
- outR = allpassR[i].process(outR);
- }
-
- // Calculate output MIXING with anything already there
- *outputL += outL * wet1 + outR * wet2 + *inputL * dry;
- *outputR += outR * wet1 + outL * wet2 + *inputR * dry;
-
- // Increment sample pointers, allowing for interleave (if any)
- inputL += skip;
- inputR += skip;
- outputL += skip;
- outputR += skip;
- }
-}
-
-void revmodel::update() {
- // Recalculate internal values after parameter change
-
- int i;
-
- wet1 = wet * (width / 2 + 0.5f);
- wet2 = wet * ((1 - width) / 2);
-
- if (mode >= freezemode) {
- roomsize1 = 1;
- damp1 = 0;
- gain = muted;
- } else {
- roomsize1 = roomsize;
- damp1 = damp;
- gain = fixedgain;
- }
-
- for (i = 0; i < numcombs; i++) {
- combL[i].setfeedback(roomsize1);
- combR[i].setfeedback(roomsize1);
- }
-
- for (i = 0; i < numcombs; i++) {
- combL[i].setdamp(damp1);
- combR[i].setdamp(damp1);
- }
-}
-
-// The following get/set functions are not inlined, because
-// speed is never an issue when calling them, and also
-// because as you develop the reverb model, you may
-// wish to take dynamic action when they are called.
-
-void revmodel::setroomsize(float value) {
- roomsize = (value * scaleroom) + offsetroom;
- update();
-}
-
-float revmodel::getroomsize() {
- return (roomsize - offsetroom) / scaleroom;
-}
-
-void revmodel::setdamp(float value) {
- damp = value * scaledamp;
- update();
-}
-
-float revmodel::getdamp() {
- return damp / scaledamp;
-}
-
-void revmodel::setwet(float value) {
- wet = value * scalewet;
- update();
-}
-
-float revmodel::getwet() {
- return wet / scalewet;
-}
-
-void revmodel::setdry(float value) {
- dry = value * scaledry;
-}
-
-float revmodel::getdry() {
- return dry / scaledry;
-}
-
-void revmodel::setwidth(float value) {
- width = value;
- update();
-}
-
-float revmodel::getwidth() {
- return width;
-}
-
-void revmodel::setmode(float value) {
- mode = value;
- update();
-}
-
-float revmodel::getmode() {
- if (mode >= freezemode)
- return 1;
- else
- return 0;
-}
diff --git a/engines/sci/sfx/softseq/mt32/freeverb.h b/engines/sci/sfx/softseq/mt32/freeverb.h
deleted file mode 100644
index 53c5307c5a..0000000000
--- a/engines/sci/sfx/softseq/mt32/freeverb.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * 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.
- *
- * $URL$
- * $Id$
- *
- */
-
-// Macro for killing denormalled numbers
-//
-// Written by Jezar at Dreampoint, June 2000
-// http://www.dreampoint.co.uk
-// Based on IS_DENORMAL macro by Jon Watte
-// This code is public domain
-
-#ifndef FREEVERB_H
-#define FREEVERB_H
-
-#define undenormalise(sample) if (((*(unsigned int*)&sample) & 0x7f800000) == 0) sample = 0.0f
-
-// Comb filter class declaration
-
-class comb {
-public:
- comb();
- void setbuffer(float *buf, int size);
- inline float process(float inp);
- void mute();
- void setdamp(float val);
- float getdamp();
- void setfeedback(float val);
- float getfeedback();
-private:
- float feedback;
- float filterstore;
- float damp1;
- float damp2;
- float *buffer;
- int bufsize;
- int bufidx;
-};
-
-
-// Big to inline - but crucial for speed
-
-inline float comb::process(float input) {
- float output;
-
- output = buffer[bufidx];
- undenormalise(output);
-
- filterstore = (output * damp2) + (filterstore * damp1);
- undenormalise(filterstore);
-
- buffer[bufidx] = input + (filterstore * feedback);
-
- if (++bufidx >= bufsize)
- bufidx = 0;
-
- return output;
-}
-
-// Allpass filter declaration
-
-class allpass {
-public:
- allpass();
- void setbuffer(float *buf, int size);
- inline float process(float inp);
- void mute();
- void setfeedback(float val);
- float getfeedback();
-private:
- float feedback;
- float *buffer;
- int bufsize;
- int bufidx;
-};
-
-
-// Big to inline - but crucial for speed
-
-inline float allpass::process(float input) {
- float output;
- float bufout;
-
- bufout = buffer[bufidx];
- undenormalise(bufout);
-
- output = -input + bufout;
- buffer[bufidx] = input + (bufout * feedback);
-
- if (++bufidx >= bufsize)
- bufidx = 0;
-
- return output;
-}
-
-
-// Reverb model tuning values
-
-const int numcombs = 8;
-const int numallpasses = 4;
-const float muted = 0;
-const float fixedgain = 0.015f;
-const float scalewet = 3;
-const float scaledry = 2;
-const float scaledamp = 0.4f;
-const float scaleroom = 0.28f;
-const float offsetroom = 0.7f;
-const float initialroom = 0.5f;
-const float initialdamp = 0.5f;
-const float initialwet = 1 / scalewet;
-const float initialdry = 0;
-const float initialwidth = 1;
-const float initialmode = 0;
-const float freezemode = 0.5f;
-const int stereospread = 23;
-
-// These values assume 44.1KHz sample rate
-// they will probably be OK for 48KHz sample rate
-// but would need scaling for 96KHz (or other) sample rates.
-// The values were obtained by listening tests.
-const int combtuningL1 = 1116;
-const int combtuningR1 = 1116 + stereospread;
-const int combtuningL2 = 1188;
-const int combtuningR2 = 1188 + stereospread;
-const int combtuningL3 = 1277;
-const int combtuningR3 = 1277 + stereospread;
-const int combtuningL4 = 1356;
-const int combtuningR4 = 1356 + stereospread;
-const int combtuningL5 = 1422;
-const int combtuningR5 = 1422 + stereospread;
-const int combtuningL6 = 1491;
-const int combtuningR6 = 1491 + stereospread;
-const int combtuningL7 = 1557;
-const int combtuningR7 = 1557 + stereospread;
-const int combtuningL8 = 1617;
-const int combtuningR8 = 1617 + stereospread;
-const int allpasstuningL1 = 556;
-const int allpasstuningR1 = 556 + stereospread;
-const int allpasstuningL2 = 441;
-const int allpasstuningR2 = 441 + stereospread;
-const int allpasstuningL3 = 341;
-const int allpasstuningR3 = 341 + stereospread;
-const int allpasstuningL4 = 225;
-const int allpasstuningR4 = 225 + stereospread;
-
-
-// Reverb model declaration
-
-class revmodel {
-public:
- revmodel();
- void mute();
- void processmix(float *inputL, float *inputR, float *outputL, float *outputR, long numsamples, int skip);
- void processreplace(float *inputL, float *inputR, float *outputL, float *outputR, long numsamples, int skip);
- void setroomsize(float value);
- float getroomsize();
- void setdamp(float value);
- float getdamp();
- void setwet(float value);
- float getwet();
- void setdry(float value);
- float getdry();
- void setwidth(float value);
- float getwidth();
- void setmode(float value);
- float getmode();
-private:
- void update();
-
- float gain;
- float roomsize, roomsize1;
- float damp, damp1;
- float wet, wet1, wet2;
- float dry;
- float width;
- float mode;
-
- // The following are all declared inline
- // to remove the need for dynamic allocation
- // with its subsequent error-checking messiness
-
- // Comb filters
- comb combL[numcombs];
- comb combR[numcombs];
-
- // Allpass filters
- allpass allpassL[numallpasses];
- allpass allpassR[numallpasses];
-
- // Buffers for the combs
- float bufcombL1[combtuningL1];
- float bufcombR1[combtuningR1];
- float bufcombL2[combtuningL2];
- float bufcombR2[combtuningR2];
- float bufcombL3[combtuningL3];
- float bufcombR3[combtuningR3];
- float bufcombL4[combtuningL4];
- float bufcombR4[combtuningR4];
- float bufcombL5[combtuningL5];
- float bufcombR5[combtuningR5];
- float bufcombL6[combtuningL6];
- float bufcombR6[combtuningR6];
- float bufcombL7[combtuningL7];
- float bufcombR7[combtuningR7];
- float bufcombL8[combtuningL8];
- float bufcombR8[combtuningR8];
-
- // Buffers for the allpasses
- float bufallpassL1[allpasstuningL1];
- float bufallpassR1[allpasstuningR1];
- float bufallpassL2[allpasstuningL2];
- float bufallpassR2[allpasstuningR2];
- float bufallpassL3[allpasstuningL3];
- float bufallpassR3[allpasstuningR3];
- float bufallpassL4[allpasstuningL4];
- float bufallpassR4[allpasstuningR4];
-};
-
-#endif
diff --git a/engines/sci/sfx/softseq/mt32/i386.cpp b/engines/sci/sfx/softseq/mt32/i386.cpp
deleted file mode 100644
index f092189d76..0000000000
--- a/engines/sci/sfx/softseq/mt32/i386.cpp
+++ /dev/null
@@ -1,849 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include "mt32emu.h"
-
-#ifdef MT32EMU_HAVE_X86
-
-namespace MT32Emu {
-
-#ifndef _MSC_VER
-
-#define eflag(value) __asm__ __volatile__("pushfl \n popfl \n" : : "a"(value))
-#define cpuid_flag (1 << 21)
-
-static inline bool atti386_DetectCPUID() {
- unsigned int result;
-
- // Is there a cpuid?
- result = cpuid_flag; // set test
- eflag(result);
- if (!(result & cpuid_flag))
- return false;
-
- result = 0; // clear test
- eflag(result);
- if (result & cpuid_flag)
- return false;
-
- return true;
-}
-
-static inline bool atti386_DetectSIMD() {
- unsigned int result;
-
- if (atti386_DetectCPUID() == false)
- return false;
-
- /* check cpuid */
- __asm__ __volatile__(
- "pushl %%ebx \n" \
- "movl $1, %%eax \n" \
- "cpuid \n" \
- "movl %%edx, %0 \n" \
- "popl %%ebx \n" \
- : "=r"(result) : : "eax", "ecx", "edx");
-
- if (result & (1 << 25))
- return true;
-
- return false;
-}
-
-static inline bool atti386_Detect3DNow() {
- unsigned int result;
-
- if (atti386_DetectCPUID() == false)
- return false;
-
- // get cpuid
- __asm__ __volatile__(
- "pushl %%ebx \n" \
- "movl $0x80000001, %%eax \n" \
- "cpuid \n" \
- "movl %%edx, %0 \n" \
- "popl %%ebx \n" \
- : "=r"(result) : : "eax", "ecx", "edx");
-
- if (result & 0x80000000)
- return true;
-
- return false;
-}
-
-
-static inline float atti386_iir_filter_sse(float *output, float *hist1_ptr, float *coef_ptr) {
- __asm__ __volatile__ (
- "pushl %1 \n" \
- "pushl %2 \n" \
- "movss 0(%0), %%xmm1 \n" \
- "movups 0(%1), %%xmm2 \n" \
- "movlps 0(%2), %%xmm3 \n" \
- " \n" \
- "shufps $0x44, %%xmm3, %%xmm3 \n" \
- " \n" \
- "mulps %%xmm3, %%xmm2 \n" \
- " \n" \
- "subss %%xmm2, %%xmm1 \n" \
- "shufps $0x39, %%xmm2, %%xmm2 \n" \
- "subss %%xmm2, %%xmm1 \n" \
- " \n" \
- "movss %%xmm1, 0(%2) \n" \
- " \n" \
- "shufps $0x39, %%xmm2, %%xmm2 \n" \
- "addss %%xmm2, %%xmm1 \n" \
- " \n" \
- "shufps $0x39, %%xmm2, %%xmm2 \n" \
- "addss %%xmm2, %%xmm1 \n" \
- " \n" \
- "movss %%xmm3, 4(%2) \n" \
- " \n" \
- "addl $16, %1 \n" \
- "addl $8, %2 \n" \
- " \n" \
- "movups 0(%1), %%xmm2 \n" \
- " \n" \
- "movlps 0(%2), %%xmm3 \n" \
- "shufps $0x44, %%xmm3, %%xmm3 \n" \
- " \n" \
- "mulps %%xmm3, %%xmm2 \n" \
- " \n" \
- "subss %%xmm2, %%xmm1 \n" \
- "shufps $0x39, %%xmm2, %%xmm2 \n" \
- "subss %%xmm2, %%xmm1 \n" \
- " \n" \
- "movss %%xmm1, 0(%2) \n" \
- " \n" \
- "shufps $0x39, %%xmm2, %%xmm2 \n" \
- "addss %%xmm2, %%xmm1 \n" \
- " \n" \
- "shufps $0x39, %%xmm2, %%xmm2 \n" \
- "addss %%xmm2, %%xmm1 \n" \
- " \n" \
- "movss %%xmm3, 4(%2) \n" \
- "movss %%xmm1, 0(%0) \n" \
- "popl %2 \n" \
- "popl %1 \n" \
- : : "r"(output), "r"(coef_ptr), "r"(hist1_ptr)
- : "memory"
-#ifdef __SSE__
- , "xmm1", "xmm2", "xmm3"
-#endif
- );
-
- return *output;
-}
-
-static inline float atti386_iir_filter_3DNow(float output, float *hist1_ptr, float *coef_ptr) {
- float tmp;
-
- __asm__ __volatile__ (
- "movq %0, %%mm1 \n" \
- " \n" \
- "movl %1, %%edi \n" \
- "movq 0(%%edi), %%mm2 \n" \
- " \n" \
- "movl %2, %%eax; \n" \
- "movq 0(%%eax), %%mm3 \n" \
- " \n" \
- "pfmul %%mm3, %%mm2 \n" \
- "pfsub %%mm2, %%mm1 \n" \
- " \n" \
- "psrlq $32, %%mm2 \n" \
- "pfsub %%mm2, %%mm1 \n" \
- " \n" \
- "movd %%mm1, %3 \n" \
- " \n" \
- "addl $8, %%edi \n" \
- "movq 0(%%edi), %%mm2 \n" \
- "movq 0(%%eax), %%mm3 \n" \
- " \n" \
- "pfmul %%mm3, %%mm2 \n" \
- "pfadd %%mm2, %%mm1 \n" \
- " \n" \
- "psrlq $32, %%mm2 \n" \
- "pfadd %%mm2, %%mm1 \n" \
- " \n" \
- "pushl %3 \n" \
- "popl 0(%%eax) \n" \
- " \n" \
- "movd %%mm3, 4(%%eax) \n" \
- " \n" \
- "addl $8, %%edi \n" \
- "addl $8, %%eax \n" \
- " \n" \
- "movq 0(%%edi), %%mm2 \n" \
- "movq 0(%%eax), %%mm3 \n" \
- " \n" \
- "pfmul %%mm3, %%mm2 \n" \
- "pfsub %%mm2, %%mm1 \n" \
- " \n" \
- "psrlq $32, %%mm2 \n" \
- "pfsub %%mm2, %%mm1 \n" \
- " \n" \
- "movd %%mm1, %3 \n" \
- " \n" \
- "addl $8, %%edi \n" \
- "movq 0(%%edi), %%mm2 \n" \
- "movq 0(%%eax), %%mm3 \n" \
- " \n" \
- "pfmul %%mm3, %%mm2 \n" \
- "pfadd %%mm2, %%mm1 \n" \
- " \n" \
- "psrlq $32, %%mm2 \n" \
- "pfadd %%mm2, %%mm1 \n" \
- " \n" \
- "pushl %3 \n" \
- "popl 0(%%eax) \n" \
- "movd %%mm3, 4(%%eax) \n" \
- " \n" \
- "movd %%mm1, %0 \n" \
- "femms \n" \
- : "=m"(output) : "g"(coef_ptr), "g"(hist1_ptr), "m"(tmp)
- : "eax", "edi", "memory"
-#ifdef __MMX__
- , "mm1", "mm2", "mm3"
-#endif
- );
-
- return output;
-}
-
-static inline void atti386_produceOutput1(int tmplen, Bit16s myvolume, Bit16s *useBuf, Bit16s *snd) {
- __asm__ __volatile__(
- "movl %0, %%ecx \n" \
- "movw %1, %%ax \n" \
- "shll $16, %%eax \n" \
- "movw %1, %%ax \n" \
- "movd %%eax, %%mm3 \n" \
- "movd %%eax, %%mm2 \n" \
- "psllq $32, %%mm3 \n" \
- "por %%mm2, %%mm3 \n" \
- "movl %2, %%esi \n" \
- "movl %3, %%edi \n" \
- "1: \n" \
- "movq 0(%%esi), %%mm1 \n" \
- "movq 0(%%edi), %%mm2 \n" \
- "pmulhw %%mm3, %%mm1 \n" \
- "paddw %%mm2, %%mm1 \n" \
- "movq %%mm1, 0(%%edi) \n" \
- " \n" \
- "addl $8, %%esi \n" \
- "addl $8, %%edi \n" \
- " \n" \
- "decl %%ecx \n" \
- "cmpl $0, %%ecx \n" \
- "jg 1b \n" \
- "emms \n" \
- : : "g"(tmplen), "g"(myvolume), "g"(useBuf), "g"(snd)
- : "eax", "ecx", "edi", "esi", "memory"
-#ifdef __MMX__
- , "mm1", "mm2", "mm3"
-#endif
- );
-}
-
-static inline void atti386_produceOutput2(Bit32u len, Bit16s *snd, float *sndbufl, float *sndbufr, float *multFactor) {
- __asm__ __volatile__(
- "movl %4, %%ecx \n" \
- "shrl $1, %%ecx \n" \
- "addl $4, %%ecx \n" \
- "pushl %%ecx \n" \
- " \n" \
- "movl %0, %%esi \n" \
- "movups 0(%%esi), %%xmm1 \n" \
- " \n" \
- "movl %1, %%esi \n" \
- "movl %2, %%edi \n" \
- "1: \n" \
- "xorl %%eax, %%eax \n" \
- "movw 0(%1), %%ax \n" \
- "cwde \n" \
- "incl %1 \n" \
- "incl %1 \n" \
- "movd %%eax, %%mm1 \n" \
- "psrlq $32, %%mm1 \n" \
- "movw 0(%1), %%ax \n" \
- "incl %1 \n" \
- "incl %1 \n" \
- "movd %%eax, %%mm2 \n" \
- "por %%mm2, %%mm1 \n" \
- " \n" \
- "decl %%ecx \n" \
- "jnz 1b \n" \
- " \n" \
- "popl %%ecx \n" \
- "movl %1, %%esi \n" \
- "movl %3, %%edi \n" \
- "incl %%esi \n" \
- "2: \n" \
- "decl %%ecx \n" \
- "jnz 2b \n" \
- : : "g"(multFactor), "r"(snd), "g"(sndbufl), "g"(sndbufr), "g"(len)
- : "eax", "ecx", "edi", "esi", "mm1", "mm2", "xmm1", "memory");
-}
-
-static inline void atti386_mixBuffers(Bit16s * buf1, Bit16s *buf2, int len) {
- __asm__ __volatile__(
- "movl %0, %%ecx \n" \
- "movl %1, %%esi \n" \
- "movl %2, %%edi \n" \
- "1: \n" \
- "movq 0(%%edi), %%mm1 \n" \
- "movq 0(%%esi), %%mm2 \n" \
- "paddw %%mm2, %%mm1 \n" \
- "movq %%mm1, 0(%%esi) \n" \
- "addl $8, %%edi \n" \
- "addl $8, %%esi \n" \
- "decl %%ecx \n" \
- "cmpl $0, %%ecx \n" \
- "jg 1b \n" \
- "emms \n" \
- : : "g"(len), "g"(buf1), "g"(buf2)
- : "ecx", "edi", "esi", "memory"
-#ifdef __MMX__
- , "mm1", "mm2"
-#endif
- );
-}
-
-static inline void atti386_mixBuffersRingMix(Bit16s * buf1, Bit16s *buf2, int len) {
- __asm__ __volatile__(
- "movl %0, %%ecx \n" \
- "movl %1, %%esi \n" \
- "movl %2, %%edi \n" \
- "1: \n" \
- "movq 0(%%esi), %%mm1 \n" \
- "movq 0(%%edi), %%mm2 \n" \
- "movq %%mm1, %%mm3 \n" \
- "pmulhw %%mm2, %%mm1 \n" \
- "paddw %%mm3, %%mm1 \n" \
- "movq %%mm1, 0(%%esi) \n" \
- "addl $8, %%edi \n" \
- "addl $8, %%esi \n" \
- "decl %%ecx \n" \
- "cmpl $0, %%ecx \n" \
- "jg 1b \n" \
- "emms \n" \
- : : "g"(len), "g"(buf1), "g"(buf2)
- : "ecx", "edi", "esi", "memory"
-#ifdef __MMX__
- , "mm1", "mm2", "mm3"
-#endif
- );
-}
-
-static inline void atti386_mixBuffersRing(Bit16s * buf1, Bit16s *buf2, int len) {
- __asm__ __volatile__(
- "movl %0, %%ecx \n" \
- "movl %1, %%esi \n" \
- "movl %2, %%edi \n" \
- "1: \n" \
- "movq 0(%%esi), %%mm1 \n" \
- "movq 0(%%edi), %%mm2 \n" \
- "pmulhw %%mm2, %%mm1 \n" \
- "movq %%mm1, 0(%%esi) \n" \
- "addl $8, %%edi \n" \
- "addl $8, %%esi \n" \
- "decl %%ecx \n" \
- "cmpl $0, %%ecx \n" \
- "jg 1b \n" \
- "emms \n" \
- : : "g"(len), "g"(buf1), "g"(buf2)
- : "ecx", "edi", "esi", "memory"
-#ifdef __MMX__
- , "mm1", "mm2"
-#endif
- );
-}
-
-static inline void atti386_partialProductOutput(int quadlen, Bit16s leftvol, Bit16s rightvol, Bit16s *partialBuf, Bit16s *p1buf) {
- __asm__ __volatile__(
- "movl %0, %%ecx \n" \
- "movw %1, %%ax \n" \
- "shll $16, %%eax \n" \
- "movw %2, %%ax \n" \
- "movd %%eax, %%mm1 \n" \
- "movd %%eax, %%mm2 \n" \
- "psllq $32, %%mm1 \n" \
- "por %%mm2, %%mm1 \n" \
- "movl %3, %%edi \n" \
- "movl %4, %%esi \n" \
- "pushl %%ebx \n" \
- "1: \n" \
- "movw 0(%%esi), %%bx \n" \
- "addl $2, %%esi \n" \
- "movw 0(%%esi), %%dx \n" \
- "addl $2, %%esi \n" \
- "" \
- "movw %%dx, %%ax \n" \
- "shll $16, %%eax \n" \
- "movw %%dx, %%ax \n" \
- "movd %%eax, %%mm2 \n" \
- "psllq $32, %%mm2 \n" \
- "movw %%bx, %%ax \n" \
- "shll $16, %%eax \n" \
- "movw %%bx, %%ax \n" \
- "movd %%eax, %%mm3 \n" \
- "por %%mm3, %%mm2 \n" \
- "" \
- "pmulhw %%mm1, %%mm2 \n" \
- "movq %%mm2, 0(%%edi) \n" \
- "addl $8, %%edi \n" \
- "" \
- "decl %%ecx \n" \
- "cmpl $0, %%ecx \n" \
- "jg 1b \n" \
- "emms \n" \
- "popl %%ebx \n" \
- : : "g"(quadlen), "g"(leftvol), "g"(rightvol), "g"(partialBuf), "g"(p1buf)
- : "eax", "ecx", "edx", "edi", "esi", "memory"
-#ifdef __MMX__
- , "mm1", "mm2", "mm3"
-#endif
- );
-}
-
-#endif
-
-bool DetectSIMD() {
-#ifdef _MSC_VER
- bool found_simd;
- __asm {
- pushfd
- pop eax // get EFLAGS into eax
- mov ebx,eax // keep a copy
- xor eax,0x200000
- // toggle CPUID bit
-
- push eax
- popfd // set new EFLAGS
- pushfd
- pop eax // EFLAGS back into eax
-
- xor eax,ebx
- // have we changed the ID bit?
-
- je NO_SIMD
- // No, no CPUID instruction
-
- // we could toggle the
- // ID bit so CPUID is present
- mov eax,1
-
- cpuid // get processor features
- test edx,1<<25 // check the SIMD bit
- jz NO_SIMD
- mov found_simd,1
- jmp DONE
- NO_SIMD:
- mov found_simd,0
- DONE:
- }
- return found_simd;
-#else
- return atti386_DetectSIMD();
-#endif
-}
-
-bool Detect3DNow() {
-#ifdef _MSC_VER
- bool found3D = false;
- __asm {
- pushfd
- pop eax
- mov edx, eax
- xor eax, 00200000h
- push eax
- popfd
- pushfd
- pop eax
- xor eax, edx
- jz NO_3DNOW
-
- mov eax, 80000000h
- cpuid
-
- cmp eax, 80000000h
- jbe NO_3DNOW
-
- mov eax, 80000001h
- cpuid
- test edx, 80000000h
- jz NO_3DNOW
- mov found3D, 1
-NO_3DNOW:
-
- }
- return found3D;
-#else
- return atti386_Detect3DNow();
-#endif
-}
-
-float iir_filter_sse(float input,float *hist1_ptr, float *coef_ptr) {
- float output;
-
- // 1st number of coefficients array is overall input scale factor, or filter gain
- output = input * (*coef_ptr++);
-
-#ifdef _MSC_VER
- __asm {
-
- movss xmm1, output
-
- mov eax, coef_ptr
- movups xmm2, [eax]
-
- mov eax, hist1_ptr
- movlps xmm3, [eax]
- shufps xmm3, xmm3, 44h
- // hist1_ptr+1, hist1_ptr, hist1_ptr+1, hist1_ptr
-
- mulps xmm2, xmm3
-
- subss xmm1, xmm2
- // Rotate elements right
- shufps xmm2, xmm2, 39h
- subss xmm1, xmm2
-
- // Store new_hist
- movss DWORD PTR [eax], xmm1
-
- // Rotate elements right
- shufps xmm2, xmm2, 39h
- addss xmm1, xmm2
-
- // Rotate elements right
- shufps xmm2, xmm2, 39h
- addss xmm1, xmm2
-
- // Store previous hist
- movss DWORD PTR [eax+4], xmm3
-
- add coef_ptr, 16
- add hist1_ptr, 8
-
- mov eax, coef_ptr
- movups xmm2, [eax]
-
- mov eax, hist1_ptr
- movlps xmm3, [eax]
- shufps xmm3, xmm3, 44h
- // hist1_ptr+1, hist1_ptr, hist1_ptr+1, hist1_ptr
-
- mulps xmm2, xmm3
-
- subss xmm1, xmm2
- // Rotate elements right
- shufps xmm2, xmm2, 39h
- subss xmm1, xmm2
-
- // Store new_hist
- movss DWORD PTR [eax], xmm1
-
- // Rotate elements right
- shufps xmm2, xmm2, 39h
- addss xmm1, xmm2
-
- // Rotate elements right
- shufps xmm2, xmm2, 39h
- addss xmm1, xmm2
-
- // Store previous hist
- movss DWORD PTR [eax+4], xmm3
-
- movss output, xmm1
- }
-#else
- output = atti386_iir_filter_sse(&output, hist1_ptr, coef_ptr);
-#endif
- return output;
-}
-
-float iir_filter_3dnow(float input,float *hist1_ptr, float *coef_ptr) {
- float output;
-
- // 1st number of coefficients array is overall input scale factor, or filter gain
- output = input * (*coef_ptr++);
-
- // I find it very sad that 3DNow requires twice as many instructions as Intel's SSE
- // Intel does have the upper hand here.
-#ifdef _MSC_VER
- float tmp;
- __asm {
- movq mm1, output
- mov ebx, coef_ptr
- movq mm2, [ebx]
-
- mov eax, hist1_ptr;
- movq mm3, [eax]
-
- pfmul mm2, mm3
- pfsub mm1, mm2
-
- psrlq mm2, 32
- pfsub mm1, mm2
-
- // Store new hist
- movd tmp, mm1
-
- add ebx, 8
- movq mm2, [ebx]
- movq mm3, [eax]
-
- pfmul mm2, mm3
- pfadd mm1, mm2
-
- psrlq mm2, 32
- pfadd mm1, mm2
-
- push tmp
- pop DWORD PTR [eax]
-
- movd DWORD PTR [eax+4], mm3
-
- add ebx, 8
- add eax, 8
-
- movq mm2, [ebx]
- movq mm3, [eax]
-
- pfmul mm2, mm3
- pfsub mm1, mm2
-
- psrlq mm2, 32
- pfsub mm1, mm2
-
- // Store new hist
- movd tmp, mm1
-
- add ebx, 8
- movq mm2, [ebx]
- movq mm3, [eax]
-
- pfmul mm2, mm3
- pfadd mm1, mm2
-
- psrlq mm2, 32
- pfadd mm1, mm2
-
- push tmp
- pop DWORD PTR [eax]
- movd DWORD PTR [eax+4], mm3
-
- movd output, mm1
-
- femms
- }
-#else
- output = atti386_iir_filter_3DNow(output, hist1_ptr, coef_ptr);
-#endif
- return output;
-}
-
-#if MT32EMU_USE_MMX > 0
-
-int i386_partialProductOutput(int len, Bit16s leftvol, Bit16s rightvol, Bit16s *partialBuf, Bit16s *mixedBuf) {
- int tmplen = len >> 1;
- if (tmplen == 0) {
- return 0;
- }
-#ifdef _MSC_VER
- __asm {
- mov ecx,tmplen
- mov ax, leftvol
- shl eax,16
- mov ax, rightvol
- movd mm1, eax
- movd mm2, eax
- psllq mm1, 32
- por mm1, mm2
- mov edi, partialBuf
- mov esi, mixedBuf
-mmxloop1:
- mov bx, [esi]
- add esi,2
- mov dx, [esi]
- add esi,2
-
- mov ax, dx
- shl eax, 16
- mov ax, dx
- movd mm2,eax
- psllq mm2, 32
- mov ax, bx
- shl eax, 16
- mov ax, bx
- movd mm3,eax
- por mm2,mm3
-
- pmulhw mm2, mm1
- movq [edi], mm2
- add edi, 8
-
- dec ecx
- cmp ecx,0
- jg mmxloop1
- emms
- }
-#else
- atti386_partialProductOutput(tmplen, leftvol, rightvol, partialBuf, mixedBuf);
-#endif
- return tmplen << 1;
-}
-
-int i386_mixBuffers(Bit16s * buf1, Bit16s *buf2, int len) {
- int tmplen = len >> 2;
- if (tmplen == 0) {
- return 0;
- }
-#ifdef _MSC_VER
- __asm {
- mov ecx, tmplen
- mov esi, buf1
- mov edi, buf2
-
-mixloop1:
- movq mm1, [edi]
- movq mm2, [esi]
- paddw mm1,mm2
- movq [esi],mm1
- add edi,8
- add esi,8
-
- dec ecx
- cmp ecx,0
- jg mixloop1
- emms
- }
-#else
- atti386_mixBuffers(buf1, buf2, tmplen);
-#endif
- return tmplen << 2;
-}
-
-
-int i386_mixBuffersRingMix(Bit16s * buf1, Bit16s *buf2, int len) {
- int tmplen = len >> 2;
- if (tmplen == 0) {
- return 0;
- }
-#ifdef _MSC_VER
- __asm {
- mov ecx, tmplen
- mov esi, buf1
- mov edi, buf2
-
-mixloop2:
- movq mm1, [esi]
- movq mm2, [edi]
- movq mm3, mm1
- pmulhw mm1, mm2
- paddw mm1,mm3
- movq [esi],mm1
- add edi,8
- add esi,8
-
- dec ecx
- cmp ecx,0
- jg mixloop2
- emms
- }
-#else
- atti386_mixBuffersRingMix(buf1, buf2, tmplen);
-#endif
- return tmplen << 2;
-}
-
-int i386_mixBuffersRing(Bit16s * buf1, Bit16s *buf2, int len) {
- int tmplen = len >> 2;
- if (tmplen == 0) {
- return 0;
- }
-#ifdef _MSC_VER
- __asm {
- mov ecx, tmplen
- mov esi, buf1
- mov edi, buf2
-
-mixloop3:
- movq mm1, [esi]
- movq mm2, [edi]
- pmulhw mm1, mm2
- movq [esi],mm1
- add edi,8
- add esi,8
-
- dec ecx
- cmp ecx,0
- jg mixloop3
- emms
- }
-#else
- atti386_mixBuffersRing(buf1, buf2, tmplen);
-#endif
- return tmplen << 2;
-}
-
-int i386_produceOutput1(Bit16s *useBuf, Bit16s *stream, Bit32u len, Bit16s volume) {
- int tmplen = (len >> 1);
- if (tmplen == 0) {
- return 0;
- }
-#ifdef _MSC_VER
- __asm {
- mov ecx, tmplen
- mov ax,volume
- shl eax,16
- mov ax,volume
- movd mm3,eax
- movd mm2,eax
- psllq mm3, 32
- por mm3,mm2
- mov esi, useBuf
- mov edi, stream
-mixloop4:
- movq mm1, [esi]
- movq mm2, [edi]
- pmulhw mm1, mm3
- paddw mm1,mm2
- movq [edi], mm1
-
- add esi,8
- add edi,8
-
- dec ecx
- cmp ecx,0
- jg mixloop4
- emms
- }
-#else
- atti386_produceOutput1(tmplen, volume, useBuf, stream);
-#endif
- return tmplen << 1;
-}
-
-#endif
-
-}
-
-#endif
diff --git a/engines/sci/sfx/softseq/mt32/i386.h b/engines/sci/sfx/softseq/mt32/i386.h
deleted file mode 100644
index e8644411cd..0000000000
--- a/engines/sci/sfx/softseq/mt32/i386.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef MT32EMU_I386_H
-#define MT32EMU_I386_H
-
-namespace MT32Emu {
-#ifdef MT32EMU_HAVE_X86
-
-// Function that detects the availablity of SSE SIMD instructions
-bool DetectSIMD();
-// Function that detects the availablity of 3DNow instructions
-bool Detect3DNow();
-
-float iir_filter_sse(float input,float *hist1_ptr, float *coef_ptr);
-float iir_filter_3dnow(float input,float *hist1_ptr, float *coef_ptr);
-float iir_filter_normal(float input,float *hist1_ptr, float *coef_ptr);
-
-#if MT32EMU_USE_MMX > 0
-int i386_partialProductOutput(int len, Bit16s leftvol, Bit16s rightvol, Bit16s *partialBuf, Bit16s *mixedBuf);
-int i386_mixBuffers(Bit16s * buf1, Bit16s *buf2, int len);
-int i386_mixBuffersRingMix(Bit16s * buf1, Bit16s *buf2, int len);
-int i386_mixBuffersRing(Bit16s * buf1, Bit16s *buf2, int len);
-int i386_produceOutput1(Bit16s *useBuf, Bit16s *stream, Bit32u len, Bit16s volume);
-#endif
-
-#endif
-
-}
-
-#endif
diff --git a/engines/sci/sfx/softseq/mt32/mt32_file.cpp b/engines/sci/sfx/softseq/mt32/mt32_file.cpp
deleted file mode 100644
index 86cb29fd49..0000000000
--- a/engines/sci/sfx/softseq/mt32/mt32_file.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include <stdio.h>
-
-#include "mt32emu.h"
-
-namespace MT32Emu {
-
- bool ANSIFile::open(const char *filename, OpenMode mode) {
- const char *fmode;
- if (mode == OpenMode_read) {
- fmode = "rb";
- } else {
- fmode = "wb";
- }
- fp = fopen(filename, fmode);
- return (fp != NULL);
- }
-
- void ANSIFile::close() {
- fclose(fp);
- }
-
- size_t ANSIFile::read(void *in, size_t size) {
- return fread(in, 1, size, fp);
- }
-
- bool ANSIFile::readLine(char *in, size_t size) {
- return fgets(in, (int)size, fp) != NULL;
- }
-
- bool ANSIFile::readBit8u(Bit8u *in) {
- int c = fgetc(fp);
- if (c == EOF)
- return false;
- *in = (Bit8u)c;
- return true;
- }
-
- bool File::readBit16u(Bit16u *in) {
- Bit8u b[2];
- if (read(&b[0], 2) != 2)
- return false;
- *in = ((b[0] << 8) | b[1]);
- return true;
- }
-
- bool File::readBit32u(Bit32u *in) {
- Bit8u b[4];
- if (read(&b[0], 4) != 4)
- return false;
- *in = ((b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]);
- return true;
- }
-
- size_t ANSIFile::write(const void *out, size_t size) {
- return fwrite(out, 1, size, fp);
- }
-
- bool ANSIFile::writeBit8u(Bit8u out) {
- return fputc(out, fp) != EOF;
- }
-
- bool File::writeBit16u(Bit16u out) {
- if (!writeBit8u((Bit8u)((out & 0xFF00) >> 8))) {
- return false;
- }
- if (!writeBit8u((Bit8u)(out & 0x00FF))) {
- return false;
- }
- return true;
- }
-
- bool File::writeBit32u(Bit32u out) {
- if (!writeBit8u((Bit8u)((out & 0xFF000000) >> 24))) {
- return false;
- }
- if (!writeBit8u((Bit8u)((out & 0x00FF0000) >> 16))) {
- return false;
- }
- if (!writeBit8u((Bit8u)((out & 0x0000FF00) >> 8))) {
- return false;
- }
- if (!writeBit8u((Bit8u)(out & 0x000000FF))) {
- return false;
- }
- return true;
- }
-
- bool ANSIFile::isEOF() {
- return feof(fp) != 0;
- }
-}
diff --git a/engines/sci/sfx/softseq/mt32/mt32_file.h b/engines/sci/sfx/softseq/mt32/mt32_file.h
deleted file mode 100644
index 5f05c9e9ae..0000000000
--- a/engines/sci/sfx/softseq/mt32/mt32_file.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef MT32EMU_FILE_H
-#define MT32EMU_FILE_H
-
-#include <stdio.h>
-
-namespace MT32Emu {
-
-class File {
-public:
- enum OpenMode {
- OpenMode_read = 0,
- OpenMode_write = 1
- };
- virtual ~File() {}
- virtual void close() = 0;
- virtual size_t read(void *in, size_t size) = 0;
- virtual bool readLine(char *in, size_t size) = 0;
- virtual bool readBit8u(Bit8u *in) = 0;
- virtual bool readBit16u(Bit16u *in);
- virtual bool readBit32u(Bit32u *in);
- virtual size_t write(const void *out, size_t size) = 0;
- virtual bool writeBit8u(Bit8u out) = 0;
- // Note: May write a single byte to the file before failing
- virtual bool writeBit16u(Bit16u out);
- // Note: May write some (<4) bytes to the file before failing
- virtual bool writeBit32u(Bit32u out);
- virtual bool isEOF() = 0;
-};
-
-class ANSIFile: public File {
-private:
- FILE *fp;
-public:
- bool open(const char *filename, OpenMode mode);
- void close();
- size_t read(void *in, size_t size);
- bool readLine(char *in, size_t size);
- bool readBit8u(Bit8u *in);
- size_t write(const void *out, size_t size);
- bool writeBit8u(Bit8u out);
- bool isEOF();
-};
-
-}
-
-#endif
diff --git a/engines/sci/sfx/softseq/mt32/mt32emu.h b/engines/sci/sfx/softseq/mt32/mt32emu.h
deleted file mode 100644
index 0aa4df7488..0000000000
--- a/engines/sci/sfx/softseq/mt32/mt32emu.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef MT32EMU_MT32EMU_H
-#define MT32EMU_MT32EMU_H
-
-// Debugging
-// Show the instruments played
-#define MT32EMU_MONITOR_INSTRUMENTS 1
-// Shows number of partials MT-32 is playing, and on which parts
-#define MT32EMU_MONITOR_PARTIALS 0
-// Determines how the waveform cache file is handled (must be regenerated after sampling rate change)
-#define MT32EMU_WAVECACHEMODE 0 // Load existing cache if possible, otherwise generate and save cache
-//#define MT32EMU_WAVECACHEMODE 1 // Load existing cache if possible, otherwise generage but don't save cache
-//#define MT32EMU_WAVECACHEMODE 2 // Ignore existing cache, generate and save cache
-//#define MT32EMU_WAVECACHEMODE 3 // Ignore existing cache, generate but don't save cache
-
-// Configuration
-// The maximum number of partials playing simultaneously
-#define MT32EMU_MAX_PARTIALS 32
-// The maximum number of notes playing simultaneously per part.
-// No point making it more than MT32EMU_MAX_PARTIALS, since each note needs at least one partial.
-#define MT32EMU_MAX_POLY 32
-// This calculates the exact frequencies of notes as they are played, instead of offsetting from pre-cached semitones. Potentially very slow.
-#define MT32EMU_ACCURATENOTES 0
-
-#if (defined (_MSC_VER) && defined(_M_IX86))
-#define MT32EMU_HAVE_X86
-#elif defined(__GNUC__)
-#if __GNUC__ >= 3 && defined(__i386__)
-#define MT32EMU_HAVE_X86
-#endif
-#endif
-
-#ifdef MT32EMU_HAVE_X86
-#define MT32EMU_USE_MMX 1
-#else
-#define MT32EMU_USE_MMX 0
-#endif
-
-#include "freeverb.h"
-
-#include "structures.h"
-#include "i386.h"
-#include "mt32_file.h"
-#include "tables.h"
-#include "partial.h"
-#include "partialManager.h"
-#include "part.h"
-#include "synth.h"
-
-#endif
diff --git a/engines/sci/sfx/softseq/mt32/part.cpp b/engines/sci/sfx/softseq/mt32/part.cpp
deleted file mode 100644
index b3d71bccca..0000000000
--- a/engines/sci/sfx/softseq/mt32/part.cpp
+++ /dev/null
@@ -1,632 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include <string.h>
-#include <math.h>
-
-#include "mt32emu.h"
-
-namespace MT32Emu {
-
-static const Bit8u PartialStruct[13] = {
- 0, 0, 2, 2, 1, 3,
- 3, 0, 3, 0, 2, 1, 3 };
-
-static const Bit8u PartialMixStruct[13] = {
- 0, 1, 0, 1, 1, 0,
- 1, 3, 3, 2, 2, 2, 2 };
-
-static const float floatKeyfollow[17] = {
- -1.0f, -1.0f/2.0f, -1.0f/4.0f, 0.0f,
- 1.0f/8.0f, 1.0f/4.0f, 3.0f/8.0f, 1.0f/2.0f, 5.0f/8.0f, 3.0f/4.0f, 7.0f/8.0f, 1.0f,
- 5.0f/4.0f, 3.0f/2.0f, 2.0f,
- 1.0009765625f, 1.0048828125f
-};
-
-//FIXME:KG: Put this dpoly stuff somewhere better
-bool dpoly::isActive() const {
- return partials[0] != NULL || partials[1] != NULL || partials[2] != NULL || partials[3] != NULL;
-}
-
-Bit32u dpoly::getAge() const {
- for (int i = 0; i < 4; i++) {
- if (partials[i] != NULL) {
- return partials[i]->age;
- }
- }
- return 0;
-}
-
-RhythmPart::RhythmPart(Synth *useSynth, unsigned int usePartNum): Part(useSynth, usePartNum) {
- strcpy(name, "Rhythm");
- rhythmTemp = &synth->mt32ram.rhythmSettings[0];
- refresh();
-}
-
-Part::Part(Synth *useSynth, unsigned int usePartNum) {
- this->synth = useSynth;
- this->partNum = usePartNum;
- patchCache[0].dirty = true;
- holdpedal = false;
- patchTemp = &synth->mt32ram.patchSettings[partNum];
- if (usePartNum == 8) {
- // Nasty hack for rhythm
- timbreTemp = NULL;
- } else {
- sprintf(name, "Part %d", partNum + 1);
- timbreTemp = &synth->mt32ram.timbreSettings[partNum];
- }
- currentInstr[0] = 0;
- currentInstr[10] = 0;
- expression = 127;
- volumeMult = 0;
- volumesetting.leftvol = 32767;
- volumesetting.rightvol = 32767;
- bend = 0.0f;
- memset(polyTable,0,sizeof(polyTable));
- memset(patchCache, 0, sizeof(patchCache));
-}
-
-void Part::setHoldPedal(bool pedalval) {
- if (holdpedal && !pedalval) {
- holdpedal = false;
- stopPedalHold();
- } else {
- holdpedal = pedalval;
- }
-}
-
-void RhythmPart::setBend(unsigned int midiBend) {
- synth->printDebug("%s: Setting bend (%d) not supported on rhythm", name, midiBend);
- return;
-}
-
-void Part::setBend(unsigned int midiBend) {
- // FIXME:KG: Slightly unbalanced increments, but I wanted min -1.0, centre 0.0 and max 1.0
- if (midiBend <= 0x2000) {
- bend = ((signed int)midiBend - 0x2000) / (float)0x2000;
- } else {
- bend = ((signed int)midiBend - 0x2000) / (float)0x1FFF;
- }
- // Loop through all partials to update their bend
- for (int i = 0; i < MT32EMU_MAX_POLY; i++) {
- for (int j = 0; j < 4; j++) {
- if (polyTable[i].partials[j] != NULL) {
- polyTable[i].partials[j]->setBend(bend);
- }
- }
- }
-}
-
-void RhythmPart::setModulation(unsigned int midiModulation) {
- synth->printDebug("%s: Setting modulation (%d) not supported on rhythm", name, midiModulation);
-}
-
-void Part::setModulation(unsigned int midiModulation) {
- // Just a bloody guess, as always, before I get things figured out
- for (int t = 0; t < 4; t++) {
- if (patchCache[t].playPartial) {
- int newrate = (patchCache[t].modsense * midiModulation) >> 7;
- //patchCache[t].lfoperiod = lfotable[newrate];
- patchCache[t].lfodepth = newrate;
- //FIXME:KG: timbreTemp->partial[t].lfo.depth =
- }
- }
-}
-
-void RhythmPart::refresh() {
- updateVolume();
- // (Re-)cache all the mapped timbres ahead of time
- for (unsigned int drumNum = 0; drumNum < synth->controlROMMap->rhythmSettingsCount; drumNum++) {
- int drumTimbreNum = rhythmTemp[drumNum].timbre;
- if (drumTimbreNum >= 127) // 94 on MT-32
- continue;
- Bit16s pan = rhythmTemp[drumNum].panpot; // They use R-L 0-14...
- // FIXME:KG: Panning cache should be backed up to partials using it, too
- if (pan < 7) {
- drumPan[drumNum].leftvol = pan * 4681;
- drumPan[drumNum].rightvol = 32767;
- } else {
- drumPan[drumNum].rightvol = (14 - pan) * 4681;
- drumPan[drumNum].leftvol = 32767;
- }
- PatchCache *cache = drumCache[drumNum];
- backupCacheToPartials(cache);
- for (int t = 0; t < 4; t++) {
- // Common parameters, stored redundantly
- cache[t].dirty = true;
- cache[t].pitchShift = 0.0f;
- cache[t].benderRange = 0.0f;
- cache[t].pansetptr = &drumPan[drumNum];
- cache[t].reverb = rhythmTemp[drumNum].reverbSwitch > 0;
- }
- }
-}
-
-void Part::refresh() {
- updateVolume();
- backupCacheToPartials(patchCache);
- for (int t = 0; t < 4; t++) {
- // Common parameters, stored redundantly
- patchCache[t].dirty = true;
- patchCache[t].pitchShift = (patchTemp->patch.keyShift - 24) + (patchTemp->patch.fineTune - 50) / 100.0f;
- patchCache[t].benderRange = patchTemp->patch.benderRange;
- patchCache[t].pansetptr = &volumesetting;
- patchCache[t].reverb = patchTemp->patch.reverbSwitch > 0;
- }
- memcpy(currentInstr, timbreTemp->common.name, 10);
-}
-
-const char *Part::getCurrentInstr() const {
- return &currentInstr[0];
-}
-
-void RhythmPart::refreshTimbre(unsigned int absTimbreNum) {
- for (int m = 0; m < 85; m++) {
- if (rhythmTemp[m].timbre == absTimbreNum - 128)
- drumCache[m][0].dirty = true;
- }
-}
-
-void Part::refreshTimbre(unsigned int absTimbreNum) {
- if (getAbsTimbreNum() == absTimbreNum) {
- memcpy(currentInstr, timbreTemp->common.name, 10);
- patchCache[0].dirty = true;
- }
-}
-
-int Part::fixBiaslevel(int srcpnt, int *dir) {
- int noteat = srcpnt & 0x3F;
- int outnote;
- if (srcpnt < 64)
- *dir = 0;
- else
- *dir = 1;
- outnote = 33 + noteat;
- //synth->printDebug("Bias note %d, dir %d", outnote, *dir);
-
- return outnote;
-}
-
-int Part::fixKeyfollow(int srckey) {
- if (srckey>=0 && srckey<=16) {
- int keyfix[17] = { -256*16, -128*16, -64*16, 0, 32*16, 64*16, 96*16, 128*16, (128+32)*16, 192*16, (192+32)*16, 256*16, (256+64)*16, (256+128)*16, (512)*16, 4100, 4116};
- return keyfix[srckey];
- } else {
- //LOG(LOG_ERROR|LOG_MISC,"Missed key: %d", srckey);
- return 256;
- }
-}
-
-void Part::abortPoly(dpoly *poly) {
- if (!poly->isPlaying) {
- return;
- }
- for (int i = 0; i < 4; i++) {
- Partial *partial = poly->partials[i];
- if (partial != NULL) {
- partial->deactivate();
- }
- }
- poly->isPlaying = false;
-}
-
-void Part::setPatch(const PatchParam *patch) {
- patchTemp->patch = *patch;
-}
-
-void RhythmPart::setTimbre(TimbreParam * /*timbre*/) {
- synth->printDebug("%s: Attempted to call setTimbre() - doesn't make sense for rhythm", name);
-}
-
-void Part::setTimbre(TimbreParam *timbre) {
- *timbreTemp = *timbre;
-}
-
-unsigned int RhythmPart::getAbsTimbreNum() const {
- synth->printDebug("%s: Attempted to call getAbsTimbreNum() - doesn't make sense for rhythm", name);
- return 0;
-}
-
-unsigned int Part::getAbsTimbreNum() const {
- return (patchTemp->patch.timbreGroup * 64) + patchTemp->patch.timbreNum;
-}
-
-void RhythmPart::setProgram(unsigned int patchNum) {
- synth->printDebug("%s: Attempt to set program (%d) on rhythm is invalid", name, patchNum);
-}
-
-void Part::setProgram(unsigned int patchNum) {
- setPatch(&synth->mt32ram.patches[patchNum]);
- setTimbre(&synth->mt32ram.timbres[getAbsTimbreNum()].timbre);
-
- refresh();
-
- allSoundOff(); //FIXME:KG: Is this correct?
-}
-
-void Part::backupCacheToPartials(PatchCache cache[4]) {
- // check if any partials are still playing with the old patch cache
- // if so then duplicate the cached data from the part to the partial so that
- // we can change the part's cache without affecting the partial.
- // We delay this until now to avoid a copy operation with every note played
- for (int m = 0; m < MT32EMU_MAX_POLY; m++) {
- for (int i = 0; i < 4; i++) {
- Partial *partial = polyTable[m].partials[i];
- if (partial != NULL && partial->patchCache == &cache[i]) {
- partial->cachebackup = cache[i];
- partial->patchCache = &partial->cachebackup;
- }
- }
- }
-}
-
-void Part::cacheTimbre(PatchCache cache[4], const TimbreParam *timbre) {
- backupCacheToPartials(cache);
- int partialCount = 0;
- for (int t = 0; t < 4; t++) {
- if (((timbre->common.pmute >> t) & 0x1) == 1) {
- cache[t].playPartial = true;
- partialCount++;
- } else {
- cache[t].playPartial = false;
- continue;
- }
-
- // Calculate and cache common parameters
-
- cache[t].pcm = timbre->partial[t].wg.pcmwave;
- cache[t].useBender = (timbre->partial[t].wg.bender == 1);
-
- switch (t) {
- case 0:
- cache[t].PCMPartial = (PartialStruct[(int)timbre->common.pstruct12] & 0x2) ? true : false;
- cache[t].structureMix = PartialMixStruct[(int)timbre->common.pstruct12];
- cache[t].structurePosition = 0;
- cache[t].structurePair = 1;
- break;
- case 1:
- cache[t].PCMPartial = (PartialStruct[(int)timbre->common.pstruct12] & 0x1) ? true : false;
- cache[t].structureMix = PartialMixStruct[(int)timbre->common.pstruct12];
- cache[t].structurePosition = 1;
- cache[t].structurePair = 0;
- break;
- case 2:
- cache[t].PCMPartial = (PartialStruct[(int)timbre->common.pstruct34] & 0x2) ? true : false;
- cache[t].structureMix = PartialMixStruct[(int)timbre->common.pstruct34];
- cache[t].structurePosition = 0;
- cache[t].structurePair = 3;
- break;
- case 3:
- cache[t].PCMPartial = (PartialStruct[(int)timbre->common.pstruct34] & 0x1) ? true : false;
- cache[t].structureMix = PartialMixStruct[(int)timbre->common.pstruct34];
- cache[t].structurePosition = 1;
- cache[t].structurePair = 2;
- break;
- default:
- break;
- }
-
- cache[t].waveform = timbre->partial[t].wg.waveform;
- cache[t].pulsewidth = timbre->partial[t].wg.pulsewid;
- cache[t].pwsens = timbre->partial[t].wg.pwvelo;
- if (timbre->partial[t].wg.keyfollow > 16) {
- synth->printDebug("Bad keyfollow value in timbre!");
- cache[t].pitchKeyfollow = 1.0f;
- } else {
- cache[t].pitchKeyfollow = floatKeyfollow[timbre->partial[t].wg.keyfollow];
- }
-
- cache[t].pitch = timbre->partial[t].wg.coarse + (timbre->partial[t].wg.fine - 50) / 100.0f + 24.0f;
- cache[t].pitchEnv = timbre->partial[t].env;
- cache[t].pitchEnv.sensitivity = (char)((float)cache[t].pitchEnv.sensitivity * 1.27f);
- cache[t].pitchsustain = cache[t].pitchEnv.level[3];
-
- // Calculate and cache TVA envelope stuff
- cache[t].ampEnv = timbre->partial[t].tva;
- cache[t].ampEnv.level = (char)((float)cache[t].ampEnv.level * 1.27f);
-
- cache[t].ampbias[0] = fixBiaslevel(cache[t].ampEnv.biaspoint1, &cache[t].ampdir[0]);
- cache[t].ampblevel[0] = 12 - cache[t].ampEnv.biaslevel1;
- cache[t].ampbias[1] = fixBiaslevel(cache[t].ampEnv.biaspoint2, &cache[t].ampdir[1]);
- cache[t].ampblevel[1] = 12 - cache[t].ampEnv.biaslevel2;
- cache[t].ampdepth = cache[t].ampEnv.envvkf * cache[t].ampEnv.envvkf;
-
- // Calculate and cache filter stuff
- cache[t].filtEnv = timbre->partial[t].tvf;
- cache[t].filtkeyfollow = fixKeyfollow(cache[t].filtEnv.keyfollow);
- cache[t].filtEnv.envdepth = (char)((float)cache[t].filtEnv.envdepth * 1.27);
- cache[t].tvfbias = fixBiaslevel(cache[t].filtEnv.biaspoint, &cache[t].tvfdir);
- cache[t].tvfblevel = cache[t].filtEnv.biaslevel;
- cache[t].filtsustain = cache[t].filtEnv.envlevel[3];
-
- // Calculate and cache LFO stuff
- cache[t].lfodepth = timbre->partial[t].lfo.depth;
- cache[t].lfoperiod = synth->tables.lfoPeriod[(int)timbre->partial[t].lfo.rate];
- cache[t].lforate = timbre->partial[t].lfo.rate;
- cache[t].modsense = timbre->partial[t].lfo.modsense;
- }
- for (int t = 0; t < 4; t++) {
- // Common parameters, stored redundantly
- cache[t].dirty = false;
- cache[t].partialCount = partialCount;
- cache[t].sustain = (timbre->common.nosustain == 0);
- }
- //synth->printDebug("Res 1: %d 2: %d 3: %d 4: %d", cache[0].waveform, cache[1].waveform, cache[2].waveform, cache[3].waveform);
-
-#if MT32EMU_MONITOR_INSTRUMENTS == 1
- synth->printDebug("%s (%s): Recached timbre", name, currentInstr);
- for (int i = 0; i < 4; i++) {
- synth->printDebug(" %d: play=%s, pcm=%s (%d), wave=%d", i, cache[i].playPartial ? "YES" : "NO", cache[i].PCMPartial ? "YES" : "NO", timbre->partial[i].wg.pcmwave, timbre->partial[i].wg.waveform);
- }
-#endif
-}
-
-const char *Part::getName() const {
- return name;
-}
-
-void Part::updateVolume() {
- volumeMult = synth->tables.volumeMult[patchTemp->outlevel * expression / 127];
-}
-
-int Part::getVolume() const {
- // FIXME: Use the mappings for this in the control ROM
- return patchTemp->outlevel * 127 / 100;
-}
-
-void Part::setVolume(int midiVolume) {
- // FIXME: Use the mappings for this in the control ROM
- patchTemp->outlevel = (Bit8u)(midiVolume * 100 / 127);
- updateVolume();
- synth->printDebug("%s (%s): Set volume to %d", name, currentInstr, midiVolume);
-}
-
-void Part::setExpression(int midiExpression) {
- expression = midiExpression;
- updateVolume();
-}
-
-void RhythmPart::setPan(unsigned int midiPan)
-{
- // FIXME:KG: This is unchangeable for drums (they always use drumPan), is that correct?
- synth->printDebug("%s: Setting pan (%d) not supported on rhythm", name, midiPan);
-}
-
-void Part::setPan(unsigned int midiPan) {
- // FIXME:KG: Tweaked this a bit so that we have a left 100%, centre and right 100%
- // (But this makes the range somewhat skewed)
- // Check against the real thing
- // NOTE: Panning is inverted compared to GM.
- if (midiPan < 64) {
- volumesetting.leftvol = (Bit16s)(midiPan * 512);
- volumesetting.rightvol = 32767;
- } else if (midiPan == 64) {
- volumesetting.leftvol = 32767;
- volumesetting.rightvol = 32767;
- } else {
- volumesetting.rightvol = (Bit16s)((127 - midiPan) * 520);
- volumesetting.leftvol = 32767;
- }
- patchTemp->panpot = (Bit8u)(midiPan * 14 / 127);
- //synth->printDebug("%s (%s): Set pan to %d", name, currentInstr, panpot);
-}
-
-void RhythmPart::playNote(unsigned int key, int vel) {
- if (key < 24 || key > 108)/*> 87 on MT-32)*/ {
- synth->printDebug("%s: Attempted to play invalid key %d", name, key);
- return;
- }
- int drumNum = key - 24;
- int drumTimbreNum = rhythmTemp[drumNum].timbre;
- if (drumTimbreNum >= 127) { // 94 on MT-32
- synth->printDebug("%s: Attempted to play unmapped key %d", name, key);
- return;
- }
- int absTimbreNum = drumTimbreNum + 128;
- TimbreParam *timbre = &synth->mt32ram.timbres[absTimbreNum].timbre;
- memcpy(currentInstr, timbre->common.name, 10);
-#if MT32EMU_MONITOR_INSTRUMENTS == 1
- synth->printDebug("%s (%s): starting poly (drum %d, timbre %d) - Vel %d Key %d", name, currentInstr, drumNum, absTimbreNum, vel, key);
-#endif
- if (drumCache[drumNum][0].dirty) {
- cacheTimbre(drumCache[drumNum], timbre);
- }
- playPoly(drumCache[drumNum], key, MIDDLEC, vel);
-}
-
-void Part::playNote(unsigned int key, int vel) {
- int freqNum = key;
- if (freqNum < 12) {
- synth->printDebug("%s (%s): Attempted to play invalid key %d < 12; moving up by octave", name, currentInstr, key);
- freqNum += 12;
- } else if (freqNum > 108) {
- synth->printDebug("%s (%s): Attempted to play invalid key %d > 108; moving down by octave", name, currentInstr, key);
- while (freqNum > 108) {
- freqNum -= 12;
- }
- }
- // POLY1 mode, Single Assign
- // Haven't found any software that uses any of the other poly modes
- // FIXME:KG: Should this also apply to rhythm?
- for (unsigned int i = 0; i < MT32EMU_MAX_POLY; i++) {
- if (polyTable[i].isActive() && (polyTable[i].key == key)) {
- //AbortPoly(&polyTable[i]);
- stopNote(key);
- break;
- }
- }
-#if MT32EMU_MONITOR_INSTRUMENTS == 1
- synth->printDebug("%s (%s): starting poly - Vel %d Key %d", name, currentInstr, vel, key);
-#endif
- if (patchCache[0].dirty) {
- cacheTimbre(patchCache, timbreTemp);
- }
- playPoly(patchCache, key, freqNum, vel);
-}
-
-void Part::playPoly(const PatchCache cache[4], unsigned int key, int freqNum, int vel) {
- unsigned int needPartials = cache[0].partialCount;
- unsigned int freePartials = synth->partialManager->getFreePartialCount();
-
- if (freePartials < needPartials) {
- if (!synth->partialManager->freePartials(needPartials - freePartials, partNum)) {
- synth->printDebug("%s (%s): Insufficient free partials to play key %d (vel=%d); needed=%d, free=%d", name, currentInstr, key, vel, needPartials, synth->partialManager->getFreePartialCount());
- return;
- }
- }
- // Find free poly
- int m;
- for (m = 0; m < MT32EMU_MAX_POLY; m++) {
- if (!polyTable[m].isActive()) {
- break;
- }
- }
- if (m == MT32EMU_MAX_POLY) {
- synth->printDebug("%s (%s): No free poly to play key %d (vel %d)", name, currentInstr, key, vel);
- return;
- }
-
- dpoly *tpoly = &polyTable[m];
-
- tpoly->isPlaying = true;
- tpoly->key = key;
- tpoly->isDecay = false;
- tpoly->freqnum = freqNum;
- tpoly->vel = vel;
- tpoly->pedalhold = false;
-
- bool allnull = true;
- for (int x = 0; x < 4; x++) {
- if (cache[x].playPartial) {
- tpoly->partials[x] = synth->partialManager->allocPartial(partNum);
- allnull = false;
- } else {
- tpoly->partials[x] = NULL;
- }
- }
-
- if (allnull)
- synth->printDebug("%s (%s): No partials to play for this instrument", name, this->currentInstr);
-
- tpoly->sustain = cache[0].sustain;
- tpoly->volumeptr = &volumeMult;
-
- for (int x = 0; x < 4; x++) {
- if (tpoly->partials[x] != NULL) {
- tpoly->partials[x]->startPartial(tpoly, &cache[x], tpoly->partials[cache[x].structurePair]);
- tpoly->partials[x]->setBend(bend);
- }
- }
-}
-
-static void startDecayPoly(dpoly *tpoly) {
- if (tpoly->isDecay) {
- return;
- }
- tpoly->isDecay = true;
-
- for (int t = 0; t < 4; t++) {
- Partial *partial = tpoly->partials[t];
- if (partial == NULL)
- continue;
- partial->startDecayAll();
- }
- tpoly->isPlaying = false;
-}
-
-void Part::allNotesOff() {
- // Note: Unchecked on real MT-32, but the MIDI specification states that all notes off (0x7B)
- // should treat the hold pedal as usual.
- // All *sound* off (0x78) should stop notes immediately regardless of the hold pedal.
- // The latter controller is not implemented on the MT-32 (according to the docs).
- for (int q = 0; q < MT32EMU_MAX_POLY; q++) {
- dpoly *tpoly = &polyTable[q];
- if (tpoly->isPlaying) {
- if (holdpedal)
- tpoly->pedalhold = true;
- else if (tpoly->sustain)
- startDecayPoly(tpoly);
- }
- }
-}
-
-void Part::allSoundOff() {
- for (int q = 0; q < MT32EMU_MAX_POLY; q++) {
- dpoly *tpoly = &polyTable[q];
- if (tpoly->isPlaying) {
- startDecayPoly(tpoly);
- }
- }
-}
-
-void Part::stopPedalHold() {
- for (int q = 0; q < MT32EMU_MAX_POLY; q++) {
- dpoly *tpoly;
- tpoly = &polyTable[q];
- if (tpoly->isActive() && tpoly->pedalhold)
- stopNote(tpoly->key);
- }
-}
-
-void Part::stopNote(unsigned int key) {
- // Non-sustaining instruments ignore stop commands.
- // They die away eventually anyway
-
-#if MT32EMU_MONITOR_INSTRUMENTS == 1
- synth->printDebug("%s (%s): stopping key %d", name, currentInstr, key);
-#endif
-
- if (key != 255) {
- for (int q = 0; q < MT32EMU_MAX_POLY; q++) {
- dpoly *tpoly = &polyTable[q];
- if (tpoly->isPlaying && tpoly->key == key) {
- if (holdpedal)
- tpoly->pedalhold = true;
- else if (tpoly->sustain)
- startDecayPoly(tpoly);
- }
- }
- return;
- }
-
- // Find oldest poly... yes, the MT-32 can be reconfigured to kill different poly first
- // This is simplest
- int oldest = -1;
- Bit32u oldage = 0;
-
- for (int q = 0; q < MT32EMU_MAX_POLY; q++) {
- dpoly *tpoly = &polyTable[q];
-
- if (tpoly->isPlaying && !tpoly->isDecay) {
- if (tpoly->getAge() >= oldage) {
- oldage = tpoly->getAge();
- oldest = q;
- }
- }
- }
-
- if (oldest != -1) {
- startDecayPoly(&polyTable[oldest]);
- }
-}
-
-}
diff --git a/engines/sci/sfx/softseq/mt32/part.h b/engines/sci/sfx/softseq/mt32/part.h
deleted file mode 100644
index 54c4999653..0000000000
--- a/engines/sci/sfx/softseq/mt32/part.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef MT32EMU_PART_H
-#define MT32EMU_PART_H
-
-namespace MT32Emu {
-
-class PartialManager;
-class Synth;
-
-class Part {
-private:
- // Pointers to the areas of the MT-32's memory dedicated to this part (for parts 1-8)
- MemParams::PatchTemp *patchTemp;
- TimbreParam *timbreTemp;
-
- // 0=Part 1, .. 7=Part 8, 8=Rhythm
- unsigned int partNum;
-
- bool holdpedal;
-
- StereoVolume volumesetting;
-
- PatchCache patchCache[4];
-
- float bend; // -1.0 .. +1.0
-
- dpoly polyTable[MT32EMU_MAX_POLY];
-
- void abortPoly(dpoly *poly);
-
- static int fixKeyfollow(int srckey);
- static int fixBiaslevel(int srcpnt, int *dir);
-
- void setPatch(const PatchParam *patch);
-
-protected:
- Synth *synth;
- char name[8]; // "Part 1".."Part 8", "Rhythm"
- char currentInstr[11];
- int expression;
- Bit32u volumeMult;
-
- void updateVolume();
- void backupCacheToPartials(PatchCache cache[4]);
- void cacheTimbre(PatchCache cache[4], const TimbreParam *timbre);
- void playPoly(const PatchCache cache[4], unsigned int key, int freqNum, int vel);
- const char *getName() const;
-
-public:
- Part(Synth *synth, unsigned int usePartNum);
- virtual ~Part() {}
- virtual void playNote(unsigned int key, int vel);
- void stopNote(unsigned int key);
- void allNotesOff();
- void allSoundOff();
- int getVolume() const;
- void setVolume(int midiVolume);
- void setExpression(int midiExpression);
- virtual void setPan(unsigned int midiPan);
- virtual void setBend(unsigned int midiBend);
- virtual void setModulation(unsigned int midiModulation);
- virtual void setProgram(unsigned int midiProgram);
- void setHoldPedal(bool pedalval);
- void stopPedalHold();
- virtual void refresh();
- virtual void refreshTimbre(unsigned int absTimbreNum);
- virtual void setTimbre(TimbreParam *timbre);
- virtual unsigned int getAbsTimbreNum() const;
- const char *getCurrentInstr() const;
-};
-
-class RhythmPart: public Part {
- // Pointer to the area of the MT-32's memory dedicated to rhythm
- const MemParams::RhythmTemp *rhythmTemp;
-
- // This caches the timbres/settings in use by the rhythm part
- PatchCache drumCache[85][4];
- StereoVolume drumPan[85];
-public:
- RhythmPart(Synth *synth, unsigned int usePartNum);
- void refresh();
- void refreshTimbre(unsigned int timbreNum);
- void setTimbre(TimbreParam *timbre);
- void playNote(unsigned int key, int vel);
- unsigned int getAbsTimbreNum() const;
- void setPan(unsigned int midiPan);
- void setBend(unsigned int midiBend);
- void setModulation(unsigned int midiModulation);
- void setProgram(unsigned int patchNum);
-};
-
-}
-#endif
diff --git a/engines/sci/sfx/softseq/mt32/partial.cpp b/engines/sci/sfx/softseq/mt32/partial.cpp
deleted file mode 100644
index 9d32282a82..0000000000
--- a/engines/sci/sfx/softseq/mt32/partial.cpp
+++ /dev/null
@@ -1,960 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-
-#include "mt32emu.h"
-
-#ifdef MACOSX
-// Older versions of Mac OS X didn't supply a powf function. To ensure
-// binary compatibility, we force using pow instead of powf (the only
-// potential drawback is that it might be a little bit slower).
-#define powf pow
-#endif
-
-#define FIXEDPOINT_UDIV(x, y, point) (((x) << (point)) / ((y)))
-#define FIXEDPOINT_SDIV(x, y, point) (((x) * (1 << point)) / ((y)))
-#define FIXEDPOINT_UMULT(x, y, point) (((x) * (y)) >> point)
-#define FIXEDPOINT_SMULT(x, y, point) (((x) * (y)) / (1 << point))
-
-using namespace MT32Emu;
-
-Partial::Partial(Synth *useSynth) {
- this->synth = useSynth;
- ownerPart = -1;
- poly = NULL;
- pair = NULL;
-#if MT32EMU_ACCURATENOTES == 1
- for (int i = 0; i < 3; i++) {
- noteLookupStorage.waveforms[i] = new Bit16s[65536];
- }
- noteLookup = &noteLookupStorage;
-#endif
-}
-
-Partial::~Partial() {
-#if MT32EMU_ACCURATENOTES == 1
- for (int i = 0; i < 3; i++) {
- delete[] noteLookupStorage.waveforms[i];
- }
- delete[] noteLookupStorage.wavTable;
-#endif
-}
-
-int Partial::getOwnerPart() const {
- return ownerPart;
-}
-
-bool Partial::isActive() {
- return ownerPart > -1;
-}
-
-const dpoly *Partial::getDpoly() const {
- return this->poly;
-}
-
-void Partial::activate(int part) {
- // This just marks the partial as being assigned to a part
- ownerPart = part;
-}
-
-void Partial::deactivate() {
- ownerPart = -1;
- if (poly != NULL) {
- for (int i = 0; i < 4; i++) {
- if (poly->partials[i] == this) {
- poly->partials[i] = NULL;
- break;
- }
- }
- if (pair != NULL) {
- pair->pair = NULL;
- }
- }
-}
-
-void Partial::initKeyFollow(int key) {
- // Setup partial keyfollow
- // Note follow relative to middle C
-
- // Calculate keyfollow for pitch
-#if 1
- float rel = key == -1 ? 0.0f : (key - MIDDLEC);
- float newPitch = rel * patchCache->pitchKeyfollow + patchCache->pitch + patchCache->pitchShift;
- //FIXME:KG: Does it truncate the keyfollowed pitch to a semitone (towards MIDDLEC)?
- //int newKey = (int)(rel * patchCache->pitchKeyfollow);
- //float newPitch = newKey + patchCache->pitch + patchCache->pitchShift;
-#else
- float rel = key == -1 ? 0.0f : (key + patchCache->pitchShift - MIDDLEC);
- float newPitch = rel * patchCache->pitchKeyfollow + patchCache->pitch;
-#endif
-#if MT32EMU_ACCURATENOTES == 1
- noteVal = newPitch;
- synth->printDebug("key=%d, pitch=%f, pitchKeyfollow=%f, pitchShift=%f, newPitch=%f", key, patchCache->pitch, patchCache->pitchKeyfollow, patchCache->pitchShift, newPitch);
-#else
- float newPitchInt;
- float newPitchFract = modff(newPitch, &newPitchInt);
- if (newPitchFract > 0.5f) {
- newPitchInt += 1.0f;
- newPitchFract -= 1.0f;
- }
- noteVal = (int)newPitchInt;
- fineShift = (int)(powf(2.0f, newPitchFract / 12.0f) * 4096.0f);
- synth->printDebug("key=%d, pitch=%f, pitchKeyfollow=%f, pitchShift=%f, newPitch=%f, noteVal=%d, fineShift=%d", key, patchCache->pitch, patchCache->pitchKeyfollow, patchCache->pitchShift, newPitch, noteVal, fineShift);
-#endif
- // FIXME:KG: Raise/lower by octaves until in the supported range.
- while (noteVal > HIGHEST_NOTE) // FIXME:KG: see tables.cpp: >108?
- noteVal -= 12;
- while (noteVal < LOWEST_NOTE) // FIXME:KG: see tables.cpp: <12?
- noteVal += 12;
- // Calculate keyfollow for filter
- int keyfollow = ((key - MIDDLEC) * patchCache->filtkeyfollow) / 4096;
- if (keyfollow > 108)
- keyfollow = 108;
- else if (keyfollow < -108)
- keyfollow = -108;
- filtVal = synth->tables.tvfKeyfollowMult[keyfollow + 108];
- realVal = synth->tables.tvfKeyfollowMult[(noteVal - MIDDLEC) + 108];
-}
-
-int Partial::getKey() const {
- if (poly == NULL) {
- return -1;
- } else {
- return poly->key;
- }
-}
-
-void Partial::startPartial(dpoly *usePoly, const PatchCache *useCache, Partial *pairPartial) {
- if (usePoly == NULL || useCache == NULL) {
- synth->printDebug("*** Error: Starting partial for owner %d, usePoly=%s, useCache=%s", ownerPart, usePoly == NULL ? "*** NULL ***" : "OK", useCache == NULL ? "*** NULL ***" : "OK");
- return;
- }
- patchCache = useCache;
- poly = usePoly;
- mixType = patchCache->structureMix;
- structurePosition = patchCache->structurePosition;
-
- play = true;
- initKeyFollow(poly->freqnum); // Initialises noteVal, filtVal and realVal
-#if MT32EMU_ACCURATENOTES == 0
- noteLookup = &synth->tables.noteLookups[noteVal - LOWEST_NOTE];
-#else
- Tables::initNote(synth, &noteLookupStorage, noteVal, (float)synth->myProp.sampleRate, synth->masterTune, synth->pcmWaves, NULL);
-#endif
- keyLookup = &synth->tables.keyLookups[poly->freqnum - 12];
-
- if (patchCache->PCMPartial) {
- pcmNum = patchCache->pcm;
- if (synth->controlROMMap->pcmCount > 128) {
- // CM-32L, etc. support two "banks" of PCMs, selectable by waveform type parameter.
- if (patchCache->waveform > 1) {
- pcmNum += 128;
- }
- }
- pcmWave = &synth->pcmWaves[pcmNum];
- } else {
- pcmWave = NULL;
- }
-
- lfoPos = 0;
- pulsewidth = patchCache->pulsewidth + synth->tables.pwVelfollowAdd[patchCache->pwsens][poly->vel];
- if (pulsewidth > 100) {
- pulsewidth = 100;
- } else if (pulsewidth < 0) {
- pulsewidth = 0;
- }
-
- for (int e = 0; e < 3; e++) {
- envs[e].envpos = 0;
- envs[e].envstat = -1;
- envs[e].envbase = 0;
- envs[e].envdist = 0;
- envs[e].envsize = 0;
- envs[e].sustaining = false;
- envs[e].decaying = false;
- envs[e].prevlevel = 0;
- envs[e].counter = 0;
- envs[e].count = 0;
- }
- ampEnvVal = 0;
- pitchEnvVal = 0;
- pitchSustain = false;
- loopPos = 0;
- partialOff.pcmoffset = partialOff.pcmplace = 0;
- pair = pairPartial;
- useNoisePair = pairPartial == NULL && (mixType == 1 || mixType == 2);
- age = 0;
- alreadyOutputed = false;
- memset(history,0,sizeof(history));
-}
-
-Bit16s *Partial::generateSamples(long length) {
- if (!isActive() || alreadyOutputed) {
- return NULL;
- }
- if (poly == NULL) {
- synth->printDebug("*** ERROR: poly is NULL at Partial::generateSamples()!");
- return NULL;
- }
-
- alreadyOutputed = true;
-
- // Generate samples
-
- Bit16s *partialBuf = &myBuffer[0];
- Bit32u volume = *poly->volumeptr;
- while (length--) {
- Bit32s envval;
- Bit32s sample = 0;
- if (!envs[EnvelopeType_amp].sustaining) {
- if (envs[EnvelopeType_amp].count <= 0) {
- Bit32u ampval = getAmpEnvelope();
- if (!play) {
- deactivate();
- break;
- }
- if (ampval > 100) {
- ampval = 100;
- }
-
- ampval = synth->tables.volumeMult[ampval];
- ampval = FIXEDPOINT_UMULT(ampval, synth->tables.tvaVelfollowMult[poly->vel][(int)patchCache->ampEnv.velosens], 8);
- //if (envs[EnvelopeType_amp].sustaining)
- ampEnvVal = ampval;
- }
- --envs[EnvelopeType_amp].count;
- }
-
- unsigned int lfoShift = 0x1000;
- if (pitchSustain) {
- // Calculate LFO position
- // LFO does not kick in completely until pitch envelope sustains
- if (patchCache->lfodepth > 0) {
- lfoPos++;
- if (lfoPos >= patchCache->lfoperiod)
- lfoPos = 0;
- int lfoatm = FIXEDPOINT_UDIV(lfoPos, patchCache->lfoperiod, 16);
- int lfoatr = synth->tables.sintable[lfoatm];
- lfoShift = synth->tables.lfoShift[patchCache->lfodepth][lfoatr];
- }
- } else {
- // Calculate Pitch envelope
- envval = getPitchEnvelope();
- int pd = patchCache->pitchEnv.depth;
- pitchEnvVal = synth->tables.pitchEnvVal[pd][envval];
- }
-
- int delta;
-
- // Wrap positions or end if necessary
- if (patchCache->PCMPartial) {
- // PCM partial
-
- delta = noteLookup->wavTable[pcmNum];
- int len = pcmWave->len;
- if (partialOff.pcmplace >= len) {
- if (pcmWave->loop) {
- //partialOff.pcmplace = partialOff.pcmoffset = 0;
- partialOff.pcmplace %= len;
- } else {
- play = false;
- deactivate();
- break;
- }
- }
- } else {
- // Synthesis partial
- delta = 0x10000;
- partialOff.pcmplace %= (Bit16u)noteLookup->div2;
- }
-
- // Build delta for position of next sample
- // Fix delta code
- Bit32u tdelta = delta;
-#if MT32EMU_ACCURATENOTES == 0
- tdelta = FIXEDPOINT_UMULT(tdelta, fineShift, 12);
-#endif
- tdelta = FIXEDPOINT_UMULT(tdelta, pitchEnvVal, 12);
- tdelta = FIXEDPOINT_UMULT(tdelta, lfoShift, 12);
- tdelta = FIXEDPOINT_UMULT(tdelta, bendShift, 12);
- delta = (int)tdelta;
-
- // Get waveform - either PCM or synthesized sawtooth or square
- if (ampEnvVal > 0) {
- if (patchCache->PCMPartial) {
- // Render PCM sample
- int ra, rb, dist;
- Bit32u taddr;
- Bit32u pcmAddr = pcmWave->addr;
- if (delta < 0x10000) {
- // Linear sound interpolation
- taddr = pcmAddr + partialOff.pcmplace;
- ra = synth->pcmROMData[taddr];
- taddr++;
- if (taddr == pcmAddr + pcmWave->len) {
- // Past end of PCM
- if (pcmWave->loop) {
- rb = synth->pcmROMData[pcmAddr];
- } else {
- rb = 0;
- }
- } else {
- rb = synth->pcmROMData[taddr];
- }
- dist = rb - ra;
- sample = (ra + ((dist * (Bit32s)(partialOff.pcmoffset >> 8)) >> 8));
- } else {
- // Sound decimation
- // The right way to do it is to use a lowpass filter on the waveform before selecting
- // a point. This is too slow. The following approximates this as fast as possible
- int idelta = delta >> 16;
- taddr = pcmAddr + partialOff.pcmplace;
- ra = synth->pcmROMData[taddr++];
- for (int ix = 0; ix < idelta - 1; ix++) {
- if (taddr == pcmAddr + pcmWave->len) {
- // Past end of PCM
- if (pcmWave->loop) {
- taddr = pcmAddr;
- } else {
- // Behave as if all subsequent samples were 0
- break;
- }
- }
- ra += synth->pcmROMData[taddr++];
- }
- sample = ra / idelta;
- }
- } else {
- // Render synthesised sample
- int toff = partialOff.pcmplace;
- int minorplace = partialOff.pcmoffset >> 14;
- Bit32s filterInput;
- Bit32s filtval = getFiltEnvelope();
-
- //synth->printDebug("Filtval: %d", filtval);
-
- if ((patchCache->waveform & 1) == 0) {
- // Square waveform. Made by combining two pregenerated bandlimited
- // sawtooth waveforms
- Bit32u ofsA = ((toff << 2) + minorplace) % noteLookup->waveformSize[0];
- int width = FIXEDPOINT_UMULT(noteLookup->div2, synth->tables.pwFactor[pulsewidth], 7);
- Bit32u ofsB = (ofsA + width) % noteLookup->waveformSize[0];
- Bit16s pa = noteLookup->waveforms[0][ofsA];
- Bit16s pb = noteLookup->waveforms[0][ofsB];
- filterInput = pa - pb;
- // Non-bandlimited squarewave
- /*
- ofs = FIXEDPOINT_UMULT(noteLookup->div2, synth->tables.pwFactor[patchCache->pulsewidth], 8);
- if (toff < ofs)
- sample = 1 * WGAMP;
- else
- sample = -1 * WGAMP;
- */
- } else {
- // Sawtooth. Made by combining the full cosine and half cosine according
- // to how it looks on the MT-32. What it really does it takes the
- // square wave and multiplies it by a full cosine
- int waveoff = (toff << 2) + minorplace;
- if (toff < noteLookup->sawTable[pulsewidth])
- filterInput = noteLookup->waveforms[1][waveoff % noteLookup->waveformSize[1]];
- else
- filterInput = noteLookup->waveforms[2][waveoff % noteLookup->waveformSize[2]];
- // This is the correct way
- // Seems slow to me (though bandlimited) -- doesn't seem to
- // sound any better though
- /*
- //int pw = (patchCache->pulsewidth * pulsemod[filtval]) >> 8;
-
- Bit32u ofs = toff % (noteLookup->div2 >> 1);
-
- Bit32u ofs3 = toff + FIXEDPOINT_UMULT(noteLookup->div2, synth->tables.pwFactor[patchCache->pulsewidth], 9);
- ofs3 = ofs3 % (noteLookup->div2 >> 1);
-
- pa = noteLookup->waveforms[0][ofs];
- pb = noteLookup->waveforms[0][ofs3];
- sample = ((pa - pb) * noteLookup->waveforms[2][toff]) / 2;
- */
- }
-
- //Very exact filter
- if (filtval > ((FILTERGRAN * 15) / 16))
- filtval = ((FILTERGRAN * 15) / 16);
- sample = (Bit32s)(floorf((synth->iirFilter)((float)filterInput, &history[0], synth->tables.filtCoeff[filtval][(int)patchCache->filtEnv.resonance])) / synth->tables.resonanceFactor[patchCache->filtEnv.resonance]);
- if (sample < -32768) {
- synth->printDebug("Overdriven amplitude for %d: %d:=%d < -32768", patchCache->waveform, filterInput, sample);
- sample = -32768;
- }
- else if (sample > 32767) {
- synth->printDebug("Overdriven amplitude for %d: %d:=%d > 32767", patchCache->waveform, filterInput, sample);
- sample = 32767;
- }
- }
- }
-
- // Add calculated delta to our waveform offset
- Bit32u absOff = ((partialOff.pcmplace << 16) | partialOff.pcmoffset);
- absOff += delta;
- partialOff.pcmplace = (Bit16u)((absOff & 0xFFFF0000) >> 16);
- partialOff.pcmoffset = (Bit16u)(absOff & 0xFFFF);
-
- // Put volume envelope over generated sample
- sample = FIXEDPOINT_SMULT(sample, ampEnvVal, 9);
- sample = FIXEDPOINT_SMULT(sample, volume, 7);
- envs[EnvelopeType_amp].envpos++;
- envs[EnvelopeType_pitch].envpos++;
- envs[EnvelopeType_filt].envpos++;
-
- *partialBuf++ = (Bit16s)sample;
- }
- // We may have deactivated and broken out of the loop before the end of the buffer,
- // if so then fill the remainder with 0s.
- if (++length > 0)
- memset(partialBuf, 0, length * 2);
- return &myBuffer[0];
-}
-
-void Partial::setBend(float factor) {
- if (!patchCache->useBender || factor == 0.0f) {
- bendShift = 4096;
- return;
- }
- // NOTE:KG: We can't do this smoothly with lookup tables, unless we use several MB.
- // FIXME:KG: Bend should be influenced by pitch key-follow too, according to docs.
- float bendSemitones = factor * patchCache->benderRange; // -24 .. 24
- float mult = powf(2.0f, bendSemitones / 12.0f);
- synth->printDebug("setBend(): factor=%f, benderRange=%f, semitones=%f, mult=%f\n", factor, patchCache->benderRange, bendSemitones, mult);
- bendShift = (int)(mult * 4096.0f);
-}
-
-Bit16s *Partial::mixBuffers(Bit16s * buf1, Bit16s *buf2, int len) {
- if (buf1 == NULL)
- return buf2;
- if (buf2 == NULL)
- return buf1;
-
- Bit16s *outBuf = buf1;
-#if MT32EMU_USE_MMX >= 1
- // KG: This seems to be fine
- int donelen = i386_mixBuffers(buf1, buf2, len);
- len -= donelen;
- buf1 += donelen;
- buf2 += donelen;
-#endif
- while (len--) {
- *buf1 = *buf1 + *buf2;
- buf1++, buf2++;
- }
- return outBuf;
-}
-
-Bit16s *Partial::mixBuffersRingMix(Bit16s * buf1, Bit16s *buf2, int len) {
- if (buf1 == NULL)
- return NULL;
- if (buf2 == NULL) {
- Bit16s *outBuf = buf1;
- while (len--) {
- if (*buf1 < -8192)
- *buf1 = -8192;
- else if (*buf1 > 8192)
- *buf1 = 8192;
- buf1++;
- }
- return outBuf;
- }
-
- Bit16s *outBuf = buf1;
-#if MT32EMU_USE_MMX >= 1
- // KG: This seems to be fine
- int donelen = i386_mixBuffersRingMix(buf1, buf2, len);
- len -= donelen;
- buf1 += donelen;
- buf2 += donelen;
-#endif
- while (len--) {
- float a, b;
- a = ((float)*buf1) / 8192.0f;
- b = ((float)*buf2) / 8192.0f;
- a = (a * b) + a;
- if (a>1.0)
- a = 1.0;
- if (a<-1.0)
- a = -1.0;
- *buf1 = (Bit16s)(a * 8192.0f);
- buf1++;
- buf2++;
- //buf1[i] = (Bit16s)(((Bit32s)buf1[i] * (Bit32s)buf2[i]) >> 10) + buf1[i];
- }
- return outBuf;
-}
-
-Bit16s *Partial::mixBuffersRing(Bit16s * buf1, Bit16s *buf2, int len) {
- if (buf1 == NULL) {
- return NULL;
- }
- if (buf2 == NULL) {
- return NULL;
- }
-
- Bit16s *outBuf = buf1;
-#if MT32EMU_USE_MMX >= 1
- // FIXME:KG: Not really checked as working
- int donelen = i386_mixBuffersRing(buf1, buf2, len);
- len -= donelen;
- buf1 += donelen;
- buf2 += donelen;
-#endif
- while (len--) {
- float a, b;
- a = ((float)*buf1) / 8192.0f;
- b = ((float)*buf2) / 8192.0f;
- a *= b;
- if (a>1.0)
- a = 1.0;
- if (a<-1.0)
- a = -1.0;
- *buf1 = (Bit16s)(a * 8192.0f);
- buf1++;
- buf2++;
- }
- return outBuf;
-}
-
-void Partial::mixBuffersStereo(Bit16s *buf1, Bit16s *buf2, Bit16s *outBuf, int len) {
- if (buf2 == NULL) {
- while (len--) {
- *outBuf++ = *buf1++;
- *outBuf++ = 0;
- }
- } else if (buf1 == NULL) {
- while (len--) {
- *outBuf++ = 0;
- *outBuf++ = *buf2++;
- }
- } else {
- while (len--) {
- *outBuf++ = *buf1++;
- *outBuf++ = *buf2++;
- }
- }
-}
-
-bool Partial::produceOutput(Bit16s *partialBuf, long length) {
- if (!isActive() || alreadyOutputed)
- return false;
- if (poly == NULL) {
- synth->printDebug("*** ERROR: poly is NULL at Partial::produceOutput()!");
- return false;
- }
-
- Bit16s *pairBuf = NULL;
- // Check for dependant partial
- if (pair != NULL) {
- if (!pair->alreadyOutputed) {
- // Note: pair may have become NULL after this
- pairBuf = pair->generateSamples(length);
- }
- } else if (useNoisePair) {
- // Generate noise for pairless ring mix
- pairBuf = synth->tables.noiseBuf;
- }
-
- Bit16s *myBuf = generateSamples(length);
-
- if (myBuf == NULL && pairBuf == NULL)
- return false;
-
- Bit16s *p1buf, *p2buf;
-
- if (structurePosition == 0 || pairBuf == NULL) {
- p1buf = myBuf;
- p2buf = pairBuf;
- } else {
- p2buf = myBuf;
- p1buf = pairBuf;
- }
-
- //synth->printDebug("mixType: %d", mixType);
-
- Bit16s *mixedBuf;
- switch (mixType) {
- case 0:
- // Standard sound mix
- mixedBuf = mixBuffers(p1buf, p2buf, length);
- break;
-
- case 1:
- // Ring modulation with sound mix
- mixedBuf = mixBuffersRingMix(p1buf, p2buf, length);
- break;
-
- case 2:
- // Ring modulation alone
- mixedBuf = mixBuffersRing(p1buf, p2buf, length);
- break;
-
- case 3:
- // Stereo mixing. One partial to one speaker channel, one to another.
- // FIXME:KG: Surely we should be multiplying by the left/right volumes here?
- mixBuffersStereo(p1buf, p2buf, partialBuf, length);
- return true;
-
- default:
- mixedBuf = mixBuffers(p1buf, p2buf, length);
- break;
- }
-
- if (mixedBuf == NULL)
- return false;
-
- Bit16s leftvol, rightvol;
- leftvol = patchCache->pansetptr->leftvol;
- rightvol = patchCache->pansetptr->rightvol;
-
-#if MT32EMU_USE_MMX >= 2
- // FIXME:KG: This appears to introduce crackle
- int donelen = i386_partialProductOutput(length, leftvol, rightvol, partialBuf, mixedBuf);
- length -= donelen;
- mixedBuf += donelen;
- partialBuf += donelen * 2;
-#endif
- while (length--) {
- *partialBuf++ = (Bit16s)(((Bit32s)*mixedBuf * (Bit32s)leftvol) >> 15);
- *partialBuf++ = (Bit16s)(((Bit32s)*mixedBuf * (Bit32s)rightvol) >> 15);
- mixedBuf++;
- }
- return true;
-}
-
-Bit32s Partial::getFiltEnvelope() {
- int reshigh;
-
- int cutoff, depth;
-
- EnvelopeStatus *tStat = &envs[EnvelopeType_filt];
-
- if (tStat->decaying) {
- reshigh = tStat->envbase;
- reshigh = (reshigh + ((tStat->envdist * tStat->envpos) / tStat->envsize));
- if (tStat->envpos >= tStat->envsize)
- reshigh = 0;
- } else {
- if (tStat->envstat==4) {
- reshigh = patchCache->filtsustain;
- if (!poly->sustain) {
- startDecay(EnvelopeType_filt, reshigh);
- }
- } else {
- if ((tStat->envstat==-1) || (tStat->envpos >= tStat->envsize)) {
- if (tStat->envstat==-1)
- tStat->envbase = 0;
- else
- tStat->envbase = patchCache->filtEnv.envlevel[tStat->envstat];
- tStat->envstat++;
- tStat->envpos = 0;
- if (tStat->envstat == 3) {
- tStat->envsize = synth->tables.envTime[(int)patchCache->filtEnv.envtime[tStat->envstat]];
- } else {
- Bit32u envTime = (int)patchCache->filtEnv.envtime[tStat->envstat];
- if (tStat->envstat > 1) {
- int envDiff = abs(patchCache->filtEnv.envlevel[tStat->envstat] - patchCache->filtEnv.envlevel[tStat->envstat - 1]);
- if (envTime > synth->tables.envDeltaMaxTime[envDiff]) {
- envTime = synth->tables.envDeltaMaxTime[envDiff];
- }
- }
-
- tStat->envsize = (synth->tables.envTime[envTime] * keyLookup->envTimeMult[(int)patchCache->filtEnv.envtkf]) >> 8;
- }
-
- tStat->envsize++;
- tStat->envdist = patchCache->filtEnv.envlevel[tStat->envstat] - tStat->envbase;
- }
-
- reshigh = tStat->envbase;
- reshigh = (reshigh + ((tStat->envdist * tStat->envpos) / tStat->envsize));
-
- }
- tStat->prevlevel = reshigh;
- }
-
- cutoff = patchCache->filtEnv.cutoff;
-
- //if (patchCache->waveform==1) reshigh = (reshigh * 3) >> 2;
-
- depth = patchCache->filtEnv.envdepth;
-
- //int sensedep = (depth * 127-patchCache->filtEnv.envsense) >> 7;
- depth = FIXEDPOINT_UMULT(depth, synth->tables.tvfVelfollowMult[poly->vel][(int)patchCache->filtEnv.envsense], 8);
-
- int bias = patchCache->tvfbias;
- int dist;
-
- if (bias != 0) {
- //FIXME:KG: Is this really based on pitch (as now), or key pressed?
- //synth->printDebug("Cutoff before %d", cutoff);
- if (patchCache->tvfdir == 0) {
- if (noteVal < bias) {
- dist = bias - noteVal;
- cutoff = FIXEDPOINT_UMULT(cutoff, synth->tables.tvfBiasMult[patchCache->tvfblevel][dist], 8);
- }
- } else {
- // > Bias
- if (noteVal > bias) {
- dist = noteVal - bias;
- cutoff = FIXEDPOINT_UMULT(cutoff, synth->tables.tvfBiasMult[patchCache->tvfblevel][dist], 8);
- }
-
- }
- //synth->printDebug("Cutoff after %d", cutoff);
- }
-
- depth = (depth * keyLookup->envDepthMult[patchCache->filtEnv.envdkf]) >> 8;
- reshigh = (reshigh * depth) >> 7;
-
- Bit32s tmp;
-
- cutoff *= filtVal;
- cutoff /= realVal; //FIXME:KG: With filter keyfollow 0, this makes no sense. What's correct?
-
- reshigh *= filtVal;
- reshigh /= realVal; //FIXME:KG: As above for cutoff
-
- if (patchCache->waveform == 1) {
- reshigh = (reshigh * 65) / 100;
- }
-
- if (cutoff > 100)
- cutoff = 100;
- else if (cutoff < 0)
- cutoff = 0;
- if (reshigh > 100)
- reshigh = 100;
- else if (reshigh < 0)
- reshigh = 0;
- tmp = noteLookup->nfiltTable[cutoff][reshigh];
- //tmp *= keyfollow;
- //tmp /= realfollow;
-
- //synth->printDebug("Cutoff %d, tmp %d, freq %d", cutoff, tmp, tmp * 256);
- return tmp;
-}
-
-bool Partial::shouldReverb() {
- if (!isActive())
- return false;
- return patchCache->reverb;
-}
-
-Bit32u Partial::getAmpEnvelope() {
- Bit32s tc;
-
- EnvelopeStatus *tStat = &envs[EnvelopeType_amp];
-
- if (!play)
- return 0;
-
- if (tStat->decaying) {
- tc = tStat->envbase;
- tc += (tStat->envdist * tStat->envpos) / tStat->envsize;
- if (tc < 0)
- tc = 0;
- if ((tStat->envpos >= tStat->envsize) || (tc == 0)) {
- play = false;
- // Don't have to worry about prevlevel storage or anything, this partial's about to die
- return 0;
- }
- } else {
- if ((tStat->envstat == -1) || (tStat->envpos >= tStat->envsize)) {
- if (tStat->envstat == -1)
- tStat->envbase = 0;
- else
- tStat->envbase = patchCache->ampEnv.envlevel[tStat->envstat];
- tStat->envstat++;
- tStat->envpos = 0;
- if (tStat->envstat == 4) {
- //synth->printDebug("Envstat %d, size %d", tStat->envstat, tStat->envsize);
- tc = patchCache->ampEnv.envlevel[3];
- if (!poly->sustain)
- startDecay(EnvelopeType_amp, tc);
- else
- tStat->sustaining = true;
- goto PastCalc;
- }
- Bit8u targetLevel = patchCache->ampEnv.envlevel[tStat->envstat];
- tStat->envdist = targetLevel - tStat->envbase;
- Bit32u envTime = patchCache->ampEnv.envtime[tStat->envstat];
- if (targetLevel == 0) {
- tStat->envsize = synth->tables.envDecayTime[envTime];
- } else {
- int envLevelDelta = abs(tStat->envdist);
- if (envTime > synth->tables.envDeltaMaxTime[envLevelDelta]) {
- envTime = synth->tables.envDeltaMaxTime[envLevelDelta];
- }
- tStat->envsize = synth->tables.envTime[envTime];
- }
-
- // Time keyfollow is used by all sections of the envelope (confirmed on CM-32L)
- tStat->envsize = FIXEDPOINT_UMULT(tStat->envsize, keyLookup->envTimeMult[(int)patchCache->ampEnv.envtkf], 8);
-
- switch (tStat->envstat) {
- case 0:
- //Spot for velocity time follow
- //Only used for first attack
- tStat->envsize = FIXEDPOINT_UMULT(tStat->envsize, synth->tables.envTimeVelfollowMult[(int)patchCache->ampEnv.envvkf][poly->vel], 8);
- //synth->printDebug("Envstat %d, size %d", tStat->envstat, tStat->envsize);
- break;
- case 1:
- case 2:
- case 3:
- //synth->printDebug("Envstat %d, size %d", tStat->envstat, tStat->envsize);
- break;
- default:
- synth->printDebug("Invalid TVA envelope number %d hit!", tStat->envstat);
- break;
- }
-
- tStat->envsize++;
-
- if (tStat->envdist != 0) {
- tStat->counter = abs(tStat->envsize / tStat->envdist);
- //synth->printDebug("Pos %d, envsize %d envdist %d", tStat->envstat, tStat->envsize, tStat->envdist);
- } else {
- tStat->counter = 0;
- //synth->printDebug("Pos %d, envsize %d envdist %d", tStat->envstat, tStat->envsize, tStat->envdist);
- }
- }
- tc = tStat->envbase;
- tc = (tc + ((tStat->envdist * tStat->envpos) / tStat->envsize));
- tStat->count = tStat->counter;
-PastCalc:
- tc = (tc * (Bit32s)patchCache->ampEnv.level) / 100;
- }
-
- // Prevlevel storage is bottle neck
- tStat->prevlevel = tc;
-
- //Bias level crap stuff now
-
- for (int i = 0; i < 2; i++) {
- if (patchCache->ampblevel[i]!=0) {
- int bias = patchCache->ampbias[i];
- if (patchCache->ampdir[i]==0) {
- // < Bias
- if (noteVal < bias) {
- int dist = bias - noteVal;
- tc = FIXEDPOINT_UMULT(tc, synth->tables.tvaBiasMult[patchCache->ampblevel[i]][dist], 8);
- }
- } else {
- // > Bias
- if (noteVal > bias) {
- int dist = noteVal - bias;
- tc = FIXEDPOINT_UMULT(tc, synth->tables.tvaBiasMult[patchCache->ampblevel[i]][dist], 8);
- }
- }
- }
- }
- if (tc < 0) {
- synth->printDebug("*** ERROR: tc < 0 (%d) at getAmpEnvelope()", tc);
- tc = 0;
- }
- return (Bit32u)tc;
-}
-
-Bit32s Partial::getPitchEnvelope() {
- EnvelopeStatus *tStat = &envs[EnvelopeType_pitch];
-
- Bit32s tc;
- pitchSustain = false;
- if (tStat->decaying) {
- if (tStat->envpos >= tStat->envsize)
- tc = patchCache->pitchEnv.level[4];
- else {
- tc = tStat->envbase;
- tc = (tc + ((tStat->envdist * tStat->envpos) / tStat->envsize));
- }
- } else {
- if (tStat->envstat==3) {
- tc = patchCache->pitchsustain;
- if (poly->sustain)
- pitchSustain = true;
- else
- startDecay(EnvelopeType_pitch, tc);
- } else {
- if ((tStat->envstat==-1) || (tStat->envpos >= tStat->envsize)) {
- tStat->envstat++;
-
- tStat->envbase = patchCache->pitchEnv.level[tStat->envstat];
-
- Bit32u envTime = patchCache->pitchEnv.time[tStat->envstat];
- int envDiff = abs(patchCache->pitchEnv.level[tStat->envstat] - patchCache->pitchEnv.level[tStat->envstat + 1]);
- if (envTime > synth->tables.envDeltaMaxTime[envDiff]) {
- envTime = synth->tables.envDeltaMaxTime[envDiff];
- }
-
- tStat->envsize = (synth->tables.envTime[envTime] * keyLookup->envTimeMult[(int)patchCache->pitchEnv.timekeyfollow]) >> 8;
-
- tStat->envpos = 0;
- tStat->envsize++;
- tStat->envdist = patchCache->pitchEnv.level[tStat->envstat + 1] - tStat->envbase;
- }
- tc = tStat->envbase;
- tc = (tc + ((tStat->envdist * tStat->envpos) / tStat->envsize));
- }
- tStat->prevlevel = tc;
- }
- return tc;
-}
-
-void Partial::startDecayAll() {
- startDecay(EnvelopeType_amp, envs[EnvelopeType_amp].prevlevel);
- startDecay(EnvelopeType_filt, envs[EnvelopeType_filt].prevlevel);
- startDecay(EnvelopeType_pitch, envs[EnvelopeType_pitch].prevlevel);
- pitchSustain = false;
-}
-
-void Partial::startDecay(EnvelopeType envnum, Bit32s startval) {
- EnvelopeStatus *tStat = &envs[envnum];
-
- tStat->sustaining = false;
- tStat->decaying = true;
- tStat->envpos = 0;
- tStat->envbase = startval;
-
- switch (envnum) {
- case EnvelopeType_amp:
- tStat->envsize = FIXEDPOINT_UMULT(synth->tables.envDecayTime[(int)patchCache->ampEnv.envtime[4]], keyLookup->envTimeMult[(int)patchCache->ampEnv.envtkf], 8);
- tStat->envdist = -startval;
- break;
- case EnvelopeType_filt:
- tStat->envsize = FIXEDPOINT_UMULT(synth->tables.envDecayTime[(int)patchCache->filtEnv.envtime[4]], keyLookup->envTimeMult[(int)patchCache->filtEnv.envtkf], 8);
- tStat->envdist = -startval;
- break;
- case EnvelopeType_pitch:
- tStat->envsize = FIXEDPOINT_UMULT(synth->tables.envDecayTime[(int)patchCache->pitchEnv.time[3]], keyLookup->envTimeMult[(int)patchCache->pitchEnv.timekeyfollow], 8);
- tStat->envdist = patchCache->pitchEnv.level[4] - startval;
- break;
- default:
- break;
- }
- tStat->envsize++;
-}
diff --git a/engines/sci/sfx/softseq/mt32/partial.h b/engines/sci/sfx/softseq/mt32/partial.h
deleted file mode 100644
index 93d8bcd985..0000000000
--- a/engines/sci/sfx/softseq/mt32/partial.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef MT32EMU_PARTIAL_H
-#define MT32EMU_PARTIAL_H
-
-namespace MT32Emu {
-
-class Synth;
-struct NoteLookup;
-
-enum EnvelopeType {
- EnvelopeType_amp = 0,
- EnvelopeType_filt = 1,
- EnvelopeType_pitch = 2
-};
-
-struct EnvelopeStatus {
- Bit32s envpos;
- Bit32s envstat;
- Bit32s envbase;
- Bit32s envdist;
- Bit32s envsize;
-
- bool sustaining;
- bool decaying;
- Bit32s prevlevel;
-
- Bit32s counter;
- Bit32s count;
-};
-
-// Class definition of MT-32 partials. 32 in all.
-class Partial {
-private:
- Synth *synth;
-
- int ownerPart; // -1 if unassigned
- int mixType;
- int structurePosition; // 0 or 1 of a structure pair
- bool useNoisePair;
-
- Bit16s myBuffer[MAX_SAMPLE_OUTPUT];
-
- // Keyfollowed note value
-#if MT32EMU_ACCURATENOTES == 1
- NoteLookup noteLookupStorage;
- float noteVal;
-#else
- int noteVal;
- int fineShift;
-#endif
- const NoteLookup *noteLookup; // LUTs for this noteVal
- const KeyLookup *keyLookup; // LUTs for the clamped (12..108) key
-
- // Keyfollowed filter values
- int realVal;
- int filtVal;
-
- // Only used for PCM partials
- int pcmNum;
- PCMWaveEntry *pcmWave;
-
- int pulsewidth;
-
- Bit32u lfoPos;
- soundaddr partialOff;
-
- Bit32u ampEnvVal;
- Bit32u pitchEnvVal;
-
- float history[32];
-
- bool pitchSustain;
-
- int loopPos;
-
- dpoly *poly;
-
- int bendShift;
-
- Bit16s *mixBuffers(Bit16s *buf1, Bit16s *buf2, int len);
- Bit16s *mixBuffersRingMix(Bit16s *buf1, Bit16s *buf2, int len);
- Bit16s *mixBuffersRing(Bit16s *buf1, Bit16s *buf2, int len);
- void mixBuffersStereo(Bit16s *buf1, Bit16s *buf2, Bit16s *outBuf, int len);
-
- Bit32s getFiltEnvelope();
- Bit32u getAmpEnvelope();
- Bit32s getPitchEnvelope();
-
- void initKeyFollow(int freqNum);
-
-public:
- const PatchCache *patchCache;
- EnvelopeStatus envs[3];
- bool play;
-
- PatchCache cachebackup;
-
- Partial *pair;
- bool alreadyOutputed;
- Bit32u age;
-
- Partial(Synth *synth);
- ~Partial();
-
- int getOwnerPart() const;
- int getKey() const;
- const dpoly *getDpoly() const;
- bool isActive();
- void activate(int part);
- void deactivate(void);
- void startPartial(dpoly *usePoly, const PatchCache *useCache, Partial *pairPartial);
- void startDecay(EnvelopeType envnum, Bit32s startval);
- void startDecayAll();
- void setBend(float factor);
- bool shouldReverb();
-
- // Returns true only if data written to buffer
- // This function (unlike the one below it) returns processed stereo samples
- // made from combining this single partial with its pair, if it has one.
- bool produceOutput(Bit16s * partialBuf, long length);
-
- // This function produces mono sample output using the partial's private internal buffer
- Bit16s *generateSamples(long length);
-};
-
-}
-
-#endif
diff --git a/engines/sci/sfx/softseq/mt32/partialManager.cpp b/engines/sci/sfx/softseq/mt32/partialManager.cpp
deleted file mode 100644
index 3d3b6302db..0000000000
--- a/engines/sci/sfx/softseq/mt32/partialManager.cpp
+++ /dev/null
@@ -1,272 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include <string.h>
-
-#include "mt32emu.h"
-
-using namespace MT32Emu;
-
-PartialManager::PartialManager(Synth *useSynth) {
- this->synth = useSynth;
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++)
- partialTable[i] = new Partial(synth);
-}
-
-PartialManager::~PartialManager(void) {
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++)
- delete partialTable[i];
-}
-
-void PartialManager::getPerPartPartialUsage(int usage[9]) {
- memset(usage, 0, 9 * sizeof (int));
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (partialTable[i]->isActive())
- usage[partialTable[i]->getOwnerPart()]++;
- }
-}
-
-void PartialManager::clearAlreadyOutputed() {
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++)
- partialTable[i]->alreadyOutputed = false;
-}
-
-void PartialManager::ageAll() {
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++)
- partialTable[i]->age++;
-}
-
-bool PartialManager::shouldReverb(int i) {
- return partialTable[i]->shouldReverb();
-}
-
-bool PartialManager::produceOutput(int i, Bit16s *buffer, Bit32u bufferLength) {
- return partialTable[i]->produceOutput(buffer, bufferLength);
-}
-
-void PartialManager::deactivateAll() {
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- partialTable[i]->deactivate();
- }
-}
-
-unsigned int PartialManager::setReserve(Bit8u *rset) {
- unsigned int pr = 0;
- for (int x = 0; x < 9; x++) {
- for (int y = 0; y < rset[x]; y++) {
- partialReserveTable[pr] = x;
- pr++;
- }
- }
- return pr;
-}
-
-Partial *PartialManager::allocPartial(int partNum) {
- Partial *outPartial = NULL;
-
- // Use the first inactive partial reserved for the specified part (if there are any)
- // Otherwise, use the last inactive partial, if any
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (!partialTable[i]->isActive()) {
- outPartial = partialTable[i];
- if (partialReserveTable[i] == partNum)
- break;
- }
- }
- if (outPartial != NULL) {
- outPartial->activate(partNum);
- outPartial->age = 0;
- }
- return outPartial;
-}
-
-unsigned int PartialManager::getFreePartialCount(void) {
- int count = 0;
- memset(partialPart, 0, sizeof(partialPart));
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (!partialTable[i]->isActive())
- count++;
- else
- partialPart[partialTable[i]->getOwnerPart()]++;
- }
- return count;
-}
-
-/*
-bool PartialManager::freePartials(unsigned int needed, int partNum) {
- int i;
- int myPartPrior = (int)mt32ram.system.reserveSettings[partNum];
- if (myPartPrior<partialPart[partNum]) {
- //This can have more parts, must kill off those with less priority
- int most, mostPart;
- while (needed > 0) {
- int selectPart = -1;
- //Find the worst offender with more partials than allocated and kill them
- most = -1;
- mostPart = -1;
- int diff;
-
- for (i=0;i<9;i++) {
- diff = partialPart[i] - (int)mt32ram.system.reserveSettings[i];
-
- if (diff>0) {
- if (diff>most) {
- most = diff;
- mostPart = i;
- }
- }
- }
- selectPart = mostPart;
- if (selectPart == -1) {
- // All parts are within the allocated limits, you suck
- // Look for first partial not of this part that's decaying perhaps?
- return false;
- }
- bool found;
- int oldest;
- int oldnum;
- while (partialPart[selectPart] > (int)mt32ram.system.reserveSettings[selectPart]) {
- oldest = -1;
- oldnum = -1;
- found = false;
- for (i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (partialTable[i]->isActive) {
- if (partialTable[i]->ownerPart == selectPart) {
- found = true;
- if (partialTable[i]->age > oldest) {
- oldest = partialTable[i]->age;
- oldnum = i;
- }
- }
- }
- }
- if (!found) break;
- partialTable[oldnum]->deactivate();
- --partialPart[selectPart];
- --needed;
- }
-
- }
- return true;
-
- } else {
- //This part has reached its max, must kill off its own
- bool found;
- int oldest;
- int oldnum;
- while (needed > 0) {
- oldest = -1;
- oldnum = -1;
- found = false;
- for (i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (partialTable[i]->isActive) {
- if (partialTable[i]->ownerPart == partNum) {
- found = true;
- if (partialTable[i]->age > oldest) {
- oldest = partialTable[i]->age;
- oldnum = i;
- }
- }
- }
- }
- if (!found) break;
- partialTable[oldnum]->deactivate();
- --needed;
- }
- // Couldn't free enough partials, sorry
- if (needed>0) return false;
- return true;
- }
-
-}
-*/
-bool PartialManager::freePartials(unsigned int needed, int partNum) {
- if (needed == 0) {
- return true;
- }
- // Reclaim partials reserved for this part
- // Kill those that are already decaying first
- /*
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (partialReserveTable[i] == partNum) {
- if (partialTable[i]->ownerPart != partNum) {
- if (partialTable[i]->partCache->envs[AMPENV].decaying) {
- partialTable[i]->isActive = false;
- --needed;
- if (needed == 0)
- return true;
- }
- }
- }
- }*/
- // Then kill those with the lowest part priority -- oldest at the moment
- while (needed > 0) {
- Bit32u prior = 0;
- int priornum = -1;
-
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (partialReserveTable[i] == partNum && partialTable[i]->isActive() && partialTable[i]->getOwnerPart() != partNum) {
- /*
- if (mt32ram.system.reserveSettings[partialTable[i]->ownerPart] < prior) {
- prior = mt32ram.system.reserveSettings[partialTable[i]->ownerPart];
- priornum = i;
- }*/
- if (partialTable[i]->age >= prior) {
- prior = partialTable[i]->age;
- priornum = i;
- }
- }
- }
- if (priornum != -1) {
- partialTable[priornum]->deactivate();
- --needed;
- } else {
- break;
- }
- }
-
- // Kill off the oldest partials within this part
- while (needed > 0) {
- Bit32u oldest = 0;
- int oldlist = -1;
- for (int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (partialTable[i]->getOwnerPart() == partNum && partialTable[i]->isActive()) {
- if (partialTable[i]->age >= oldest) {
- oldest = partialTable[i]->age;
- oldlist = i;
- }
- }
- }
- if (oldlist != -1) {
- partialTable[oldlist]->deactivate();
- --needed;
- } else {
- break;
- }
- }
- return needed == 0;
-}
-
-const Partial *PartialManager::getPartial(unsigned int partialNum) const {
- if (partialNum > MT32EMU_MAX_PARTIALS - 1)
- return NULL;
- return partialTable[partialNum];
-}
diff --git a/engines/sci/sfx/softseq/mt32/partialManager.h b/engines/sci/sfx/softseq/mt32/partialManager.h
deleted file mode 100644
index b10f93ff02..0000000000
--- a/engines/sci/sfx/softseq/mt32/partialManager.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef MT32EMU_PARTIALMANAGER_H
-#define MT32EMU_PARTIALMANAGER_H
-
-namespace MT32Emu {
-
-class Synth;
-
-class PartialManager {
-private:
- Synth *synth; // Only used for sending debug output
-
- Partial *partialTable[MT32EMU_MAX_PARTIALS];
- Bit32s partialReserveTable[MT32EMU_MAX_PARTIALS];
- Bit32s partialPart[9]; // The count of partials played per part
-
-public:
-
- PartialManager(Synth *synth);
- ~PartialManager();
- Partial *allocPartial(int partNum);
- unsigned int getFreePartialCount(void);
- bool freePartials(unsigned int needed, int partNum);
- unsigned int setReserve(Bit8u *rset);
- void deactivateAll();
- void ageAll();
- bool produceOutput(int i, Bit16s *buffer, Bit32u bufferLength);
- bool shouldReverb(int i);
- void clearAlreadyOutputed();
- void getPerPartPartialUsage(int usage[9]);
- const Partial *getPartial(unsigned int partialNum) const;
-};
-
-}
-
-#endif
diff --git a/engines/sci/sfx/softseq/mt32/structures.h b/engines/sci/sfx/softseq/mt32/structures.h
deleted file mode 100644
index ef58c1d20f..0000000000
--- a/engines/sci/sfx/softseq/mt32/structures.h
+++ /dev/null
@@ -1,284 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef MT32EMU_STRUCTURES_H
-#define MT32EMU_STRUCTURES_H
-
-namespace MT32Emu {
-
-const unsigned int MAX_SAMPLE_OUTPUT = 4096;
-
-// MT32EMU_MEMADDR() converts from sysex-padded, MT32EMU_SYSEXMEMADDR converts to it
-// Roland provides documentation using the sysex-padded addresses, so we tend to use that in code and output
-#define MT32EMU_MEMADDR(x) ((((x) & 0x7f0000) >> 2) | (((x) & 0x7f00) >> 1) | ((x) & 0x7f))
-#define MT32EMU_SYSEXMEMADDR(x) ((((x) & 0x1FC000) << 2) | (((x) & 0x3F80) << 1) | ((x) & 0x7f))
-
-#ifdef _MSC_VER
-#define MT32EMU_ALIGN_PACKED __declspec(align(1))
-typedef unsigned __int64 Bit64u;
-typedef signed __int64 Bit64s;
-#else
-#define MT32EMU_ALIGN_PACKED __attribute__((packed))
-typedef unsigned long long Bit64u;
-typedef signed long long Bit64s;
-#endif
-
-typedef unsigned int Bit32u;
-typedef signed int Bit32s;
-typedef unsigned short int Bit16u;
-typedef signed short int Bit16s;
-typedef unsigned char Bit8u;
-typedef signed char Bit8s;
-
-// The following structures represent the MT-32's memory
-// Since sysex allows this memory to be written to in blocks of bytes,
-// we keep this packed so that we can copy data into the various
-// banks directly
-#if defined(_MSC_VER) || defined (__MINGW32__)
-#pragma pack(push, 1)
-#else
-#pragma pack(1)
-#endif
-
-struct TimbreParam {
- struct commonParam {
- char name[10];
- Bit8u pstruct12; // 1&2 0-12 (1-13)
- Bit8u pstruct34; // #3&4 0-12 (1-13)
- Bit8u pmute; // 0-15 (0000-1111)
- Bit8u nosustain; // 0-1(Normal, No sustain)
- } MT32EMU_ALIGN_PACKED common;
-
- struct partialParam {
- struct wgParam {
- Bit8u coarse; // 0-96 (C1,C#1-C9)
- Bit8u fine; // 0-100 (-50 to +50 (cents?))
- Bit8u keyfollow; // 0-16 (-1,-1/2,0,1,1/8,1/4,3/8,1/2,5/8,3/4,7/8,1,5/4,3/2,2.s1,s2)
- Bit8u bender; // 0,1 (ON/OFF)
- Bit8u waveform; // MT-32: 0-1 (SQU/SAW); LAPC-I: WG WAVEFORM/PCM BANK 0 - 3 (SQU/1, SAW/1, SQU/2, SAW/2)
- Bit8u pcmwave; // 0-127 (1-128)
- Bit8u pulsewid; // 0-100
- Bit8u pwvelo; // 0-14 (-7 - +7)
- } MT32EMU_ALIGN_PACKED wg;
-
- struct envParam {
- Bit8u depth; // 0-10
- Bit8u sensitivity; // 1-100
- Bit8u timekeyfollow; // 0-4
- Bit8u time[4]; // 1-100
- Bit8u level[5]; // 1-100 (-50 - +50)
- } MT32EMU_ALIGN_PACKED env;
-
- struct lfoParam {
- Bit8u rate; // 0-100
- Bit8u depth; // 0-100
- Bit8u modsense; // 0-100
- } MT32EMU_ALIGN_PACKED lfo;
-
- struct tvfParam {
- Bit8u cutoff; // 0-100
- Bit8u resonance; // 0-30
- Bit8u keyfollow; // 0-16 (-1,-1/2,1/4,0,1,1/8,1/4,3/8,1/2,5/8,3/2,7/8,1,5/4,3/2,2,s1,s2)
- Bit8u biaspoint; // 0-127 (<1A-<7C >1A-7C)
- Bit8u biaslevel; // 0-14 (-7 - +7)
- Bit8u envdepth; // 0-100
- Bit8u envsense; // 0-100
- Bit8u envdkf; // DEPTH KEY FOLL0W 0-4
- Bit8u envtkf; // TIME KEY FOLLOW 0-4
- Bit8u envtime[5]; // 1-100
- Bit8u envlevel[4]; // 1-100
- } MT32EMU_ALIGN_PACKED tvf;
-
- struct tvaParam {
- Bit8u level; // 0-100
- Bit8u velosens; // 0-100
- Bit8u biaspoint1; // 0-127 (<1A-<7C >1A-7C)
- Bit8u biaslevel1; // 0-12 (-12 - 0)
- Bit8u biaspoint2; // 0-127 (<1A-<7C >1A-7C)
- Bit8u biaslevel2; // 0-12 (-12 - 0)
- Bit8u envtkf; // TIME KEY FOLLOW 0-4
- Bit8u envvkf; // VELOS KEY FOLL0W 0-4
- Bit8u envtime[5]; // 1-100
- Bit8u envlevel[4]; // 1-100
- } MT32EMU_ALIGN_PACKED tva;
- } MT32EMU_ALIGN_PACKED partial[4];
-} MT32EMU_ALIGN_PACKED;
-
-struct PatchParam {
- Bit8u timbreGroup; // TIMBRE GROUP 0-3 (group A, group B, Memory, Rhythm)
- Bit8u timbreNum; // TIMBRE NUMBER 0-63
- Bit8u keyShift; // KEY SHIFT 0-48 (-24 - +24 semitones)
- Bit8u fineTune; // FINE TUNE 0-100 (-50 - +50 cents)
- Bit8u benderRange; // BENDER RANGE 0-24
- Bit8u assignMode; // ASSIGN MODE 0-3 (POLY1, POLY2, POLY3, POLY4)
- Bit8u reverbSwitch; // REVERB SWITCH 0-1 (OFF,ON)
- Bit8u dummy; // (DUMMY)
-} MT32EMU_ALIGN_PACKED;
-
-struct MemParams {
- // NOTE: The MT-32 documentation only specifies PatchTemp areas for parts 1-8.
- // The LAPC-I documentation specified an additional area for rhythm at the end,
- // where all parameters but fine tune, assign mode and output level are ignored
- struct PatchTemp {
- PatchParam patch;
- Bit8u outlevel; // OUTPUT LEVEL 0-100
- Bit8u panpot; // PANPOT 0-14 (R-L)
- Bit8u dummyv[6];
- } MT32EMU_ALIGN_PACKED;
-
- PatchTemp patchSettings[9];
-
- struct RhythmTemp {
- Bit8u timbre; // TIMBRE 0-94 (M1-M64,R1-30,OFF)
- Bit8u outlevel; // OUTPUT LEVEL 0-100
- Bit8u panpot; // PANPOT 0-14 (R-L)
- Bit8u reverbSwitch; // REVERB SWITCH 0-1 (OFF,ON)
- } MT32EMU_ALIGN_PACKED;
-
- RhythmTemp rhythmSettings[85];
-
- TimbreParam timbreSettings[8];
-
- PatchParam patches[128];
-
- // NOTE: There are only 30 timbres in the "rhythm" bank for MT-32; the additional 34 are for LAPC-I and above
- struct PaddedTimbre {
- TimbreParam timbre;
- Bit8u padding[10];
- } MT32EMU_ALIGN_PACKED;
-
- PaddedTimbre timbres[64 + 64 + 64 + 64]; // Group A, Group B, Memory, Rhythm
-
- struct SystemArea {
- Bit8u masterTune; // MASTER TUNE 0-127 432.1-457.6Hz
- Bit8u reverbMode; // REVERB MODE 0-3 (room, hall, plate, tap delay)
- Bit8u reverbTime; // REVERB TIME 0-7 (1-8)
- Bit8u reverbLevel; // REVERB LEVEL 0-7 (1-8)
- Bit8u reserveSettings[9]; // PARTIAL RESERVE (PART 1) 0-32
- Bit8u chanAssign[9]; // MIDI CHANNEL (PART1) 0-16 (1-16,OFF)
- Bit8u masterVol; // MASTER VOLUME 0-100
- } MT32EMU_ALIGN_PACKED;
-
- SystemArea system;
-};
-
-#if defined(_MSC_VER) || defined (__MINGW32__)
-#pragma pack(pop)
-#else
-#pragma pack()
-#endif
-
-struct PCMWaveEntry {
- Bit32u addr;
- Bit32u len;
- double tune;
- bool loop;
-};
-
-struct soundaddr {
- Bit16u pcmplace;
- Bit16u pcmoffset;
-};
-
-struct StereoVolume {
- Bit16s leftvol;
- Bit16s rightvol;
-};
-
-// This is basically a per-partial, pre-processed combination of timbre and patch/rhythm settings
-struct PatchCache {
- bool playPartial;
- bool PCMPartial;
- int pcm;
- char waveform;
- int pulsewidth;
- int pwsens;
-
- float pitch;
-
- int lfodepth;
- int lforate;
- Bit32u lfoperiod;
- int modsense;
-
- float pitchKeyfollow;
-
- int filtkeyfollow;
-
- int tvfbias;
- int tvfblevel;
- int tvfdir;
-
- int ampbias[2];
- int ampblevel[2];
- int ampdir[2];
-
- int ampdepth;
- int amplevel;
-
- bool useBender;
- float benderRange; // 0.0, 1.0, .., 24.0 (semitones)
-
- TimbreParam::partialParam::envParam pitchEnv;
- TimbreParam::partialParam::tvaParam ampEnv;
- TimbreParam::partialParam::tvfParam filtEnv;
-
- Bit32s pitchsustain;
- Bit32s filtsustain;
-
- Bit32u structureMix;
- int structurePosition;
- int structurePair;
-
- // The following fields are actually common to all partials in the timbre
- bool dirty;
- Bit32u partialCount;
- bool sustain;
- float pitchShift;
- bool reverb;
- const StereoVolume *pansetptr;
-};
-
-class Partial; // Forward reference for class defined in partial.h
-
-struct dpoly {
- bool isPlaying;
-
- unsigned int key;
- int freqnum;
- int vel;
-
- bool isDecay;
-
- const Bit32u *volumeptr;
-
- Partial *partials[4];
-
- bool pedalhold; // This marks keys that have been released on the keyboard, but are being held by the pedal
- bool sustain;
-
- bool isActive() const;
- Bit32u getAge() const;
-};
-
-}
-
-#endif
diff --git a/engines/sci/sfx/softseq/mt32/synth.cpp b/engines/sci/sfx/softseq/mt32/synth.cpp
deleted file mode 100644
index 5ae196dc63..0000000000
--- a/engines/sci/sfx/softseq/mt32/synth.cpp
+++ /dev/null
@@ -1,1199 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include <math.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "mt32emu.h"
-
-#ifdef MACOSX
-// Older versions of Mac OS X didn't supply a powf function. To ensure
-// binary compatibility, we force using pow instead of powf (the only
-// potential drawback is that it might be a little bit slower).
-#define powf pow
-#endif
-
-namespace MT32Emu {
-
-const int MAX_SYSEX_SIZE = 512;
-
-const ControlROMMap ControlROMMaps[5] = {
- // ID IDc IDbytes PCMmap PCMc tmbrA tmbrAO, tmbrB tmbrBO, tmbrR trC rhythm rhyC rsrv panpot prog
- {0x4014, 22, "\000 ver1.04 14 July 87 ", 0x3000, 128, 0x8000, 0x0000, 0xC000, 0x4000, 0x3200, 30, 0x73A6, 85, 0x57C7, 0x57D0, 0x57E2}, // MT-32 revision 0
- {0x4014, 22, "\000 ver1.06 31 Aug, 87 ", 0x3000, 128, 0x8000, 0x0000, 0xC000, 0x4000, 0x3200, 30, 0x7414, 85, 0x57D9, 0x57E2, 0x57F4}, // MT-32 revision 0
- {0x4010, 22, "\000 ver1.07 10 Oct, 87 ", 0x3000, 128, 0x8000, 0x0000, 0xC000, 0x4000, 0x3200, 30, 0x73fe, 85, 0x57B1, 0x57BA, 0x57CC}, // MT-32 revision 1
- {0x4010, 22, "\000verX.XX 30 Sep, 88 ", 0x3000, 128, 0x8000, 0x0000, 0xC000, 0x4000, 0x3200, 30, 0x741C, 85, 0x57E5, 0x57EE, 0x5800}, // MT-32 Blue Ridge mod
- {0x2205, 22, "\000CM32/LAPC1.02 891205", 0x8100, 256, 0x8000, 0x8000, 0x8080, 0x8000, 0x8500, 64, 0x8580, 85, 0x4F93, 0x4F9C, 0x4FAE} // CM-32L
- // (Note that all but CM-32L ROM actually have 86 entries for rhythmTemp)
-};
-
-float iir_filter_normal(float input, float *hist1_ptr, float *coef_ptr) {
- float *hist2_ptr;
- float output,new_hist;
-
- hist2_ptr = hist1_ptr + 1; // next history
-
- // 1st number of coefficients array is overall input scale factor, or filter gain
- output = input * (*coef_ptr++);
-
- output = output - *hist1_ptr * (*coef_ptr++);
- new_hist = output - *hist2_ptr * (*coef_ptr++); // poles
-
- output = new_hist + *hist1_ptr * (*coef_ptr++);
- output = output + *hist2_ptr * (*coef_ptr++); // zeros
-
- *hist2_ptr++ = *hist1_ptr;
- *hist1_ptr++ = new_hist;
- hist1_ptr++;
- hist2_ptr++;
-
- // i = 1
- output = output - *hist1_ptr * (*coef_ptr++);
- new_hist = output - *hist2_ptr * (*coef_ptr++); // poles
-
- output = new_hist + *hist1_ptr * (*coef_ptr++);
- output = output + *hist2_ptr * (*coef_ptr++); // zeros
-
- *hist2_ptr++ = *hist1_ptr;
- *hist1_ptr++ = new_hist;
-
- return(output);
-}
-
-Bit8u Synth::calcSysexChecksum(const Bit8u *data, Bit32u len, Bit8u checksum) {
- for (unsigned int i = 0; i < len; i++) {
- checksum = checksum + data[i];
- }
- checksum = checksum & 0x7f;
- if (checksum)
- checksum = 0x80 - checksum;
- return checksum;
-}
-
-Synth::Synth() {
- isOpen = false;
- reverbModel = NULL;
- partialManager = NULL;
- memset(parts, 0, sizeof(parts));
-}
-
-Synth::~Synth() {
- close(); // Make sure we're closed and everything is freed
-}
-
-int Synth::report(ReportType type, const void *data) {
- if (myProp.report != NULL) {
- return myProp.report(myProp.userData, type, data);
- }
- return 0;
-}
-
-void Synth::printDebug(const char *fmt, ...) {
- va_list ap;
- va_start(ap, fmt);
- if (myProp.printDebug != NULL) {
- myProp.printDebug(myProp.userData, fmt, ap);
- } else {
- vprintf(fmt, ap);
- printf("\n");
- }
- va_end(ap);
-}
-
-void Synth::initReverb(Bit8u newRevMode, Bit8u newRevTime, Bit8u newRevLevel) {
- // FIXME:KG: I don't think it's necessary to recreate the reverbModel... Just set the parameters
- if (reverbModel != NULL)
- delete reverbModel;
- reverbModel = new revmodel();
-
- switch (newRevMode) {
- case 0:
- reverbModel->setroomsize(.1f);
- reverbModel->setdamp(.75f);
- break;
- case 1:
- reverbModel->setroomsize(.5f);
- reverbModel->setdamp(.5f);
- break;
- case 2:
- reverbModel->setroomsize(.5f);
- reverbModel->setdamp(.1f);
- break;
- case 3:
- reverbModel->setroomsize(1.0f);
- reverbModel->setdamp(.75f);
- break;
- default:
- reverbModel->setroomsize(.1f);
- reverbModel->setdamp(.5f);
- break;
- }
- reverbModel->setdry(1);
- reverbModel->setwet((float)newRevLevel / 8.0f);
- reverbModel->setwidth((float)newRevTime / 8.0f);
-}
-
-File *Synth::openFile(const char *filename, File::OpenMode mode) {
- if (myProp.openFile != NULL) {
- return myProp.openFile(myProp.userData, filename, mode);
- }
- char pathBuf[2048];
- if (myProp.baseDir != NULL) {
- strcpy(&pathBuf[0], myProp.baseDir);
- strcat(&pathBuf[0], filename);
- filename = pathBuf;
- }
- ANSIFile *file = new ANSIFile();
- if (!file->open(filename, mode)) {
- delete file;
- return NULL;
- }
- return file;
-}
-
-void Synth::closeFile(File *file) {
- if (myProp.closeFile != NULL) {
- myProp.closeFile(myProp.userData, file);
- } else {
- file->close();
- delete file;
- }
-}
-
-bool Synth::loadPreset(File *file) {
- bool inSys = false;
- Bit8u sysexBuf[MAX_SYSEX_SIZE];
- Bit16u syslen = 0;
- bool rc = true;
- for (;;) {
- Bit8u c;
- if (!file->readBit8u(&c)) {
- if (!file->isEOF()) {
- rc = false;
- }
- break;
- }
- sysexBuf[syslen] = c;
- if (inSys) {
- syslen++;
- if (c == 0xF7) {
- playSysex(&sysexBuf[0], syslen);
- inSys = false;
- syslen = 0;
- } else if (syslen == MAX_SYSEX_SIZE) {
- printDebug("MAX_SYSEX_SIZE (%d) exceeded while processing preset, ignoring message", MAX_SYSEX_SIZE);
- inSys = false;
- syslen = 0;
- }
- } else if (c == 0xF0) {
- syslen++;
- inSys = true;
- }
- }
- return rc;
-}
-
-bool Synth::loadControlROM(const char *filename) {
- File *file = openFile(filename, File::OpenMode_read); // ROM File
- if (file == NULL) {
- return false;
- }
- bool rc = (file->read(controlROMData, CONTROL_ROM_SIZE) == CONTROL_ROM_SIZE);
-
- closeFile(file);
- if (!rc)
- return rc;
-
- // Control ROM successfully loaded, now check whether it's a known type
- controlROMMap = NULL;
- for (unsigned int i = 0; i < sizeof (ControlROMMaps) / sizeof (ControlROMMaps[0]); i++) {
- if (memcmp(&controlROMData[ControlROMMaps[i].idPos], ControlROMMaps[i].idBytes, ControlROMMaps[i].idLen) == 0) {
- controlROMMap = &ControlROMMaps[i];
- return true;
- }
- }
- return false;
-}
-
-bool Synth::loadPCMROM(const char *filename) {
- File *file = openFile(filename, File::OpenMode_read); // ROM File
- if (file == NULL) {
- return false;
- }
- bool rc = true;
- int i;
- for (i = 0; i < pcmROMSize; i++) {
- Bit8u s;
- if (!file->readBit8u(&s)) {
- if (!file->isEOF()) {
- rc = false;
- }
- break;
- }
- Bit8u c;
- if (!file->readBit8u(&c)) {
- if (!file->isEOF()) {
- rc = false;
- } else {
- printDebug("PCM ROM file has an odd number of bytes! Ignoring last");
- }
- break;
- }
-
- short e;
- int bit;
- int u;
- int order[16] = {0, 9, 1 ,2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 8};
-
- e = 0;
- for (u = 0; u < 15; u++) {
- if (order[u] < 8)
- bit = (s >> (7 - order[u])) & 0x1;
- else
- bit = (c >> (7 - (order[u] - 8))) & 0x1;
- e = e | (short)(bit << (15 - u));
- }
-
- /*
- //Bit16s e = ( ((s & 0x7f) << 4) | ((c & 0x40) << 6) | ((s & 0x80) << 6) | ((c & 0x3f))) << 2;
- if (e<0)
- e = -32767 - e;
- int ut = abs(e);
- int dif = 0x7fff - ut;
- x = exp(((float)((float)0x8000-(float)dif) / (float)0x1000));
- e = (int)((float)e * (x/3200));
- */
-
- // File is companded (dB?), convert to linear PCM
- // MINDB = -96
- // MAXDB = -15
- float testval;
- testval = (float)((~e) & 0x7fff);
- testval = -(testval / 400.00f);
- //testval = -(testval / 341.32291666666666666666666666667);
- float vol = powf(8, testval / 20) * 32767.0f;
-
- if (e > 0)
- vol = -vol;
-
- pcmROMData[i] = (Bit16s)vol;
- }
- if (i != pcmROMSize) {
- printDebug("PCM ROM file is too short (expected %d, got %d)", pcmROMSize, i);
- rc = false;
- }
- closeFile(file);
- return rc;
-}
-
-bool Synth::initPCMList(Bit16u mapAddress, Bit16u count) {
- ControlROMPCMStruct *tps = (ControlROMPCMStruct *)&controlROMData[mapAddress];
- for (int i = 0; i < count; i++) {
- int rAddr = tps[i].pos * 0x800;
- int rLenExp = (tps[i].len & 0x70) >> 4;
- int rLen = 0x800 << rLenExp;
- bool rLoop = (tps[i].len & 0x80) != 0;
- //Bit8u rFlag = tps[i].len & 0x0F;
- Bit16u rTuneOffset = (tps[i].pitchMSB << 8) | tps[i].pitchLSB;
- // The number below is confirmed to a reasonable degree of accuracy on CM-32L
- double STANDARDFREQ = 442.0;
- float rTune = (float)(STANDARDFREQ * pow(2.0, (0x5000 - rTuneOffset) / 4056.0 - 9.0 / 12.0));
- //printDebug("%f,%d,%d", pTune, tps[i].pitchCoarse, tps[i].pitchFine);
- if (rAddr + rLen > pcmROMSize) {
- printDebug("Control ROM error: Wave map entry %d points to invalid PCM address 0x%04X, length 0x%04X", i, rAddr, rLen);
- return false;
- }
- pcmWaves[i].addr = rAddr;
- pcmWaves[i].len = rLen;
- pcmWaves[i].loop = rLoop;
- pcmWaves[i].tune = rTune;
- }
- return false;
-}
-
-bool Synth::initRhythmTimbre(int timbreNum, const Bit8u *mem, unsigned int memLen) {
- if (memLen < sizeof(TimbreParam::commonParam)) {
- return false;
- }
- TimbreParam *timbre = &mt32ram.timbres[timbreNum].timbre;
- memcpy(&timbre->common, mem, 14);
- unsigned int memPos = 14;
- char drumname[11];
- strncpy(drumname, timbre->common.name, 10);
- drumname[10] = 0;
- for (int t = 0; t < 4; t++) {
- if (((timbre->common.pmute >> t) & 0x1) == 0x1) {
- if (memPos + 58 >= memLen) {
- return false;
- }
- memcpy(&timbre->partial[t], mem + memPos, 58);
- memPos += 58;
- }
- }
- return true;
-}
-
-bool Synth::initRhythmTimbres(Bit16u mapAddress, Bit16u count) {
- const Bit8u *drumMap = &controlROMData[mapAddress];
- int timbreNum = 192;
- for (Bit16u i = 0; i < count * 2; i += 2) {
- Bit16u address = (drumMap[i + 1] << 8) | drumMap[i];
- /*
- // This check is nonsensical when the control ROM is the full 64KB addressable by 16-bit absolute pointers (which it is)
- if (address >= CONTROL_ROM_SIZE) {
- printDebug("Control ROM error: Timbre map entry 0x%04x points to invalid timbre address 0x%04x", i, address);
- return false;
- }
- */
- if (!initRhythmTimbre(timbreNum++, &controlROMData[address], CONTROL_ROM_SIZE - address)) {
- printDebug("Control ROM error: Timbre map entry 0x%04x points to invalid timbre 0x%04x", i, address);
- return false;
- }
- }
- return true;
-}
-
-bool Synth::initTimbres(Bit16u mapAddress, Bit16u offset, int startTimbre) {
- for (Bit16u i = mapAddress; i < mapAddress + 0x80; i += 2) {
- Bit16u address = (controlROMData[i + 1] << 8) | controlROMData[i];
- if (address + sizeof(TimbreParam) > CONTROL_ROM_SIZE) {
- printDebug("Control ROM error: Timbre map entry 0x%04x points to invalid timbre address 0x%04x", i, address);
- return false;
- }
- address = address + offset;
- TimbreParam *timbre = &mt32ram.timbres[startTimbre++].timbre;
- memcpy(timbre, &controlROMData[address], sizeof(TimbreParam));
- }
- return true;
-}
-
-bool Synth::open(SynthProperties &useProp) {
- if (isOpen)
- return false;
-
- myProp = useProp;
- if (useProp.baseDir != NULL) {
- myProp.baseDir = new char[strlen(useProp.baseDir) + 1];
- strcpy(myProp.baseDir, useProp.baseDir);
- }
-
- // This is to help detect bugs
- memset(&mt32ram, '?', sizeof(mt32ram));
-
- printDebug("Loading Control ROM");
- if (!loadControlROM("CM32L_CONTROL.ROM")) {
- if (!loadControlROM("MT32_CONTROL.ROM")) {
- printDebug("Init Error - Missing or invalid MT32_CONTROL.ROM");
- report(ReportType_errorControlROM, NULL);
- return false;
- }
- }
-
- // 512KB PCM ROM for MT-32, etc.
- // 1MB PCM ROM for CM-32L, LAPC-I, CM-64, CM-500
- // Note that the size below is given in samples (16-bit), not bytes
- pcmROMSize = controlROMMap->pcmCount == 256 ? 512 * 1024 : 256 * 1024;
- pcmROMData = new Bit16s[pcmROMSize];
-
- printDebug("Loading PCM ROM");
- if (!loadPCMROM("CM32L_PCM.ROM")) {
- if (!loadPCMROM("MT32_PCM.ROM")) {
- printDebug("Init Error - Missing MT32_PCM.ROM");
- report(ReportType_errorPCMROM, NULL);
- return false;
- }
- }
-
- printDebug("Initialising Timbre Bank A");
- if (!initTimbres(controlROMMap->timbreAMap, controlROMMap->timbreAOffset, 0)) {
- return false;
- }
-
- printDebug("Initialising Timbre Bank B");
- if (!initTimbres(controlROMMap->timbreBMap, controlROMMap->timbreBOffset, 64)) {
- return false;
- }
-
- printDebug("Initialising Timbre Bank R");
- if (!initRhythmTimbres(controlROMMap->timbreRMap, controlROMMap->timbreRCount)) {
- return false;
- }
-
- printDebug("Initialising Timbre Bank M");
- // CM-64 seems to initialise all bytes in this bank to 0.
- memset(&mt32ram.timbres[128], 0, sizeof (mt32ram.timbres[128]) * 64);
-
- partialManager = new PartialManager(this);
-
- pcmWaves = new PCMWaveEntry[controlROMMap->pcmCount];
-
- printDebug("Initialising PCM List");
- initPCMList(controlROMMap->pcmTable, controlROMMap->pcmCount);
-
- printDebug("Initialising Rhythm Temp");
- memcpy(mt32ram.rhythmSettings, &controlROMData[controlROMMap->rhythmSettings], controlROMMap->rhythmSettingsCount * 4);
-
- printDebug("Initialising Patches");
- for (Bit8u i = 0; i < 128; i++) {
- PatchParam *patch = &mt32ram.patches[i];
- patch->timbreGroup = i / 64;
- patch->timbreNum = i % 64;
- patch->keyShift = 24;
- patch->fineTune = 50;
- patch->benderRange = 12;
- patch->assignMode = 0;
- patch->reverbSwitch = 1;
- patch->dummy = 0;
- }
-
- printDebug("Initialising System");
- // The MT-32 manual claims that "Standard pitch" is 442Hz.
- mt32ram.system.masterTune = 0x4A; // Confirmed on CM-64
- mt32ram.system.reverbMode = 0; // Confirmed
- mt32ram.system.reverbTime = 5; // Confirmed
- mt32ram.system.reverbLevel = 3; // Confirmed
- memcpy(mt32ram.system.reserveSettings, &controlROMData[controlROMMap->reserveSettings], 9); // Confirmed
- for (Bit8u i = 0; i < 9; i++) {
- // This is the default: {1, 2, 3, 4, 5, 6, 7, 8, 9}
- // An alternative configuration can be selected by holding "Master Volume"
- // and pressing "PART button 1" on the real MT-32's frontpanel.
- // The channel assignment is then {0, 1, 2, 3, 4, 5, 6, 7, 9}
- mt32ram.system.chanAssign[i] = i + 1;
- }
- mt32ram.system.masterVol = 100; // Confirmed
- if (!refreshSystem())
- return false;
-
- for (int i = 0; i < 8; i++) {
- mt32ram.patchSettings[i].outlevel = 80;
- mt32ram.patchSettings[i].panpot = controlROMData[controlROMMap->panSettings + i];
- memset(mt32ram.patchSettings[i].dummyv, 0, sizeof(mt32ram.patchSettings[i].dummyv));
- parts[i] = new Part(this, i);
- parts[i]->setProgram(controlROMData[controlROMMap->programSettings + i]);
- }
- parts[8] = new RhythmPart(this, 8);
-
- // For resetting mt32 mid-execution
- mt32default = mt32ram;
-
- iirFilter = &iir_filter_normal;
-
-#ifdef MT32EMU_HAVE_X86
- bool availableSSE = DetectSIMD();
- bool available3DNow = Detect3DNow();
-
- if (availableSSE)
- report(ReportType_availableSSE, NULL);
- if (available3DNow)
- report(ReportType_available3DNow, NULL);
-
- if (available3DNow) {
- printDebug("Detected and using SIMD (AMD 3DNow) extensions");
- iirFilter = &iir_filter_3dnow;
- report(ReportType_using3DNow, NULL);
- } else if (availableSSE) {
- printDebug("Detected and using SIMD (Intel SSE) extensions");
- iirFilter = &iir_filter_sse;
- report(ReportType_usingSSE, NULL);
- }
-#endif
-
- isOpen = true;
- isEnabled = false;
-
- printDebug("*** Initialisation complete ***");
- return true;
-}
-
-void Synth::close(void) {
- if (!isOpen)
- return;
-
- tables.freeNotes();
- if (partialManager != NULL) {
- delete partialManager;
- partialManager = NULL;
- }
-
- if (reverbModel != NULL) {
- delete reverbModel;
- reverbModel = NULL;
- }
-
- for (int i = 0; i < 9; i++) {
- if (parts[i] != NULL) {
- delete parts[i];
- parts[i] = NULL;
- }
- }
- if (myProp.baseDir != NULL) {
- delete myProp.baseDir;
- myProp.baseDir = NULL;
- }
-
- delete[] pcmWaves;
- delete[] pcmROMData;
- isOpen = false;
-}
-
-void Synth::playMsg(Bit32u msg) {
- // FIXME: Implement active sensing
- unsigned char code = (unsigned char)((msg & 0x0000F0) >> 4);
- unsigned char chan = (unsigned char) (msg & 0x00000F);
- unsigned char note = (unsigned char)((msg & 0x00FF00) >> 8);
- unsigned char velocity = (unsigned char)((msg & 0xFF0000) >> 16);
- isEnabled = true;
-
- //printDebug("Playing chan %d, code 0x%01x note: 0x%02x", chan, code, note);
-
- char part = chantable[chan];
- if (part < 0 || part > 8) {
- printDebug("Play msg on unreg chan %d (%d): code=0x%01x, vel=%d", chan, part, code, velocity);
- return;
- }
- playMsgOnPart(part, code, note, velocity);
-}
-
-void Synth::playMsgOnPart(unsigned char part, unsigned char code, unsigned char note, unsigned char velocity) {
- Bit32u bend;
-
- //printDebug("Synth::playMsg(0x%02x)",msg);
- switch (code) {
- case 0x8:
- //printDebug("Note OFF - Part %d", part);
- // The MT-32 ignores velocity for note off
- parts[part]->stopNote(note);
- break;
- case 0x9:
- //printDebug("Note ON - Part %d, Note %d Vel %d", part, note, velocity);
- if (velocity == 0) {
- // MIDI defines note-on with velocity 0 as being the same as note-off with velocity 40
- parts[part]->stopNote(note);
- } else {
- parts[part]->playNote(note, velocity);
- }
- break;
- case 0xB: // Control change
- switch (note) {
- case 0x01: // Modulation
- //printDebug("Modulation: %d", velocity);
- parts[part]->setModulation(velocity);
- break;
- case 0x07: // Set volume
- //printDebug("Volume set: %d", velocity);
- parts[part]->setVolume(velocity);
- break;
- case 0x0A: // Pan
- //printDebug("Pan set: %d", velocity);
- parts[part]->setPan(velocity);
- break;
- case 0x0B:
- //printDebug("Expression set: %d", velocity);
- parts[part]->setExpression(velocity);
- break;
- case 0x40: // Hold (sustain) pedal
- //printDebug("Hold pedal set: %d", velocity);
- parts[part]->setHoldPedal(velocity>=64);
- break;
-
- case 0x79: // Reset all controllers
- //printDebug("Reset all controllers");
- //FIXME: Check for accuracy against real thing
- parts[part]->setVolume(100);
- parts[part]->setExpression(127);
- parts[part]->setPan(64);
- parts[part]->setBend(0x2000);
- parts[part]->setHoldPedal(false);
- break;
-
- case 0x7B: // All notes off
- //printDebug("All notes off");
- parts[part]->allNotesOff();
- break;
-
- default:
- printDebug("Unknown MIDI Control code: 0x%02x - vel 0x%02x", note, velocity);
- break;
- }
-
- break;
- case 0xC: // Program change
- //printDebug("Program change %01x", note);
- parts[part]->setProgram(note);
- break;
- case 0xE: // Pitch bender
- bend = (velocity << 7) | (note);
- //printDebug("Pitch bender %02x", bend);
- parts[part]->setBend(bend);
- break;
- default:
- printDebug("Unknown Midi code: 0x%01x - %02x - %02x", code, note, velocity);
- break;
- }
-
- //midiOutShortMsg(m_out, msg);
-}
-
-void Synth::playSysex(const Bit8u *sysex, Bit32u len) {
- if (len < 2) {
- printDebug("playSysex: Message is too short for sysex (%d bytes)", len);
- }
- if (sysex[0] != 0xF0) {
- printDebug("playSysex: Message lacks start-of-sysex (0xF0)");
- return;
- }
- // Due to some programs (e.g. Java) sending buffers with junk at the end, we have to go through and find the end marker rather than relying on len.
- Bit32u endPos;
- for (endPos = 1; endPos < len; endPos++)
- {
- if (sysex[endPos] == 0xF7)
- break;
- }
- if (endPos == len) {
- printDebug("playSysex: Message lacks end-of-sysex (0xf7)");
- return;
- }
- playSysexWithoutFraming(sysex + 1, endPos - 1);
-}
-
-void Synth::playSysexWithoutFraming(const Bit8u *sysex, Bit32u len) {
- if (len < 4) {
- printDebug("playSysexWithoutFraming: Message is too short (%d bytes)!", len);
- return;
- }
- if (sysex[0] != SYSEX_MANUFACTURER_ROLAND) {
- printDebug("playSysexWithoutFraming: Header not intended for this device manufacturer: %02x %02x %02x %02x", (int)sysex[0], (int)sysex[1], (int)sysex[2], (int)sysex[3]);
- return;
- }
- if (sysex[2] == SYSEX_MDL_D50) {
- printDebug("playSysexWithoutFraming: Header is intended for model D-50 (not yet supported): %02x %02x %02x %02x", (int)sysex[0], (int)sysex[1], (int)sysex[2], (int)sysex[3]);
- return;
- }
- else if (sysex[2] != SYSEX_MDL_MT32) {
- printDebug("playSysexWithoutFraming: Header not intended for model MT-32: %02x %02x %02x %02x", (int)sysex[0], (int)sysex[1], (int)sysex[2], (int)sysex[3]);
- return;
- }
- playSysexWithoutHeader(sysex[1], sysex[3], sysex + 4, len - 4);
-}
-
-void Synth::playSysexWithoutHeader(unsigned char device, unsigned char command, const Bit8u *sysex, Bit32u len) {
- if (device > 0x10) {
- // We have device ID 0x10 (default, but changeable, on real MT-32), < 0x10 is for channels
- printDebug("playSysexWithoutHeader: Message is not intended for this device ID (provided: %02x, expected: 0x10 or channel)", (int)device);
- return;
- }
- if (len < 4) {
- printDebug("playSysexWithoutHeader: Message is too short (%d bytes)!", len);
- return;
- }
- unsigned char checksum = calcSysexChecksum(sysex, len - 1, 0);
- if (checksum != sysex[len - 1]) {
- printDebug("playSysexWithoutHeader: Message checksum is incorrect (provided: %02x, expected: %02x)!", sysex[len - 1], checksum);
- return;
- }
- len -= 1; // Exclude checksum
- switch (command) {
- case SYSEX_CMD_DT1:
- writeSysex(device, sysex, len);
- break;
- case SYSEX_CMD_RQ1:
- readSysex(device, sysex, len);
- break;
- default:
- printDebug("playSysexWithoutFraming: Unsupported command %02x", command);
- return;
- }
-}
-
-void Synth::readSysex(unsigned char /*device*/, const Bit8u * /*sysex*/, Bit32u /*len*/) {
-}
-
-const MemoryRegion memoryRegions[8] = {
- {MR_PatchTemp, MT32EMU_MEMADDR(0x030000), sizeof(MemParams::PatchTemp), 9},
- {MR_RhythmTemp, MT32EMU_MEMADDR(0x030110), sizeof(MemParams::RhythmTemp), 85},
- {MR_TimbreTemp, MT32EMU_MEMADDR(0x040000), sizeof(TimbreParam), 8},
- {MR_Patches, MT32EMU_MEMADDR(0x050000), sizeof(PatchParam), 128},
- {MR_Timbres, MT32EMU_MEMADDR(0x080000), sizeof(MemParams::PaddedTimbre), 64 + 64 + 64 + 64},
- {MR_System, MT32EMU_MEMADDR(0x100000), sizeof(MemParams::SystemArea), 1},
- {MR_Display, MT32EMU_MEMADDR(0x200000), MAX_SYSEX_SIZE - 1, 1},
- {MR_Reset, MT32EMU_MEMADDR(0x7F0000), 0x3FFF, 1}
-};
-
-const int NUM_REGIONS = sizeof(memoryRegions) / sizeof(MemoryRegion);
-
-void Synth::writeSysex(unsigned char device, const Bit8u *sysex, Bit32u len) {
- Bit32u addr = (sysex[0] << 16) | (sysex[1] << 8) | (sysex[2]);
- addr = MT32EMU_MEMADDR(addr);
- sysex += 3;
- len -= 3;
- //printDebug("Sysex addr: 0x%06x", MT32EMU_SYSEXMEMADDR(addr));
- // NOTE: Please keep both lower and upper bounds in each check, for ease of reading
-
- // Process channel-specific sysex by converting it to device-global
- if (device < 0x10) {
- printDebug("WRITE-CHANNEL: Channel %d temp area 0x%06x", device, MT32EMU_SYSEXMEMADDR(addr));
- if (/*addr >= MT32EMU_MEMADDR(0x000000) && */addr < MT32EMU_MEMADDR(0x010000)) {
- int offset;
- if (chantable[device] == -1) {
- printDebug(" (Channel not mapped to a partial... 0 offset)");
- offset = 0;
- } else if (chantable[device] == 8) {
- printDebug(" (Channel mapped to rhythm... 0 offset)");
- offset = 0;
- } else {
- offset = chantable[device] * sizeof(MemParams::PatchTemp);
- printDebug(" (Setting extra offset to %d)", offset);
- }
- addr += MT32EMU_MEMADDR(0x030000) + offset;
- } else if (/*addr >= 0x010000 && */ addr < MT32EMU_MEMADDR(0x020000)) {
- addr += MT32EMU_MEMADDR(0x030110) - MT32EMU_MEMADDR(0x010000);
- } else if (/*addr >= 0x020000 && */ addr < MT32EMU_MEMADDR(0x030000)) {
- int offset;
- if (chantable[device] == -1) {
- printDebug(" (Channel not mapped to a partial... 0 offset)");
- offset = 0;
- } else if (chantable[device] == 8) {
- printDebug(" (Channel mapped to rhythm... 0 offset)");
- offset = 0;
- } else {
- offset = chantable[device] * sizeof(TimbreParam);
- printDebug(" (Setting extra offset to %d)", offset);
- }
- addr += MT32EMU_MEMADDR(0x040000) - MT32EMU_MEMADDR(0x020000) + offset;
- } else {
- printDebug("PlaySysexWithoutHeader: Invalid channel %d address 0x%06x", device, MT32EMU_SYSEXMEMADDR(addr));
- return;
- }
- }
-
- // Process device-global sysex (possibly converted from channel-specific sysex above)
- for (;;) {
- // Find the appropriate memory region
- int regionNum;
- const MemoryRegion *region = NULL; // Initialised to please compiler
- for (regionNum = 0; regionNum < NUM_REGIONS; regionNum++) {
- region = &memoryRegions[regionNum];
- if (region->contains(addr)) {
- writeMemoryRegion(region, addr, region->getClampedLen(addr, len), sysex);
- break;
- }
- }
- if (regionNum == NUM_REGIONS) {
- printDebug("Sysex write to unrecognised address %06x, len %d", MT32EMU_SYSEXMEMADDR(addr), len);
- break;
- }
- Bit32u next = region->next(addr, len);
- if (next == 0) {
- break;
- }
- addr += next;
- sysex += next;
- len -= next;
- }
-}
-
-void Synth::readMemory(Bit32u addr, Bit32u len, Bit8u *data) {
- int regionNum;
- const MemoryRegion *region = NULL;
- for (regionNum = 0; regionNum < NUM_REGIONS; regionNum++) {
- region = &memoryRegions[regionNum];
- if (region->contains(addr)) {
- readMemoryRegion(region, addr, len, data);
- break;
- }
- }
-}
-
-void Synth::readMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u len, Bit8u *data) {
- unsigned int first = region->firstTouched(addr);
- //unsigned int last = region->lastTouched(addr, len);
- unsigned int off = region->firstTouchedOffset(addr);
- len = region->getClampedLen(addr, len);
-
- unsigned int m;
-
- switch(region->type) {
- case MR_PatchTemp:
- for (m = 0; m < len; m++)
- data[m] = ((Bit8u *)&mt32ram.patchSettings[first])[off + m];
- break;
- case MR_RhythmTemp:
- for (m = 0; m < len; m++)
- data[m] = ((Bit8u *)&mt32ram.rhythmSettings[first])[off + m];
- break;
- case MR_TimbreTemp:
- for (m = 0; m < len; m++)
- data[m] = ((Bit8u *)&mt32ram.timbreSettings[first])[off + m];
- break;
- case MR_Patches:
- for (m = 0; m < len; m++)
- data[m] = ((Bit8u *)&mt32ram.patches[first])[off + m];
- break;
- case MR_Timbres:
- for (m = 0; m < len; m++)
- data[m] = ((Bit8u *)&mt32ram.timbres[first])[off + m];
- break;
- case MR_System:
- for (m = 0; m < len; m++)
- data[m] = ((Bit8u *)&mt32ram.system)[m + off];
- break;
- default:
- for (m = 0; m < len; m += 2) {
- data[m] = 0xff;
- if (m + 1 < len) {
- data[m+1] = (Bit8u)region->type;
- }
- }
- // TODO: Don't care about the others ATM
- break;
- }
-
-}
-
-void Synth::writeMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u len, const Bit8u *data) {
- unsigned int first = region->firstTouched(addr);
- unsigned int last = region->lastTouched(addr, len);
- unsigned int off = region->firstTouchedOffset(addr);
- switch (region->type) {
- case MR_PatchTemp:
- for (unsigned int m = 0; m < len; m++) {
- ((Bit8u *)&mt32ram.patchSettings[first])[off + m] = data[m];
- }
- //printDebug("Patch temp: Patch %d, offset %x, len %d", off/16, off % 16, len);
-
- for (unsigned int i = first; i <= last; i++) {
- int absTimbreNum = mt32ram.patchSettings[i].patch.timbreGroup * 64 + mt32ram.patchSettings[i].patch.timbreNum;
- char timbreName[11];
- memcpy(timbreName, mt32ram.timbres[absTimbreNum].timbre.common.name, 10);
- timbreName[10] = 0;
- printDebug("WRITE-PARTPATCH (%d-%d@%d..%d): %d; timbre=%d (%s), outlevel=%d", first, last, off, off + len, i, absTimbreNum, timbreName, mt32ram.patchSettings[i].outlevel);
- if (parts[i] != NULL) {
- if (i != 8) {
- // Note: Confirmed on CM-64 that we definitely *should* update the timbre here,
- // but only in the case that the sysex actually writes to those values
- if (i == first && off > 2) {
- printDebug(" (Not updating timbre, since those values weren't touched)");
- } else {
- parts[i]->setTimbre(&mt32ram.timbres[parts[i]->getAbsTimbreNum()].timbre);
- }
- }
- parts[i]->refresh();
- }
- }
- break;
- case MR_RhythmTemp:
- for (unsigned int m = 0; m < len; m++)
- ((Bit8u *)&mt32ram.rhythmSettings[first])[off + m] = data[m];
- for (unsigned int i = first; i <= last; i++) {
- int timbreNum = mt32ram.rhythmSettings[i].timbre;
- char timbreName[11];
- if (timbreNum < 94) {
- memcpy(timbreName, mt32ram.timbres[128 + timbreNum].timbre.common.name, 10);
- timbreName[10] = 0;
- } else {
- strcpy(timbreName, "[None]");
- }
- printDebug("WRITE-RHYTHM (%d-%d@%d..%d): %d; level=%02x, panpot=%02x, reverb=%02x, timbre=%d (%s)", first, last, off, off + len, i, mt32ram.rhythmSettings[i].outlevel, mt32ram.rhythmSettings[i].panpot, mt32ram.rhythmSettings[i].reverbSwitch, mt32ram.rhythmSettings[i].timbre, timbreName);
- }
- if (parts[8] != NULL) {
- parts[8]->refresh();
- }
- break;
- case MR_TimbreTemp:
- for (unsigned int m = 0; m < len; m++)
- ((Bit8u *)&mt32ram.timbreSettings[first])[off + m] = data[m];
- for (unsigned int i = first; i <= last; i++) {
- char instrumentName[11];
- memcpy(instrumentName, mt32ram.timbreSettings[i].common.name, 10);
- instrumentName[10] = 0;
- printDebug("WRITE-PARTTIMBRE (%d-%d@%d..%d): timbre=%d (%s)", first, last, off, off + len, i, instrumentName);
- if (parts[i] != NULL) {
- parts[i]->refresh();
- }
- }
- break;
- case MR_Patches:
- for (unsigned int m = 0; m < len; m++)
- ((Bit8u *)&mt32ram.patches[first])[off + m] = data[m];
- for (unsigned int i = first; i <= last; i++) {
- PatchParam *patch = &mt32ram.patches[i];
- int patchAbsTimbreNum = patch->timbreGroup * 64 + patch->timbreNum;
- char instrumentName[11];
- memcpy(instrumentName, mt32ram.timbres[patchAbsTimbreNum].timbre.common.name, 10);
- instrumentName[10] = 0;
- Bit8u *n = (Bit8u *)patch;
- printDebug("WRITE-PATCH (%d-%d@%d..%d): %d; timbre=%d (%s) %02X%02X%02X%02X%02X%02X%02X%02X", first, last, off, off + len, i, patchAbsTimbreNum, instrumentName, n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7]);
- // FIXME:KG: The below is definitely dodgy. We just guess that this is the patch that the part was using
- // based on a timbre match (but many patches could have the same timbre!)
- // If this refresh is really correct, we should store the patch number in use by each part.
- /*
- for (int part = 0; part < 8; part++) {
- if (parts[part] != NULL) {
- int partPatchAbsTimbreNum = mt32ram.patchSettings[part].patch.timbreGroup * 64 + mt32ram.patchSettings[part].patch.timbreNum;
- if (parts[part]->getAbsTimbreNum() == patchAbsTimbreNum) {
- parts[part]->setPatch(patch);
- parts[part]->RefreshPatch();
- }
- }
- }
- */
- }
- break;
- case MR_Timbres:
- // Timbres
- first += 128;
- last += 128;
- for (unsigned int m = 0; m < len; m++)
- ((Bit8u *)&mt32ram.timbres[first])[off + m] = data[m];
- for (unsigned int i = first; i <= last; i++) {
- char instrumentName[11];
- memcpy(instrumentName, mt32ram.timbres[i].timbre.common.name, 10);
- instrumentName[10] = 0;
- printDebug("WRITE-TIMBRE (%d-%d@%d..%d): %d; name=\"%s\"", first, last, off, off + len, i, instrumentName);
- // FIXME:KG: Not sure if the stuff below should be done (for rhythm and/or parts)...
- // Does the real MT-32 automatically do this?
- for (unsigned int part = 0; part < 9; part++) {
- if (parts[part] != NULL) {
- parts[part]->refreshTimbre(i);
- }
- }
- }
- break;
- case MR_System:
- for (unsigned int m = 0; m < len; m++)
- ((Bit8u *)&mt32ram.system)[m + off] = data[m];
-
- report(ReportType_devReconfig, NULL);
-
- printDebug("WRITE-SYSTEM:");
- refreshSystem();
- break;
- case MR_Display:
- char buf[MAX_SYSEX_SIZE];
- memcpy(&buf, &data[0], len);
- buf[len] = 0;
- printDebug("WRITE-LCD: %s", buf);
- report(ReportType_lcdMessage, buf);
- break;
- case MR_Reset:
- printDebug("RESET");
- report(ReportType_devReset, NULL);
- partialManager->deactivateAll();
- mt32ram = mt32default;
- for (int i = 0; i < 9; i++) {
- parts[i]->refresh();
- }
- isEnabled = false;
- break;
- }
-}
-
-bool Synth::refreshSystem() {
- memset(chantable, -1, sizeof(chantable));
-
- for (unsigned int i = 0; i < 9; i++) {
- //LOG(LOG_MISC|LOG_ERROR,"Part %d set to MIDI channel %d",i,mt32ram.system.chanAssign[i]);
- if (mt32ram.system.chanAssign[i] == 16 && parts[i] != NULL) {
- parts[i]->allSoundOff();
- } else {
- chantable[(int)mt32ram.system.chanAssign[i]] = (char)i;
- }
- }
- //FIXME:KG: This is just an educated guess.
- // The LAPC-I documentation claims a range of 427.5Hz-452.6Hz (similar to what we have here)
- // The MT-32 documentation claims a range of 432.1Hz-457.6Hz
- masterTune = 440.0f * powf(2.0f, (mt32ram.system.masterTune - 64.0f) / (128.0f * 12.0f));
- printDebug(" Master Tune: %f", masterTune);
- printDebug(" Reverb: mode=%d, time=%d, level=%d", mt32ram.system.reverbMode, mt32ram.system.reverbTime, mt32ram.system.reverbLevel);
- report(ReportType_newReverbMode, &mt32ram.system.reverbMode);
- report(ReportType_newReverbTime, &mt32ram.system.reverbTime);
- report(ReportType_newReverbLevel, &mt32ram.system.reverbLevel);
-
- if (myProp.useDefaultReverb) {
- initReverb(mt32ram.system.reverbMode, mt32ram.system.reverbTime, mt32ram.system.reverbLevel);
- } else {
- initReverb(myProp.reverbType, myProp.reverbTime, mt32ram.system.reverbLevel);
- }
-
- Bit8u *rset = mt32ram.system.reserveSettings;
- printDebug(" Partial reserve: 1=%02d 2=%02d 3=%02d 4=%02d 5=%02d 6=%02d 7=%02d 8=%02d Rhythm=%02d", rset[0], rset[1], rset[2], rset[3], rset[4], rset[5], rset[6], rset[7], rset[8]);
- int pr = partialManager->setReserve(rset);
- if (pr != 32)
- printDebug(" (Partial Reserve Table with less than 32 partials reserved!)");
- rset = mt32ram.system.chanAssign;
- printDebug(" Part assign: 1=%02d 2=%02d 3=%02d 4=%02d 5=%02d 6=%02d 7=%02d 8=%02d Rhythm=%02d", rset[0], rset[1], rset[2], rset[3], rset[4], rset[5], rset[6], rset[7], rset[8]);
- printDebug(" Master volume: %d", mt32ram.system.masterVol);
- masterVolume = (Bit16u)(mt32ram.system.masterVol * 32767 / 100);
- if (!tables.init(this, pcmWaves, (float)myProp.sampleRate, masterTune)) {
- report(ReportType_errorSampleRate, NULL);
- return false;
- }
- return true;
-}
-
-bool Synth::dumpTimbre(File *file, const TimbreParam *timbre, Bit32u address) {
- // Sysex header
- if (!file->writeBit8u(0xF0))
- return false;
- if (!file->writeBit8u(0x41))
- return false;
- if (!file->writeBit8u(0x10))
- return false;
- if (!file->writeBit8u(0x16))
- return false;
- if (!file->writeBit8u(0x12))
- return false;
-
- char lsb = (char)(address & 0x7f);
- char isb = (char)((address >> 7) & 0x7f);
- char msb = (char)(((address >> 14) & 0x7f) | 0x08);
-
- //Address
- if (!file->writeBit8u(msb))
- return false;
- if (!file->writeBit8u(isb))
- return false;
- if (!file->writeBit8u(lsb))
- return false;
-
- //Data
- if (file->write(timbre, 246) != 246)
- return false;
-
- //Checksum
- unsigned char checksum = calcSysexChecksum((const Bit8u *)timbre, 246, msb + isb + lsb);
- if (!file->writeBit8u(checksum))
- return false;
-
- //End of sysex
- if (!file->writeBit8u(0xF7))
- return false;
- return true;
-}
-
-int Synth::dumpTimbres(const char *filename, int start, int len) {
- File *file = openFile(filename, File::OpenMode_write);
- if (file == NULL)
- return -1;
-
- for (int timbreNum = start; timbreNum < start + len; timbreNum++) {
- int useaddr = (timbreNum - start) * 256;
- TimbreParam *timbre = &mt32ram.timbres[timbreNum].timbre;
- if (!dumpTimbre(file, timbre, useaddr))
- break;
- }
- closeFile(file);
- return 0;
-}
-
-void ProduceOutput1(Bit16s *useBuf, Bit16s *stream, Bit32u len, Bit16s volume) {
-#if MT32EMU_USE_MMX > 2
- //FIXME:KG: This appears to introduce crackle
- int donelen = i386_produceOutput1(useBuf, stream, len, volume);
- len -= donelen;
- stream += donelen * 2;
- useBuf += donelen * 2;
-#endif
- int end = len * 2;
- while (end--) {
- *stream = *stream + (Bit16s)(((Bit32s)*useBuf++ * (Bit32s)volume)>>15);
- stream++;
- }
-}
-
-void Synth::render(Bit16s *stream, Bit32u len) {
- memset(stream, 0, len * sizeof (Bit16s) * 2);
- if (!isEnabled)
- return;
- while (len > 0) {
- Bit32u thisLen = len > MAX_SAMPLE_OUTPUT ? MAX_SAMPLE_OUTPUT : len;
- doRender(stream, thisLen);
- len -= thisLen;
- stream += 2 * thisLen;
- }
-}
-
-void Synth::doRender(Bit16s *stream, Bit32u len) {
- partialManager->ageAll();
-
- if (myProp.useReverb) {
- for (unsigned int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (partialManager->shouldReverb(i)) {
- if (partialManager->produceOutput(i, &tmpBuffer[0], len)) {
- ProduceOutput1(&tmpBuffer[0], stream, len, masterVolume);
- }
- }
- }
- Bit32u m = 0;
- for (unsigned int i = 0; i < len; i++) {
- sndbufl[i] = (float)stream[m] / 32767.0f;
- m++;
- sndbufr[i] = (float)stream[m] / 32767.0f;
- m++;
- }
- reverbModel->processreplace(sndbufl, sndbufr, outbufl, outbufr, len, 1);
- m=0;
- for (unsigned int i = 0; i < len; i++) {
- stream[m] = (Bit16s)(outbufl[i] * 32767.0f);
- m++;
- stream[m] = (Bit16s)(outbufr[i] * 32767.0f);
- m++;
- }
- for (unsigned int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (!partialManager->shouldReverb(i)) {
- if (partialManager->produceOutput(i, &tmpBuffer[0], len)) {
- ProduceOutput1(&tmpBuffer[0], stream, len, masterVolume);
- }
- }
- }
- } else {
- for (unsigned int i = 0; i < MT32EMU_MAX_PARTIALS; i++) {
- if (partialManager->produceOutput(i, &tmpBuffer[0], len))
- ProduceOutput1(&tmpBuffer[0], stream, len, masterVolume);
- }
- }
-
- partialManager->clearAlreadyOutputed();
-
-#if MT32EMU_MONITOR_PARTIALS == 1
- samplepos += len;
- if (samplepos > myProp.SampleRate * 5) {
- samplepos = 0;
- int partialUsage[9];
- partialManager->GetPerPartPartialUsage(partialUsage);
- printDebug("1:%02d 2:%02d 3:%02d 4:%02d 5:%02d 6:%02d 7:%02d 8:%02d", partialUsage[0], partialUsage[1], partialUsage[2], partialUsage[3], partialUsage[4], partialUsage[5], partialUsage[6], partialUsage[7]);
- printDebug("Rhythm: %02d TOTAL: %02d", partialUsage[8], MT32EMU_MAX_PARTIALS - partialManager->GetFreePartialCount());
- }
-#endif
-}
-
-const Partial *Synth::getPartial(unsigned int partialNum) const {
- return partialManager->getPartial(partialNum);
-}
-
-const Part *Synth::getPart(unsigned int partNum) const {
- if (partNum > 8)
- return NULL;
- return parts[partNum];
-}
-
-}
diff --git a/engines/sci/sfx/softseq/mt32/synth.h b/engines/sci/sfx/softseq/mt32/synth.h
deleted file mode 100644
index 9d57c8d3cd..0000000000
--- a/engines/sci/sfx/softseq/mt32/synth.h
+++ /dev/null
@@ -1,300 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef MT32EMU_SYNTH_H
-#define MT32EMU_SYNTH_H
-
-#include <stdarg.h>
-
-class revmodel;
-
-namespace MT32Emu {
-
-class File;
-class TableInitialiser;
-class Partial;
-class PartialManager;
-class Part;
-
-enum ReportType {
- // Errors
- ReportType_errorControlROM = 1,
- ReportType_errorPCMROM,
- ReportType_errorSampleRate,
-
- // Progress
- ReportType_progressInit,
-
- // HW spec
- ReportType_availableSSE,
- ReportType_available3DNow,
- ReportType_usingSSE,
- ReportType_using3DNow,
-
- // General info
- ReportType_lcdMessage,
- ReportType_devReset,
- ReportType_devReconfig,
- ReportType_newReverbMode,
- ReportType_newReverbTime,
- ReportType_newReverbLevel
-};
-
-struct SynthProperties {
- // Sample rate to use in mixing
- int sampleRate;
-
- // Flag to activate reverb. True = use reverb, False = no reverb
- bool useReverb;
- // True to use software set reverb settings, False to set reverb settings in
- // following parameters
- bool useDefaultReverb;
- // When not using the default settings, this specifies one of the 4 reverb types
- // 1 = Room 2 = Hall 3 = Plate 4 = Tap
- unsigned char reverbType;
- // This specifies the delay time, from 0-7 (not sure of the actual MT-32's measurement)
- unsigned char reverbTime;
- // This specifies the reverb level, from 0-7 (not sure of the actual MT-32's measurement)
- unsigned char reverbLevel;
- // The name of the directory in which the ROM and data files are stored (with trailing slash/backslash)
- // Not used if "openFile" is set. May be NULL in any case.
- char *baseDir;
- // This is used as the first argument to all callbacks
- void *userData;
- // Callback for reporting various errors and information. May be NULL
- int (*report)(void *userData, ReportType type, const void *reportData);
- // Callback for debug messages, in vprintf() format
- void (*printDebug)(void *userData, const char *fmt, va_list list);
- // Callback for providing an implementation of File, opened and ready for use
- // May be NULL, in which case a default implementation will be used.
- File *(*openFile)(void *userData, const char *filename, File::OpenMode mode);
- // Callback for closing a File. May be NULL, in which case the File will automatically be close()d/deleted.
- void (*closeFile)(void *userData, File *file);
-};
-
-// This is the specification of the Callback routine used when calling the RecalcWaveforms
-// function
-typedef void (*recalcStatusCallback)(int percDone);
-
-// This external function recreates the base waveform file (waveforms.raw) using a specifed
-// sampling rate. The callback routine provides interactivity to let the user know what
-// percentage is complete in regenerating the waveforms. When a NULL pointer is used as the
-// callback routine, no status is reported.
-bool RecalcWaveforms(char * baseDir, int sampRate, recalcStatusCallback callBack);
-
-typedef float (*iir_filter_type)(float input,float *hist1_ptr, float *coef_ptr);
-
-const Bit8u SYSEX_MANUFACTURER_ROLAND = 0x41;
-
-const Bit8u SYSEX_MDL_MT32 = 0x16;
-const Bit8u SYSEX_MDL_D50 = 0x14;
-
-const Bit8u SYSEX_CMD_RQ1 = 0x11; // Request data #1
-const Bit8u SYSEX_CMD_DT1 = 0x12; // Data set 1
-const Bit8u SYSEX_CMD_WSD = 0x40; // Want to send data
-const Bit8u SYSEX_CMD_RQD = 0x41; // Request data
-const Bit8u SYSEX_CMD_DAT = 0x42; // Data set
-const Bit8u SYSEX_CMD_ACK = 0x43; // Acknowledge
-const Bit8u SYSEX_CMD_EOD = 0x45; // End of data
-const Bit8u SYSEX_CMD_ERR = 0x4E; // Communications error
-const Bit8u SYSEX_CMD_RJC = 0x4F; // Rejection
-
-const unsigned int CONTROL_ROM_SIZE = 64 * 1024;
-
-struct ControlROMPCMStruct
-{
- Bit8u pos;
- Bit8u len;
- Bit8u pitchLSB;
- Bit8u pitchMSB;
-};
-
-struct ControlROMMap {
- Bit16u idPos;
- Bit16u idLen;
- const char *idBytes;
- Bit16u pcmTable;
- Bit16u pcmCount;
- Bit16u timbreAMap;
- Bit16u timbreAOffset;
- Bit16u timbreBMap;
- Bit16u timbreBOffset;
- Bit16u timbreRMap;
- Bit16u timbreRCount;
- Bit16u rhythmSettings;
- Bit16u rhythmSettingsCount;
- Bit16u reserveSettings;
- Bit16u panSettings;
- Bit16u programSettings;
-};
-
-enum MemoryRegionType {
- MR_PatchTemp, MR_RhythmTemp, MR_TimbreTemp, MR_Patches, MR_Timbres, MR_System, MR_Display, MR_Reset
-};
-
-class MemoryRegion {
-public:
- MemoryRegionType type;
- Bit32u startAddr, entrySize, entries;
-
- int lastTouched(Bit32u addr, Bit32u len) const {
- return (offset(addr) + len - 1) / entrySize;
- }
- int firstTouchedOffset(Bit32u addr) const {
- return offset(addr) % entrySize;
- }
- int firstTouched(Bit32u addr) const {
- return offset(addr) / entrySize;
- }
- Bit32u regionEnd() const {
- return startAddr + entrySize * entries;
- }
- bool contains(Bit32u addr) const {
- return addr >= startAddr && addr < regionEnd();
- }
- int offset(Bit32u addr) const {
- return addr - startAddr;
- }
- Bit32u getClampedLen(Bit32u addr, Bit32u len) const {
- if (addr + len > regionEnd())
- return regionEnd() - addr;
- return len;
- }
- Bit32u next(Bit32u addr, Bit32u len) const {
- if (addr + len > regionEnd()) {
- return regionEnd() - addr;
- }
- return 0;
- }
-};
-
-
-class Synth {
-friend class Part;
-friend class RhythmPart;
-friend class Partial;
-friend class Tables;
-private:
- bool isEnabled;
-
- iir_filter_type iirFilter;
-
- PCMWaveEntry *pcmWaves; // Array
-
- const ControlROMMap *controlROMMap;
- Bit8u controlROMData[CONTROL_ROM_SIZE];
- Bit16s *pcmROMData;
- int pcmROMSize; // This is in 16-bit samples, therefore half the number of bytes in the ROM
-
- Bit8s chantable[32];
-
- #if MT32EMU_MONITOR_PARTIALS == 1
- static Bit32s samplepos = 0;
- #endif
-
- Tables tables;
-
- MemParams mt32ram, mt32default;
-
- revmodel *reverbModel;
-
- float masterTune;
- Bit16u masterVolume;
-
- bool isOpen;
-
- PartialManager *partialManager;
- Part *parts[9];
-
- Bit16s tmpBuffer[MAX_SAMPLE_OUTPUT * 2];
- float sndbufl[MAX_SAMPLE_OUTPUT];
- float sndbufr[MAX_SAMPLE_OUTPUT];
- float outbufl[MAX_SAMPLE_OUTPUT];
- float outbufr[MAX_SAMPLE_OUTPUT];
-
- SynthProperties myProp;
-
- bool loadPreset(File *file);
- void initReverb(Bit8u newRevMode, Bit8u newRevTime, Bit8u newRevLevel);
- void doRender(Bit16s * stream, Bit32u len);
-
- void playAddressedSysex(unsigned char channel, const Bit8u *sysex, Bit32u len);
- void readSysex(unsigned char channel, const Bit8u *sysex, Bit32u len);
- void writeMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u len, const Bit8u *data);
- void readMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u len, Bit8u *data);
-
- bool loadControlROM(const char *filename);
- bool loadPCMROM(const char *filename);
- bool dumpTimbre(File *file, const TimbreParam *timbre, Bit32u addr);
- int dumpTimbres(const char *filename, int start, int len);
-
- bool initPCMList(Bit16u mapAddress, Bit16u count);
- bool initRhythmTimbres(Bit16u mapAddress, Bit16u count);
- bool initTimbres(Bit16u mapAddress, Bit16u offset, int startTimbre);
- bool initRhythmTimbre(int drumNum, const Bit8u *mem, unsigned int memLen);
- bool refreshSystem();
-
-protected:
- int report(ReportType type, const void *reportData);
- File *openFile(const char *filename, File::OpenMode mode);
- void closeFile(File *file);
- void printDebug(const char *fmt, ...);
-
-public:
- static Bit8u calcSysexChecksum(const Bit8u *data, Bit32u len, Bit8u checksum);
-
- Synth();
- ~Synth();
-
- // Used to initialise the MT-32. Must be called before any other function.
- // Returns true if initialization was sucessful, otherwise returns false.
- bool open(SynthProperties &useProp);
-
- // Closes the MT-32 and deallocates any memory used by the synthesizer
- void close(void);
-
- // Sends a 4-byte MIDI message to the MT-32 for immediate playback
- void playMsg(Bit32u msg);
- void playMsgOnPart(unsigned char part, unsigned char code, unsigned char note, unsigned char velocity);
-
- // Sends a string of Sysex commands to the MT-32 for immediate interpretation
- // The length is in bytes
- void playSysex(const Bit8u *sysex, Bit32u len);
- void playSysexWithoutFraming(const Bit8u *sysex, Bit32u len);
- void playSysexWithoutHeader(unsigned char device, unsigned char command, const Bit8u *sysex, Bit32u len);
- void writeSysex(unsigned char channel, const Bit8u *sysex, Bit32u len);
-
- // This callback routine is used to have the MT-32 generate samples to the specified
- // output stream. The length is in whole samples, not bytes. (I.E. in 16-bit stereo,
- // one sample is 4 bytes)
- void render(Bit16s * stream, Bit32u len);
-
- const Partial *getPartial(unsigned int partialNum) const;
-
- void readMemory(Bit32u addr, Bit32u len, Bit8u *data);
-
- // partNum should be 0..7 for Part 1..8, or 8 for Rhythm
- const Part *getPart(unsigned int partNum) const;
-};
-
-}
-
-#endif
diff --git a/engines/sci/sfx/softseq/mt32/tables.cpp b/engines/sci/sfx/softseq/mt32/tables.cpp
deleted file mode 100644
index 4591ea22e3..0000000000
--- a/engines/sci/sfx/softseq/mt32/tables.cpp
+++ /dev/null
@@ -1,749 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-#include "mt32emu.h"
-
-#ifdef MACOSX
-// Older versions of Mac OS X didn't supply a powf function. To ensure
-// binary compatibility, we force using pow instead of powf (the only
-// potential drawback is that it might be a little bit slower).
-#define powf pow
-#endif
-
-#define FIXEDPOINT_MAKE(x, point) ((Bit32u)((1 << point) * x))
-
-namespace MT32Emu {
-
-//Amplitude time velocity follow exponential coefficients
-static const double tvcatconst[5] = {0.0, 0.002791309, 0.005942882, 0.012652792, 0.026938637};
-static const double tvcatmult[5] = {1.0, 1.072662811, 1.169129367, 1.288579123, 1.229630539};
-
-// These are division constants for the TVF depth key follow
-static const Bit32u depexp[5] = {3000, 950, 485, 255, 138};
-
-//Envelope time keyfollow exponential coefficients
-static const double tkcatconst[5] = {0.0, 0.005853144, 0.011148054, 0.019086143, 0.043333215};
-static const double tkcatmult[5] = {1.0, 1.058245688, 1.048488989, 1.016049301, 1.097538067};
-
-// Begin filter stuff
-
-// Pre-warp the coefficients of a numerator or denominator.
-// Note that a0 is assumed to be 1, so there is no wrapping
-// of it.
-static void prewarp(double *a1, double *a2, double fc, double fs) {
- double wp;
-
- wp = 2.0 * fs * tan(DOUBLE_PI * fc / fs);
-
- *a2 = *a2 / (wp * wp);
- *a1 = *a1 / wp;
-}
-
-// Transform the numerator and denominator coefficients
-// of s-domain biquad section into corresponding
-// z-domain coefficients.
-//
-// Store the 4 IIR coefficients in array pointed by coef
-// in following order:
-// beta1, beta2 (denominator)
-// alpha1, alpha2 (numerator)
-//
-// Arguments:
-// a0-a2 - s-domain numerator coefficients
-// b0-b2 - s-domain denominator coefficients
-// k - filter gain factor. initially set to 1
-// and modified by each biquad section in such
-// a way, as to make it the coefficient by
-// which to multiply the overall filter gain
-// in order to achieve a desired overall filter gain,
-// specified in initial value of k.
-// fs - sampling rate (Hz)
-// coef - array of z-domain coefficients to be filled in.
-//
-// Return:
-// On return, set coef z-domain coefficients
-static void bilinear(double a0, double a1, double a2, double b0, double b1, double b2, double *k, double fs, float *coef) {
- double ad, bd;
-
- // alpha (Numerator in s-domain)
- ad = 4. * a2 * fs * fs + 2. * a1 * fs + a0;
- // beta (Denominator in s-domain)
- bd = 4. * b2 * fs * fs + 2. * b1* fs + b0;
-
- // update gain constant for this section
- *k *= ad/bd;
-
- // Denominator
- *coef++ = (float)((2. * b0 - 8. * b2 * fs * fs) / bd); // beta1
- *coef++ = (float)((4. * b2 * fs * fs - 2. * b1 * fs + b0) / bd); // beta2
-
- // Nominator
- *coef++ = (float)((2. * a0 - 8. * a2 * fs * fs) / ad); // alpha1
- *coef = (float)((4. * a2 * fs * fs - 2. * a1 * fs + a0) / ad); // alpha2
-}
-
-// a0-a2: numerator coefficients
-// b0-b2: denominator coefficients
-// fc: Filter cutoff frequency
-// fs: sampling rate
-// k: overall gain factor
-// coef: pointer to 4 iir coefficients
-static void szxform(double *a0, double *a1, double *a2, double *b0, double *b1, double *b2, double fc, double fs, double *k, float *coef) {
- // Calculate a1 and a2 and overwrite the original values
- prewarp(a1, a2, fc, fs);
- prewarp(b1, b2, fc, fs);
- bilinear(*a0, *a1, *a2, *b0, *b1, *b2, k, fs, coef);
-}
-
-static void initFilter(float fs, float fc, float *icoeff, float Q) {
- float *coef;
- double a0, a1, a2, b0, b1, b2;
-
- double k = 1.5; // Set overall filter gain factor
- coef = icoeff + 1; // Skip k, or gain
-
- // Section 1
- a0 = 1.0;
- a1 = 0;
- a2 = 0;
- b0 = 1.0;
- b1 = 0.765367 / Q; // Divide by resonance or Q
- b2 = 1.0;
- szxform(&a0, &a1, &a2, &b0, &b1, &b2, fc, fs, &k, coef);
- coef += 4; // Point to next filter section
-
- // Section 2
- a0 = 1.0;
- a1 = 0;
- a2 = 0;
- b0 = 1.0;
- b1 = 1.847759 / Q;
- b2 = 1.0;
- szxform(&a0, &a1, &a2, &b0, &b1, &b2, fc, fs, &k, coef);
-
- icoeff[0] = (float)k;
-}
-
-void Tables::initFiltCoeff(float samplerate) {
- for (int j = 0; j < FILTERGRAN; j++) {
- for (int res = 0; res < 31; res++) {
- float tres = resonanceFactor[res];
- initFilter((float)samplerate, (((float)(j+1.0)/FILTERGRAN)) * ((float)samplerate/2), filtCoeff[j][res], tres);
- }
- }
-}
-
-void Tables::initEnvelopes(float samplerate) {
- for (int lf = 0; lf <= 100; lf++) {
- float elf = (float)lf;
-
- // General envelope
- // This formula fits observation of the CM-32L by +/- 0.03s or so for the second time value in the filter,
- // when all other times were 0 and all levels were 100. Note that variations occur depending on the level
- // delta of the section, which we're not fully emulating.
- float seconds = powf(2.0f, (elf / 8.0f) + 7.0f) / 32768.0f;
- int samples = (int)(seconds * samplerate);
- envTime[lf] = samples;
-
- // Cap on envelope times depending on the level delta
- if (elf == 0) {
- envDeltaMaxTime[lf] = 63;
- } else {
- float cap = 11.0f * (float)log(elf) + 64;
- if (cap > 100.0f) {
- cap = 100.0f;
- }
- envDeltaMaxTime[lf] = (int)cap;
- }
-
-
- // This (approximately) represents the time durations when the target level is 0.
- // Not sure why this is a special case, but it's seen to be from the real thing.
- seconds = powf(2, (elf / 8.0f) + 6) / 32768.0f;
- envDecayTime[lf] = (int)(seconds * samplerate);
-
- // I am certain of this: Verified by hand LFO log
- lfoPeriod[lf] = (Bit32u)(((float)samplerate) / (powf(1.088883372f, (float)lf) * 0.021236044f));
- }
-}
-
-void Tables::initMT32ConstantTables(Synth *synth) {
- int lf;
- synth->printDebug("Initialising Pitch Tables");
- for (lf = -108; lf <= 108; lf++) {
- tvfKeyfollowMult[lf + 108] = (int)(256 * powf(2.0f, (float)(lf / 24.0f)));
- //synth->printDebug("KT %d = %d", f, keytable[f+108]);
- }
-
- for (int res = 0; res < 31; res++) {
- resonanceFactor[res] = powf((float)res / 30.0f, 5.0f) + 1.0f;
- }
-
- int period = 65536;
-
- for (int ang = 0; ang < period; ang++) {
- int halfang = (period / 2);
- int angval = ang % halfang;
- float tval = (((float)angval / (float)halfang) - 0.5f) * 2;
- if (ang >= halfang)
- tval = -tval;
- sintable[ang] = (Bit16s)(tval * 50.0f) + 50;
- }
-
- int velt, dep;
- float tempdep;
- for (velt = 0; velt < 128; velt++) {
- for (dep = 0; dep < 5; dep++) {
- if (dep > 0) {
- float ff = (float)(exp(3.5f * tvcatconst[dep] * (59.0f - (float)velt)) * tvcatmult[dep]);
- tempdep = 256.0f * ff;
- envTimeVelfollowMult[dep][velt] = (int)tempdep;
- //if ((velt % 16) == 0) {
- // synth->printDebug("Key %d, depth %d, factor %d", velt, dep, (int)tempdep);
- //}
- } else
- envTimeVelfollowMult[dep][velt] = 256;
- }
-
- for (dep = -7; dep < 8; dep++) {
- float fldep = (float)abs(dep) / 7.0f;
- fldep = powf(fldep,2.5f);
- if (dep < 0)
- fldep = fldep * -1.0f;
- pwVelfollowAdd[dep+7][velt] = Bit32s((fldep * (float)velt * 100) / 128.0);
- }
- }
-
- for (dep = 0; dep <= 100; dep++) {
- for (velt = 0; velt < 128; velt++) {
- float fdep = (float)dep * 0.000347013f; // Another MT-32 constant
- float fv = ((float)velt - 64.0f)/7.26f;
- float flogdep = powf(10, fdep * fv);
- float fbase;
-
- if (velt > 64)
- synth->tables.tvfVelfollowMult[velt][dep] = (int)(flogdep * 256.0);
- else {
- //lff = 1 - (pow(((128.0 - (float)lf) / 64.0),.25) * ((float)velt / 96));
- fbase = 1 - (powf(((float)dep / 100.0f),.25f) * ((float)(64-velt) / 96.0f));
- synth->tables.tvfVelfollowMult[velt][dep] = (int)(fbase * 256.0);
- }
- //synth->printDebug("Filvel dep %d velt %d = %x", dep, velt, filveltable[velt][dep]);
- }
- }
-
- for (lf = 0; lf < 128; lf++) {
- float veloFract = lf / 127.0f;
- for (int velsens = 0; velsens <= 100; velsens++) {
- float sensFract = (velsens - 50) / 50.0f;
- if (velsens < 50) {
- tvaVelfollowMult[lf][velsens] = FIXEDPOINT_MAKE(1.0f / powf(2.0f, veloFract * -sensFract * 127.0f / 20.0f), 8);
- } else {
- tvaVelfollowMult[lf][velsens] = FIXEDPOINT_MAKE(1.0f / powf(2.0f, (1.0f - veloFract) * sensFract * 127.0f / 20.0f), 8);
- }
- }
- }
-
- for (lf = 0; lf <= 100; lf++) {
- // Converts the 0-100 range used by the MT-32 to volume multiplier
- volumeMult[lf] = FIXEDPOINT_MAKE(powf((float)lf / 100.0f, FLOAT_LN), 7);
- }
-
- for (lf = 0; lf <= 100; lf++) {
- float mv = lf / 100.0f;
- float pt = mv - 0.5f;
- if (pt < 0)
- pt = 0;
-
- // Original (CC version)
- //pwFactor[lf] = (int)(pt * 210.04f) + 128;
-
- // Approximation from sample comparison
- pwFactor[lf] = (int)(pt * 179.0f) + 128;
- }
-
- for (unsigned int i = 0; i < MAX_SAMPLE_OUTPUT; i++) {
- int myRand;
- myRand = rand();
- //myRand = ((myRand - 16383) * 7168) >> 16;
- // This one is slower but works with all values of RAND_MAX
- myRand = (int)((myRand - RAND_MAX / 2) / (float)RAND_MAX * (7168 / 2));
- //FIXME:KG: Original ultimately set the lowest two bits to 0, for no obvious reason
- noiseBuf[i] = (Bit16s)myRand;
- }
-
- float tdist;
- float padjtable[51];
- for (lf = 0; lf <= 50; lf++) {
- if (lf == 0)
- padjtable[lf] = 7;
- else if (lf == 1)
- padjtable[lf] = 6;
- else if (lf == 2)
- padjtable[lf] = 5;
- else if (lf == 3)
- padjtable[lf] = 4;
- else if (lf == 4)
- padjtable[lf] = 4 - (0.333333f);
- else if (lf == 5)
- padjtable[lf] = 4 - (0.333333f * 2);
- else if (lf == 6)
- padjtable[lf] = 3;
- else if ((lf > 6) && (lf <= 12)) {
- tdist = (lf-6.0f) / 6.0f;
- padjtable[lf] = 3.0f - tdist;
- } else if ((lf > 12) && (lf <= 25)) {
- tdist = (lf - 12.0f) / 13.0f;
- padjtable[lf] = 2.0f - tdist;
- } else {
- tdist = (lf - 25.0f) / 25.0f;
- padjtable[lf] = 1.0f - tdist;
- }
- //synth->printDebug("lf %d = padj %f", lf, padjtable[lf]);
- }
-
- float lfp, depf, finalval, tlf;
- int depat, pval, depti;
- for (lf = 0; lf <= 10; lf++) {
- // I believe the depth is cubed or something
-
- for (depat = 0; depat <= 100; depat++) {
- if (lf > 0) {
- depti = abs(depat - 50);
- tlf = (float)lf - padjtable[depti];
- if (tlf < 0)
- tlf = 0;
- lfp = (float)exp(0.713619942f * tlf) / 407.4945111f;
-
- if (depat < 50)
- finalval = 4096.0f * powf(2, -lfp);
- else
- finalval = 4096.0f * powf(2, lfp);
- pval = (int)finalval;
-
- pitchEnvVal[lf][depat] = pval;
- //synth->printDebug("lf %d depat %d pval %d tlf %f lfp %f", lf,depat,pval, tlf, lfp);
- } else {
- pitchEnvVal[lf][depat] = 4096;
- //synth->printDebug("lf %d depat %d pval 4096", lf, depat);
- }
- }
- }
- for (lf = 0; lf <= 100; lf++) {
- // It's linear - verified on MT-32 - one of the few things linear
- lfp = ((float)lf * 0.1904f) / 310.55f;
-
- for (depat = 0; depat <= 100; depat++) {
- depf = ((float)depat - 50.0f) / 50.0f;
- //finalval = pow(2, lfp * depf * .5);
- finalval = 4096.0f + (4096.0f * lfp * depf);
-
- pval = (int)finalval;
-
- lfoShift[lf][depat] = pval;
-
- //synth->printDebug("lf %d depat %d pval %x", lf,depat,pval);
- }
- }
-
- for (lf = 0; lf <= 12; lf++) {
- for (int distval = 0; distval < 128; distval++) {
- float amplog, dval;
- if (lf == 0) {
- amplog = 0;
- dval = 1;
- tvaBiasMult[lf][distval] = 256;
- } else {
- /*
- amplog = powf(1.431817011f, (float)lf) / FLOAT_PI;
- dval = ((128.0f - (float)distval) / 128.0f);
- amplog = exp(amplog);
- dval = powf(amplog, dval) / amplog;
- tvaBiasMult[lf][distval] = (int)(dval * 256.0);
- */
- // Lets assume for a second it's linear
-
- // Distance of full volume reduction
- amplog = (float)(12.0f / (float)lf) * 24.0f;
- if (distval > amplog) {
- tvaBiasMult[lf][distval] = 0;
- } else {
- dval = (amplog - (float)distval) / amplog;
- tvaBiasMult[lf][distval] = (int)(dval * 256.0f);
- }
- }
- //synth->printDebug("Ampbias lf %d distval %d = %f (%x) %f", lf, distval, dval, tvaBiasMult[lf][distval],amplog);
- }
- }
-
- for (lf = 0; lf <= 14; lf++) {
- for (int distval = 0; distval < 128; distval++) {
- float filval = fabsf((float)((lf - 7) * 12) / 7.0f);
- float amplog, dval;
- if (lf == 7) {
- amplog = 0;
- dval = 1;
- tvfBiasMult[lf][distval] = 256;
- } else {
- //amplog = pow(1.431817011, filval) / FLOAT_PI;
- amplog = powf(1.531817011f, filval) / FLOAT_PI;
- dval = (128.0f - (float)distval) / 128.0f;
- amplog = (float)exp(amplog);
- dval = powf(amplog,dval)/amplog;
- if (lf < 8) {
- tvfBiasMult[lf][distval] = (int)(dval * 256.0f);
- } else {
- dval = powf(dval, 0.3333333f);
- if (dval < 0.01f)
- dval = 0.01f;
- dval = 1 / dval;
- tvfBiasMult[lf][distval] = (int)(dval * 256.0f);
- }
- }
- //synth->printDebug("Fbias lf %d distval %d = %f (%x) %f", lf, distval, dval, tvfBiasMult[lf][distval],amplog);
- }
- }
-}
-
-// Per-note table initialisation follows
-
-static void initSaw(NoteLookup *noteLookup, Bit32s div2) {
- int tmpdiv = div2 << 16;
- for (int rsaw = 0; rsaw <= 100; rsaw++) {
- float fsaw;
- if (rsaw < 50)
- fsaw = 50.0f;
- else
- fsaw = (float)rsaw;
-
- //(66 - (((A8 - 50) / 50) ^ 0.63) * 50) / 132
- float sawfact = (66.0f - (powf((fsaw - 50.0f) / 50.0f, 0.63f) * 50.0f)) / 132.0f;
- noteLookup->sawTable[rsaw] = (int)(sawfact * (float)tmpdiv) >> 16;
- //synth->printDebug("F %d divtable %d saw %d sawtable %d", f, div, rsaw, sawtable[f][rsaw]);
- }
-}
-
-static void initDep(KeyLookup *keyLookup, float f) {
- for (int dep = 0; dep < 5; dep++) {
- if (dep == 0) {
- keyLookup->envDepthMult[dep] = 256;
- keyLookup->envTimeMult[dep] = 256;
- } else {
- float depfac = 3000.0f;
- float ff, tempdep;
- depfac = (float)depexp[dep];
-
- ff = (f - (float)MIDDLEC) / depfac;
- tempdep = powf(2, ff) * 256.0f;
- keyLookup->envDepthMult[dep] = (int)tempdep;
-
- ff = (float)(exp(tkcatconst[dep] * ((float)MIDDLEC - f)) * tkcatmult[dep]);
- keyLookup->envTimeMult[dep] = (int)(ff * 256.0f);
- }
- }
- //synth->printDebug("F %f d1 %x d2 %x d3 %x d4 %x d5 %x", f, noteLookup->fildepTable[0], noteLookup->fildepTable[1], noteLookup->fildepTable[2], noteLookup->fildepTable[3], noteLookup->fildepTable[4]);
-}
-
-Bit16s Tables::clampWF(Synth *synth, const char *n, float ampVal, double input) {
- Bit32s x = (Bit32s)(input * ampVal);
- if (x < -ampVal - 1) {
- synth->printDebug("%s==%d<-WGAMP-1!", n, x);
- x = (Bit32s)(-ampVal - 1);
- } else if (x > ampVal) {
- synth->printDebug("%s==%d>WGAMP!", n, x);
- x = (Bit32s)ampVal;
- }
- return (Bit16s)x;
-}
-
-File *Tables::initWave(Synth *synth, NoteLookup *noteLookup, float ampVal, float div2, File *file) {
- int iDiv2 = (int)div2;
- noteLookup->waveformSize[0] = iDiv2 << 1;
- noteLookup->waveformSize[1] = iDiv2 << 1;
- noteLookup->waveformSize[2] = iDiv2 << 2;
- for (int i = 0; i < 3; i++) {
- if (noteLookup->waveforms[i] == NULL) {
- noteLookup->waveforms[i] = new Bit16s[noteLookup->waveformSize[i]];
- }
- }
- if (file != NULL) {
- for (int i = 0; i < 3 && file != NULL; i++) {
- size_t len = noteLookup->waveformSize[i];
- for (unsigned int j = 0; j < len; j++) {
- if (!file->readBit16u((Bit16u *)&noteLookup->waveforms[i][j])) {
- synth->printDebug("Error reading wave file cache!");
- file->close();
- file = NULL;
- break;
- }
- }
- }
- }
- if (file == NULL) {
- double sd = DOUBLE_PI / div2;
-
- for (int fa = 0; fa < (iDiv2 << 1); fa++) {
- // sa ranges from 0 to 2PI
- double sa = fa * sd;
-
- // Calculate a sample for the bandlimited sawtooth wave
- double saw = 0.0;
- int sincs = iDiv2 >> 1;
- double sinus = 1.0;
- for (int sincNum = 1; sincNum <= sincs; sincNum++) {
- saw += sin(sinus * sa) / sinus;
- sinus++;
- }
-
- // This works pretty well
- // Multiplied by 0.84 so that the spikes caused by bandlimiting don't overdrive the amplitude
- noteLookup->waveforms[0][fa] = clampWF(synth, "saw", ampVal, -saw / (0.5 * DOUBLE_PI) * 0.84);
- noteLookup->waveforms[1][fa] = clampWF(synth, "cos", ampVal, -cos(sa / 2.0));
- noteLookup->waveforms[2][fa * 2] = clampWF(synth, "cosoff_0", ampVal, -cos(sa - DOUBLE_PI));
- noteLookup->waveforms[2][fa * 2 + 1] = clampWF(synth, "cosoff_1", ampVal, -cos((sa + (sd / 2)) - DOUBLE_PI));
- }
- }
- return file;
-}
-
-static void initFiltTable(NoteLookup *noteLookup, float freq, float rate) {
- for (int tr = 0; tr <= 200; tr++) {
- float ftr = (float)tr;
-
- // Verified exact on MT-32
- if (tr > 100)
- ftr = 100.0f + (powf((ftr - 100.0f) / 100.0f, 3.0f) * 100.0f);
-
- // I think this is the one
- float brsq = powf(10.0f, (tr / 50.0f) - 1.0f);
- noteLookup->filtTable[0][tr] = (int)((freq * brsq) / (rate / 2) * FILTERGRAN);
- if (noteLookup->filtTable[0][tr]>=((FILTERGRAN*15)/16))
- noteLookup->filtTable[0][tr] = ((FILTERGRAN*15)/16);
-
- float brsa = powf(10.0f, ((tr / 55.0f) - 1.0f)) / 2.0f;
- noteLookup->filtTable[1][tr] = (int)((freq * brsa) / (rate / 2) * FILTERGRAN);
- if (noteLookup->filtTable[1][tr]>=((FILTERGRAN*15)/16))
- noteLookup->filtTable[1][tr] = ((FILTERGRAN*15)/16);
- }
-}
-
-static void initNFiltTable(NoteLookup *noteLookup, float freq, float rate) {
- for (int cf = 0; cf <= 100; cf++) {
- float cfmult = (float)cf;
-
- for (int tf = 0;tf <= 100; tf++) {
- float tfadd = (float)tf;
-
- //float freqsum = exp((cfmult + tfadd) / 30.0f) / 4.0f;
- //float freqsum = 0.15f * exp(0.45f * ((cfmult + tfadd) / 10.0f));
-
- float freqsum = powf(2.0f, ((cfmult + tfadd) - 40.0f) / 16.0f);
-
- noteLookup->nfiltTable[cf][tf] = (int)((freq * freqsum) / (rate / 2) * FILTERGRAN);
- if (noteLookup->nfiltTable[cf][tf] >= ((FILTERGRAN * 15) / 16))
- noteLookup->nfiltTable[cf][tf] = ((FILTERGRAN * 15) / 16);
- }
- }
-}
-
-File *Tables::initNote(Synth *synth, NoteLookup *noteLookup, float note, float rate, float masterTune, PCMWaveEntry *pcmWaves, File *file) {
- float freq = (float)(masterTune * pow(2.0, ((double)note - MIDDLEA) / 12.0));
- float div2 = rate * 2.0f / freq;
- noteLookup->div2 = (int)div2;
-
- if (noteLookup->div2 == 0)
- noteLookup->div2 = 1;
-
- initSaw(noteLookup, noteLookup->div2);
-
- //synth->printDebug("Note %f; freq=%f, div=%f", note, freq, rate / freq);
- file = initWave(synth, noteLookup, (const float)WGAMP, div2, file);
-
- // Create the pitch tables
- if (noteLookup->wavTable == NULL)
- noteLookup->wavTable = new Bit32u[synth->controlROMMap->pcmCount];
- double rateMult = 32000.0 / rate;
- double tuner = freq * 65536.0f;
- for (int pc = 0; pc < synth->controlROMMap->pcmCount; pc++) {
- noteLookup->wavTable[pc] = (int)(tuner / pcmWaves[pc].tune * rateMult);
- }
-
- initFiltTable(noteLookup, freq, rate);
- initNFiltTable(noteLookup, freq, rate);
- return file;
-}
-
-bool Tables::initNotes(Synth *synth, PCMWaveEntry *pcmWaves, float rate, float masterTune) {
- const char *NoteNames[12] = {
- "C ", "C#", "D ", "D#", "E ", "F ", "F#", "G ", "G#", "A ", "A#", "B "
- };
- char filename[64];
- int intRate = (int)rate;
- char version[4] = {0, 0, 0, 5};
- sprintf(filename, "waveformcache-%d-%.2f.raw", intRate, masterTune);
-
- File *file = NULL;
- char header[20];
- strncpy(header, "MT32WAVE", 8);
- int pos = 8;
- // Version...
- for (int i = 0; i < 4; i++)
- header[pos++] = version[i];
- header[pos++] = (char)((intRate >> 24) & 0xFF);
- header[pos++] = (char)((intRate >> 16) & 0xFF);
- header[pos++] = (char)((intRate >> 8) & 0xFF);
- header[pos++] = (char)(intRate & 0xFF);
- int intTuning = (int)masterTune;
- header[pos++] = (char)((intTuning >> 8) & 0xFF);
- header[pos++] = (char)(intTuning & 0xFF);
- header[pos++] = 0;
- header[pos] = (char)((masterTune - intTuning) * 10);
-#if MT32EMU_WAVECACHEMODE < 2
- bool reading = false;
- file = synth->openFile(filename, File::OpenMode_read);
- if (file != NULL) {
- char fileHeader[20];
- if (file->read(fileHeader, 20) == 20) {
- if (memcmp(fileHeader, header, 20) == 0) {
- Bit16u endianCheck;
- if (file->readBit16u(&endianCheck)) {
- if (endianCheck == 1) {
- reading = true;
- } else {
- synth->printDebug("Endian check in %s does not match expected", filename);
- }
- } else {
- synth->printDebug("Unable to read endian check in %s", filename);
- }
- } else {
- synth->printDebug("Header of %s does not match expected", filename);
- }
- } else {
- synth->printDebug("Error reading 16 bytes of %s", filename);
- }
- if (!reading) {
- file->close();
- file = NULL;
- }
- } else {
- synth->printDebug("Unable to open %s for reading", filename);
- }
-#endif
-
- float progress = 0.0f;
- bool abort = false;
- synth->report(ReportType_progressInit, &progress);
- for (int f = LOWEST_NOTE; f <= HIGHEST_NOTE; f++) {
- synth->printDebug("Initialising note %s%d", NoteNames[f % 12], (f / 12) - 2);
- NoteLookup *noteLookup = &noteLookups[f - LOWEST_NOTE];
- file = initNote(synth, noteLookup, (float)f, rate, masterTune, pcmWaves, file);
- progress = (f - LOWEST_NOTE + 1) / (float)NUM_NOTES;
- abort = synth->report(ReportType_progressInit, &progress) != 0;
- if (abort)
- break;
- }
-
-#if MT32EMU_WAVECACHEMODE == 0 || MT32EMU_WAVECACHEMODE == 2
- if (file == NULL) {
- file = synth->openFile(filename, File::OpenMode_write);
- if (file != NULL) {
- if (file->write(header, 20) == 20 && file->writeBit16u(1)) {
- for (int f = 0; f < NUM_NOTES; f++) {
- for (int i = 0; i < 3 && file != NULL; i++) {
- int len = noteLookups[f].waveformSize[i];
- for (int j = 0; j < len; j++) {
- if (!file->writeBit16u(noteLookups[f].waveforms[i][j])) {
- synth->printDebug("Error writing waveform cache file");
- file->close();
- file = NULL;
- break;
- }
- }
- }
- }
- } else {
- synth->printDebug("Error writing 16-byte header to %s - won't continue saving", filename);
- }
- } else {
- synth->printDebug("Unable to open %s for writing - won't be created", filename);
- }
- }
-#endif
-
- if (file != NULL)
- synth->closeFile(file);
- return !abort;
-}
-
-void Tables::freeNotes() {
- for (int t = 0; t < 3; t++) {
- for (int m = 0; m < NUM_NOTES; m++) {
- if (noteLookups[m].waveforms[t] != NULL) {
- delete[] noteLookups[m].waveforms[t];
- noteLookups[m].waveforms[t] = NULL;
- noteLookups[m].waveformSize[t] = 0;
- }
- if (noteLookups[m].wavTable != NULL) {
- delete[] noteLookups[m].wavTable;
- noteLookups[m].wavTable = NULL;
- }
- }
- }
- initialisedMasterTune = 0.0f;
-}
-
-Tables::Tables() {
- initialisedSampleRate = 0.0f;
- initialisedMasterTune = 0.0f;
- memset(&noteLookups, 0, sizeof(noteLookups));
-}
-
-bool Tables::init(Synth *synth, PCMWaveEntry *pcmWaves, float sampleRate, float masterTune) {
- if (sampleRate <= 0.0f) {
- synth->printDebug("Bad sampleRate (%d <= 0.0f)", sampleRate);
- return false;
- }
- if (initialisedSampleRate == 0.0f) {
- initMT32ConstantTables(synth);
- }
- if (initialisedSampleRate != sampleRate) {
- initFiltCoeff(sampleRate);
- initEnvelopes(sampleRate);
- for (int key = 12; key <= 108; key++) {
- initDep(&keyLookups[key - 12], (float)key);
- }
- }
- if (initialisedSampleRate != sampleRate || initialisedMasterTune != masterTune) {
- freeNotes();
- if (!initNotes(synth, pcmWaves, sampleRate, masterTune)) {
- return false;
- }
- initialisedSampleRate = sampleRate;
- initialisedMasterTune = masterTune;
- }
- return true;
-}
-
-}
diff --git a/engines/sci/sfx/softseq/mt32/tables.h b/engines/sci/sfx/softseq/mt32/tables.h
deleted file mode 100644
index d9af5114b2..0000000000
--- a/engines/sci/sfx/softseq/mt32/tables.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Copyright (c) 2003-2005 Various contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef MT32EMU_TABLES_H
-#define MT32EMU_TABLES_H
-
-namespace MT32Emu {
-
-// Mathematical constants
-const double DOUBLE_PI = 3.1415926535897932384626433832795;
-const double DOUBLE_LN = 2.3025850929940456840179914546844;
-const float FLOAT_PI = 3.1415926535897932384626433832795f;
-const float FLOAT_LN = 2.3025850929940456840179914546844f;
-
-// Filter settings
-const int FILTERGRAN = 512;
-
-// Amplitude of waveform generator
-// FIXME: This value is the amplitude possible whilst avoiding
-// overdriven values immediately after filtering when playing
-// back SQ3MT.MID. Needs to be checked.
-const int WGAMP = 12382;
-
-const int MIDDLEC = 60;
-const int MIDDLEA = 69; // By this I mean "A above middle C"
-
-// FIXME:KG: may only need to do 12 to 108
-// 12..108 is the range allowed by note on commands, but the key can be modified by pitch keyfollow
-// and adjustment for timbre pitch, so the results can be outside that range.
-// Should we move it (by octave) into the 12..108 range, or keep it in 0..127 range,
-// or something else altogether?
-const int LOWEST_NOTE = 12;
-const int HIGHEST_NOTE = 127;
-const int NUM_NOTES = HIGHEST_NOTE - LOWEST_NOTE + 1; // Number of slots for note LUT
-
-class Synth;
-
-struct NoteLookup {
- Bit32u div2;
- Bit32u *wavTable;
- Bit32s sawTable[101];
- int filtTable[2][201];
- int nfiltTable[101][101];
- Bit16s *waveforms[3];
- Bit32u waveformSize[3];
-};
-
-struct KeyLookup {
- Bit32s envTimeMult[5]; // For envelope time adjustment for key pressed
- Bit32s envDepthMult[5];
-};
-
-class Tables {
- float initialisedSampleRate;
- float initialisedMasterTune;
- void initMT32ConstantTables(Synth *synth);
- static Bit16s clampWF(Synth *synth, const char *n, float ampVal, double input);
- static File *initWave(Synth *synth, NoteLookup *noteLookup, float ampsize, float div2, File *file);
- bool initNotes(Synth *synth, PCMWaveEntry *pcmWaves, float rate, float tuning);
- void initEnvelopes(float sampleRate);
- void initFiltCoeff(float samplerate);
-public:
- // Constant LUTs
- Bit32s tvfKeyfollowMult[217];
- Bit32s tvfVelfollowMult[128][101];
- Bit32s tvfBiasMult[15][128];
- Bit32u tvaVelfollowMult[128][101];
- Bit32s tvaBiasMult[13][128];
- Bit16s noiseBuf[MAX_SAMPLE_OUTPUT];
- Bit16s sintable[65536];
- Bit32s pitchEnvVal[16][101];
- Bit32s envTimeVelfollowMult[5][128];
- Bit32s pwVelfollowAdd[15][128];
- float resonanceFactor[31];
- Bit32u lfoShift[101][101];
- Bit32s pwFactor[101];
- Bit32s volumeMult[101];
-
- // LUTs varying with sample rate
- Bit32u envTime[101];
- Bit32u envDeltaMaxTime[101];
- Bit32u envDecayTime[101];
- Bit32u lfoPeriod[101];
- float filtCoeff[FILTERGRAN][31][8];
-
- // Various LUTs for each note and key
- NoteLookup noteLookups[NUM_NOTES];
- KeyLookup keyLookups[97];
-
- Tables();
- bool init(Synth *synth, PCMWaveEntry *pcmWaves, float sampleRate, float masterTune);
- File *initNote(Synth *synth, NoteLookup *noteLookup, float note, float rate, float tuning, PCMWaveEntry *pcmWaves, File *file);
- void freeNotes();
-};
-
-}
-
-#endif