summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/i_oplmusic.c189
-rw-r--r--src/strife/am_map.c22
-rw-r--r--src/strife/d_englsh.h2
3 files changed, 102 insertions, 111 deletions
diff --git a/src/i_oplmusic.c b/src/i_oplmusic.c
index 45469dfb..4641912e 100644
--- a/src/i_oplmusic.c
+++ b/src/i_oplmusic.c
@@ -364,6 +364,7 @@ static boolean LoadInstrumentTable(void)
static opl_voice_t *GetFreeVoice(void)
{
opl_voice_t *result;
+ opl_voice_t **rover;
// None available?
@@ -379,8 +380,15 @@ static opl_voice_t *GetFreeVoice(void)
// Add to allocated list
- result->next = voice_alloced_list;
- voice_alloced_list = result;
+ rover = &voice_alloced_list;
+
+ while (*rover != NULL)
+ {
+ rover = &(*rover)->next;
+ }
+
+ *rover = result;
+ result->next = NULL;
return result;
}
@@ -507,46 +515,45 @@ static void SetVoiceInstrument(opl_voice_t *voice,
static void SetVoiceVolume(opl_voice_t *voice, unsigned int volume)
{
genmidi_voice_t *opl_voice;
+ unsigned int midi_volume;
unsigned int full_volume;
- unsigned int op_volume;
- unsigned int reg_volume;
-
+ unsigned int car_volume;
+ unsigned int mod_volume;
+
voice->note_volume = volume;
-
+
opl_voice = &voice->current_instr->voices[voice->current_instr_voice];
-
+
// Multiply note volume and channel volume to get the actual volume.
-
- full_volume = (volume_mapping_table[voice->note_volume]
- * volume_mapping_table[voice->channel->volume]
- * volume_mapping_table[current_music_volume]) / (127 * 127);
-
- // The volume of each instrument can be controlled via GENMIDI:
-
- op_volume = 0x3f - opl_voice->carrier.level;
-
+
+ midi_volume = 2 * (volume_mapping_table[(voice->channel->volume
+ * current_music_volume) / 127] + 1);
+
+ full_volume = (volume_mapping_table[voice->note_volume] * midi_volume) >> 9;
+
// The volume value to use in the register:
-
- reg_volume = (op_volume * full_volume) / 128;
- reg_volume = (0x3f - reg_volume) | opl_voice->carrier.scale;
-
+ car_volume = 0x3f - full_volume;
+
// Update the volume register(s) if necessary.
-
- if (reg_volume != voice->reg_volume)
+
+ if (car_volume != voice->reg_volume)
{
- voice->reg_volume = reg_volume;
-
- OPL_WriteRegister(OPL_REGS_LEVEL + voice->op2, reg_volume);
-
+ voice->reg_volume = car_volume | (opl_voice->carrier.scale & 0xc0);
+
+ OPL_WriteRegister(OPL_REGS_LEVEL + voice->op2, voice->reg_volume);
+
// If we are using non-modulated feedback mode, we must set the
// volume for both voices.
- // Note that the same register volume value is written for
- // both voices, always calculated from the carrier's level
- // value.
-
- if ((opl_voice->feedback & 0x01) != 0)
+
+ if ((opl_voice->feedback & 0x01) != 0 && opl_voice->modulator.level != 0x3f)
{
- OPL_WriteRegister(OPL_REGS_LEVEL + voice->op1, reg_volume);
+ mod_volume = 0x3f - opl_voice->modulator.level;
+ if (mod_volume >= car_volume)
+ {
+ mod_volume = car_volume;
+ }
+ OPL_WriteRegister(OPL_REGS_LEVEL + voice->op1,
+ mod_volume | (opl_voice->modulator.scale & 0xc0));
}
}
}
@@ -602,6 +609,26 @@ static void VoiceKeyOff(opl_voice_t *voice)
OPL_WriteRegister(OPL_REGS_FREQ_2 + voice->index, voice->freq >> 8);
}
+static opl_channel_data_t *TrackChannelForEvent(opl_track_data_t *track,
+ midi_event_t *event)
+{
+ unsigned int channel_num = event->data.channel.channel;
+
+ // MIDI uses track #9 for percussion, but for MUS it's track #15
+ // instead. Because DMX works on MUS data internally, we need to
+ // swap back to the MUS version of the channel number.
+ if (channel_num == 9)
+ {
+ channel_num = 15;
+ }
+ else if (channel_num == 15)
+ {
+ channel_num = 9;
+ }
+
+ return &track->channels[channel_num];
+}
+
// Get the frequency that we should be using for a voice.
static void KeyOffEvent(opl_track_data_t *track, midi_event_t *event)
@@ -617,7 +644,7 @@ static void KeyOffEvent(opl_track_data_t *track, midi_event_t *event)
event->data.channel.param2);
*/
- channel = &track->channels[event->data.channel.channel];
+ channel = TrackChannelForEvent(track, event);
key = event->data.channel.param1;
// Turn off voices being used to play this key.
@@ -636,22 +663,12 @@ static void KeyOffEvent(opl_track_data_t *track, midi_event_t *event)
}
}
-// Compare the priorities of channels, returning either -1, 0 or 1.
-
-static int CompareChannelPriorities(opl_channel_data_t *chan1,
- opl_channel_data_t *chan2)
-{
- // TODO ...
-
- return 1;
-}
-
// When all voices are in use, we must discard an existing voice to
// play a new note. Find and free an existing voice. The channel
// passed to the function is the channel for the new note to be
// played.
-static opl_voice_t *ReplaceExistingVoice(opl_channel_data_t *channel)
+static void ReplaceExistingVoice()
{
opl_voice_t *rover;
opl_voice_t *result;
@@ -664,51 +681,19 @@ static opl_voice_t *ReplaceExistingVoice(opl_channel_data_t *channel)
// than higher-numbered channels, eg. MIDI channel 1 is never
// discarded for MIDI channel 2.
- result = NULL;
+ result = voice_alloced_list;
for (rover = voice_alloced_list; rover != NULL; rover = rover->next)
{
if (rover->current_instr_voice != 0
- || (rover->channel > channel
- && CompareChannelPriorities(channel, rover->channel) > 0))
+ || rover->channel >= result->channel)
{
result = rover;
- break;
- }
- }
-
- // If we didn't find a voice, find an existing voice being used to
- // play a note on the same channel, and use that.
-
- if (result == NULL)
- {
- for (rover = voice_alloced_list; rover != NULL; rover = rover->next)
- {
- if (rover->channel == channel)
- {
- result = rover;
- break;
- }
}
}
- // Still nothing found? Give up and just use the first voice in
- // the list.
-
- if (result == NULL)
- {
- result = voice_alloced_list;
- }
-
- // Stop playing this voice playing and release it back to the free
- // list.
-
VoiceKeyOff(result);
ReleaseVoice(result);
-
- // Re-allocate the voice again and return it.
-
- return GetFreeVoice();
}
@@ -815,6 +800,7 @@ static void UpdateVoiceFrequency(opl_voice_t *voice)
static void VoiceKeyOn(opl_channel_data_t *channel,
genmidi_instr_t *instrument,
unsigned int instrument_voice,
+ unsigned int note,
unsigned int key,
unsigned int volume)
{
@@ -824,21 +810,9 @@ static void VoiceKeyOn(opl_channel_data_t *channel,
voice = GetFreeVoice();
- // If there are no more voices left, we must decide what to do.
- // If this is the first voice of the instrument, free an existing
- // voice and use that. Otherwise, if this is the second voice,
- // it isn't as important; just discard it.
-
if (voice == NULL)
{
- if (instrument_voice == 0)
- {
- voice = ReplaceExistingVoice(channel);
- }
- else
- {
- return;
- }
+ return;
}
voice->channel = channel;
@@ -853,7 +827,7 @@ static void VoiceKeyOn(opl_channel_data_t *channel,
}
else
{
- voice->note = key;
+ voice->note = note;
}
// Program the voice with the instrument data:
@@ -874,8 +848,7 @@ static void KeyOnEvent(opl_track_data_t *track, midi_event_t *event)
{
genmidi_instr_t *instrument;
opl_channel_data_t *channel;
- unsigned int key;
- unsigned int volume;
+ unsigned int note, key, volume;
/*
printf("note on: channel %i, %i, %i\n",
@@ -884,6 +857,7 @@ static void KeyOnEvent(opl_track_data_t *track, midi_event_t *event)
event->data.channel.param2);
*/
+ note = event->data.channel.param1;
key = event->data.channel.param1;
volume = event->data.channel.param2;
@@ -897,10 +871,9 @@ static void KeyOnEvent(opl_track_data_t *track, midi_event_t *event)
}
// The channel.
- channel = &track->channels[event->data.channel.channel];
-
- // Percussion channel (10) is treated differently.
+ channel = TrackChannelForEvent(track, event);
+ // Percussion channel is treated differently.
if (event->data.channel.channel == 9)
{
if (key < 35 || key > 81)
@@ -912,33 +885,39 @@ static void KeyOnEvent(opl_track_data_t *track, midi_event_t *event)
last_perc[last_perc_count] = key;
last_perc_count = (last_perc_count + 1) % PERCUSSION_LOG_LEN;
+ note = 60;
}
else
{
instrument = channel->instrument;
}
+ if (voice_free_list == NULL)
+ {
+ ReplaceExistingVoice();
+ }
+
// Find and program a voice for this instrument. If this
// is a double voice instrument, we must do this twice.
- VoiceKeyOn(channel, instrument, 0, key, volume);
+ VoiceKeyOn(channel, instrument, 0, note, key, volume);
if ((SHORT(instrument->flags) & GENMIDI_FLAG_2VOICE) != 0)
{
- VoiceKeyOn(channel, instrument, 1, key, volume);
+ VoiceKeyOn(channel, instrument, 1, note, key, volume);
}
}
static void ProgramChangeEvent(opl_track_data_t *track, midi_event_t *event)
{
- int channel;
+ opl_channel_data_t *channel;
int instrument;
// Set the instrument used on this channel.
- channel = event->data.channel.channel;
+ channel = TrackChannelForEvent(track, event);
instrument = event->data.channel.param1;
- track->channels[channel].instrument = &main_instrs[instrument];
+ channel->instrument = &main_instrs[instrument];
// TODO: Look through existing voices that are turned on on this
// channel, and change the instrument.
@@ -978,9 +957,9 @@ static void AllNotesOff(opl_channel_data_t *channel, unsigned int param)
static void ControllerEvent(opl_track_data_t *track, midi_event_t *event)
{
+ opl_channel_data_t *channel;
unsigned int controller;
unsigned int param;
- opl_channel_data_t *channel;
/*
printf("change controller: channel %i, %i, %i\n",
@@ -989,7 +968,7 @@ static void ControllerEvent(opl_track_data_t *track, midi_event_t *event)
event->data.channel.param2);
*/
- channel = &track->channels[event->data.channel.channel];
+ channel = TrackChannelForEvent(track, event);
controller = event->data.channel.param1;
param = event->data.channel.param2;
@@ -1021,7 +1000,7 @@ static void PitchBendEvent(opl_track_data_t *track, midi_event_t *event)
// Update the channel bend value. Only the MSB of the pitch bend
// value is considered: this is what Doom does.
- channel = &track->channels[event->data.channel.channel];
+ channel = TrackChannelForEvent(track, event);
channel->bend = event->data.channel.param2 - 64;
// Update all voices for this channel.
diff --git a/src/strife/am_map.c b/src/strife/am_map.c
index 9bdaea69..148fa341 100644
--- a/src/strife/am_map.c
+++ b/src/strife/am_map.c
@@ -170,7 +170,7 @@ mline_t thintriangle_guy[] = {
static int cheating = 0;
-static int grid = 0;
+//static int grid = 0; [STRIFE]: no such variable
static int leveljuststarted = 1; // kluge until AM_LevelInit() is called
@@ -322,7 +322,8 @@ void AM_addMark(void)
{
markpoints[markpointnum].x = m_x + m_w/2;
markpoints[markpointnum].y = m_y + m_h/2;
- markpointnum = (markpointnum + 1) % AM_NUMMARKPOINTS;
+ //markpointnum = (markpointnum + 1) % AM_NUMMARKPOINTS;
+ ++markpointnum; // haleyjd 20141101: [STRIFE] does not wrap around
}
@@ -653,6 +654,8 @@ AM_Responder
else
plr->message = DEH_String(AMSTR_FOLLOWOFF);
}
+ // haleyjd 20141101: [STRIFE] grid is not supported
+ /*
else if (key == key_map_grid)
{
grid = !grid;
@@ -661,17 +664,26 @@ AM_Responder
else
plr->message = DEH_String(AMSTR_GRIDOFF);
}
+ */
else if (key == key_map_mark)
{
+ // haleyjd 20141101: [STRIFE] if full, mark 9 is replaced
+ if(markpointnum == AM_NUMMARKPOINTS)
+ --markpointnum;
M_snprintf(buffer, sizeof(buffer),
- "%s %d", DEH_String(AMSTR_MARKEDSPOT), markpointnum);
+ "%s %d", DEH_String(AMSTR_MARKEDSPOT), markpointnum + 1); // [STRIFE]
plr->message = buffer;
AM_addMark();
}
else if (key == key_map_clearmark)
{
- AM_clearMarks();
- plr->message = DEH_String(AMSTR_MARKSCLEARED);
+ // haleyjd 20141101: [STRIFE] clears last mark only
+ if(markpointnum > 0)
+ {
+ markpoints[markpointnum - 1].x = -1;
+ --markpointnum;
+ plr->message = DEH_String(AMSTR_MARKSCLEARED);
+ }
}
else
{
diff --git a/src/strife/d_englsh.h b/src/strife/d_englsh.h
index 9d58e7d9..0f78f21a 100644
--- a/src/strife/d_englsh.h
+++ b/src/strife/d_englsh.h
@@ -227,7 +227,7 @@
#define AMSTR_GRIDOFF "Grid OFF"
#define AMSTR_MARKEDSPOT "Marked Spot"
-#define AMSTR_MARKSCLEARED "All Marks Cleared"
+#define AMSTR_MARKSCLEARED "Last Mark Cleared" // [STRIFE]
//
// ST_stuff.C