Files
CydandClaude Opus 4.8 4abbf8879f Initial import of Red Planet v4.10 Win32 source
Imports the current Win32 source for the pod-racing game 'Red Planet',
built on the MUNGA engine and its L4 (Win32/DirectX) platform layer:

- MUNGA / MUNGA_L4: cross-platform engine core and Win32 backend
- RP / RP_L4: Red Planet game logic and Win32 application
- DivLoader, Setup1: asset loader and installer project
- lib, MUNGA_L4/openal, MUNGA_L4/sos: third-party audio dependencies

Removed stale Subversion metadata and added .gitignore/.gitattributes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 07:59:51 -05:00

531 lines
14 KiB
C++

#pragma once
#include "..\munga\style.h"
#include "..\munga\node.h"
#include "..\munga\schain.h"
#include "..\munga\audio.h"
#include "openal/al.h"
struct SourceSet
{
int count;
ALuint sources[5];
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MIDI types ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
typedef unsigned char MIDIStatus;
typedef unsigned char MIDIChannel;
typedef unsigned char MIDIValue;
typedef int MIDIPitchBend;
typedef int MIDINRPNValue;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MIDI status ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#define MIDI_CHANNEL_COUNT (16)
#define MIDI_NOTE_OFF_STATUS ((MIDIValue)0x8) // 8
#define MIDI_NOTE_ON_STATUS ((MIDIValue)0x9) // 9
#define MIDI_POLYKEY_STATUS ((MIDIValue)0xa) // 10
#define MIDI_CONTROLLER_STATUS ((MIDIValue)0xb) // 11
#define MIDI_PROGRAM_CHANGE_STATUS ((MIDIValue)0xc) // 12
#define MIDI_CHANNEL_PRESSURE_STATUS ((MIDIValue)0xd) // 13
#define MIDI_PITCH_BEND_STATUS ((MIDIValue)0xe) // 14
//~~~~~~~~~~~~~~~~~~~~~~~~~~ MIDI controllers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#define MIDI_MAX_CONTROL_VALUE ((MIDIValue)127)
#define MIDI_MIN_CONTROL_VALUE ((MIDIValue)0)
#define MIDI_LEFT_PAN_VALUE ((MIDIValue)0)
#define MIDI_CENTER_PAN_VALUE ((MIDIValue)63)
#define MIDI_RIGHT_PAN_VALUE ((MIDIValue)127)
#define MIDI_VOLUME_CONTROL ((MIDIValue)7)
#define MIDI_PAN_CONTROL ((MIDIValue)10)
#define MIDI_REVERB_CONTROL ((MIDIValue)91)
#define MIDI_CHORUS_CONTROL ((MIDIValue)93)
#define MIDI_CONTROL_RESET ((MIDIValue)121)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MIDI notes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#define MIDI_DEFAULT_NOTE ((MIDIValue)60)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MIDI pitch ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#define MIDI_PITCH_BEND_MAX ((MIDIPitchBend)8191)
#define MIDI_PITCH_BEND_RANGE ((MIDIValue)24)
#define MIDI_PITCH_BEND_CENTS (24*100)
#define MIDI_PITCH_PER_CENTS ((Scalar)MIDI_PITCH_BEND_MAX / (Scalar)MIDI_PITCH_BEND_CENTS)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AWE NRPN ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#define AWE_VOL_ATTACK_TIME_NRPN ((MIDIValue)11)
#define AWE_PITCH_NRPN ((MIDIValue)16)
#define AWE_FILTER_CUTOFF_NRPN ((MIDIValue)21)
#define AWE_VOL_ATTACK_TIME_RANGE ((MIDINRPNValue)5940) // 0...5.9 secs
#define AWE_FILTER_CUTOFF_RANGE ((MIDINRPNValue)127) // 100...8000 Hz
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AWE effects ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
typedef enum
{
ChorusMIDIEffectType,
ReverbMIDIEffectType
} MIDIEffectType;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~ AWE resources ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#define AWE_VOICE_COUNT (32)
#define AWE_CHANNEL_COUNT (16)
#define AWE_PERCUSSIVE_CHANNEL (9)
//
// Driver type to use
//
#define _MIDI_DRIVER_TYPE _MIDI_AWE32
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MIDIMessage ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#define MIDI_MESSAGE_SIZE (3)
class MIDIMessage SIGNATURED
{
friend class AudioCard;
friend std::ostream& operator << (std::ostream &strm, const MIDIMessage &midi_message);
public:
MIDIMessage(MIDIStatus status, MIDIChannel channel, MIDIValue byte1, MIDIValue byte2 = 0);
~MIDIMessage() {}
Logical TestInstance() const;
private:
MIDIValue message[MIDI_MESSAGE_SIZE];
};
inline MIDIMessage::MIDIMessage(MIDIStatus status, MIDIChannel channel, MIDIValue byte1, MIDIValue byte2)
{
message[0] = (MIDIValue)((status << 4) | channel);
message[1] = byte1;
message[2] = byte2;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioChannel ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
typedef enum
{
InstrumentAudioChannelType = 0,
PercussionAudioChannelType
} AudioChannelType;
class AudioCard;
/*class AudioChannel : public Plug
{
public:
//
//--------------------------------------------------------------------
// Constructor, Destructor, Testing
//--------------------------------------------------------------------
//
AudioChannel(AudioChannelType audio_channel_type, MIDIChannel midi_channel, AudioCard *audio_card);
~AudioChannel();
Logical TestInstance() const;
//
//--------------------------------------------------------------------
// Accessors
//--------------------------------------------------------------------
//
AudioChannelType GetAudioChannelType() { return audioChannelType; }
MIDIChannel GetChannelNumber() { return midiChannel; }
void SetVoicesUsed(AudioVoiceCount voices_used) { voicesUsed = voices_used; }
AudioVoiceCount GetVoicesUsed() { return voicesUsed; }
//
//--------------------------------------------------------------------
// MIDI methods
//--------------------------------------------------------------------
//
void SendNoteOn(MIDIValue key, MIDIValue velocity);
MIDIValue myPreset;
MIDIValue myBank;
void SendNoteOff(MIDIValue key, MIDIValue velocity);
void SendProgramChange(MIDIValue program);
void SendController(MIDIValue controller, MIDIValue value);
void SendPolyKeyPressure(MIDIValue key, MIDIValue value);
void SendChannelPressure(MIDIValue value);
void SendPitchBend(MIDIPitchBend pitch_bend);
void SendPitchBendRange(MIDIValue sensitivity);
void SendNRPN(MIDIValue paramNumber, MIDINRPNValue value);
void SelectEffect(MIDIEffectType type, MIDIValue effect);
void SelectBank(MIDIValue bank);
//
//--------------------------------------------------------------------
// Release
//--------------------------------------------------------------------
//
void Release();
private:
//
//--------------------------------------------------------------------
// Private data
//--------------------------------------------------------------------
//
AudioChannelType
audioChannelType;
MIDIChannel midiChannel;
AudioVoiceCount voicesUsed;
AudioCard *audioCard;
};*/
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioCard ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*class AudioCard : public Node
{
friend class AudioHardware;
public:
//
//--------------------------------------------------------------------
// Constructor, Destructor, Testing
//--------------------------------------------------------------------
//
AudioCard();
~AudioCard();
Logical TestInstance() const;
//
//--------------------------------------------------------------------
// Public methods
//--------------------------------------------------------------------
//
void Initialize();
void Close();
void GetEnvironmentSettings(char *env_str);
Logical InitMIDIReceive();
void CloseMIDIReceive();
Logical IsMIDIAvailable();
MIDIValue GetMIDIByte();
void InitializeChannels();
int LoadSBK(const char *file_name);
void ReleaseAllBanks();
//
//--------------------------------------------------------------------
// MIDI methods
//--------------------------------------------------------------------
//
void SendNoteOn(MIDIChannel channel, MIDIValue key, MIDIValue velocity);
void SendNoteOff(MIDIChannel channel, MIDIValue key, MIDIValue velocity);
void SendProgramChange(MIDIChannel channel, MIDIValue program);
void SendController(MIDIChannel channel, MIDIValue controller, MIDIValue value);
void SendPolyKeyPressure(MIDIChannel channel, MIDIValue key, MIDIValue value);
void SendChannelPressure(MIDIChannel channel, MIDIValue value);
void SendPitchBendRange(MIDIChannel channel, MIDIValue sensitivity);
void SendPitchBend(MIDIChannel channel, MIDIPitchBend pitch_bend);
void SendSysex(void *data, size_t length);
void SendNRPN(MIDIChannel channel, MIDIValue paramNumber, MIDINRPNValue value);
void SelectEffect(MIDIEffectType type, MIDIValue effect);
void SelectBank(MIDIChannel channel, MIDIValue bank);
void SendMIDIMessage(MIDIMessage *midi_message, Word length);
//
//--------------------------------------------------------------------
// Channel methods
//--------------------------------------------------------------------
//
AudioChannel* RequestAudioChannel(AudioVoiceCount voice_count);
void ReleaseAudioChannel(AudioChannel *audio_channel);
private:
//
//--------------------------------------------------------------------
// Private methods
//--------------------------------------------------------------------
//
WORD GetHexWord(const char ** s);
//
//--------------------------------------------------------------------
// Private data
//--------------------------------------------------------------------
//
//
// Card addresses
//
WORD srcAddx;
WORD irqInterrupt;
WORD dmaChannel;
WORD mpuAddx;
WORD emuAddx;
//
// Structure for the MIDI driver initialization function
// Structure for the MIDI driver hardware
//
#ifdef AUDIO_HARDWARE
_SOS_MIDI_INIT_DRIVER sSOSMIDIInitDriver;
_SOS_MIDI_HARDWARE sSOSMIDIHardware;
#endif
//
// Handle for the loaded MIDI driver
//
WORD wDriverHandle;
//
// Number of free voices
//
AudioVoiceCount
idleVoices;
//
// Idle channels
//
ChainOf<AudioChannel*> idleChannelSocket;
ChainOf<AudioChannel*> percussionChannelSocket;
};*/
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioHardware ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*class AudioHardware : public Node
{
public:
//
//--------------------------------------------------------------------
// Constructor, Destructor, Testing
//--------------------------------------------------------------------
//
AudioHardware();
~AudioHardware();
Logical TestInstance() const;
static Logical TestClass();
static Logical ProfileClass();
//
//--------------------------------------------------------------------
// Public methods
//--------------------------------------------------------------------
//
void Initialize();
void Close();
//
//--------------------------------------------------------------------
// Card Access
//--------------------------------------------------------------------
//
AudioCard* GetFrontCard();
AudioCard* GetRearCard();
private:
//
//--------------------------------------------------------------------
// Private methods
//--------------------------------------------------------------------
//
//
//--------------------------------------------------------------------
// Private data
//--------------------------------------------------------------------
//
AudioCard frontCard;
AudioCard rearCard;
};*/
//~~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioCard inlines ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*inline void AudioCard::SendMIDIMessage(MIDIMessage *midi_message, Word length)
{
#ifdef AUDIO_HARDWARE
SET_AUDIO_RENDERER_MIDI();
Check_Signature(midi_message);
#if DEBUG_LEVEL>0
switch (midi_message->message[0] >> 4)
{
case MIDI_NOTE_ON_STATUS:
case MIDI_NOTE_OFF_STATUS:
case MIDI_POLYKEY_STATUS:
case MIDI_CONTROLLER_STATUS:
case MIDI_PITCH_BEND_STATUS:
Verify(length == 3);
break;
case MIDI_PROGRAM_CHANGE_STATUS:
case MIDI_CHANNEL_PRESSURE_STATUS:
Verify(length == 2);
break;
default:
Fail("Should never reach here");
break;
}
#endif
#if DEBUG_LEVEL>0
{
Word wError = sosMIDISendMIDIData(wDriverHandle, (char*)midi_message->message, length);
Verify(wError == _ERR_NO_ERROR);
}
#else
sosMIDISendMIDIData(wDriverHandle, (char*)midi_message->message, length);
#endif
CLEAR_AUDIO_RENDERER_MIDI();
#endif
}
//
//--------------------------------------------------------------------
// MIDI methods
//--------------------------------------------------------------------
//
inline void AudioCard::SendNoteOn(MIDIChannel channel, MIDIValue key, MIDIValue velocity)
{
MIDIMessage message(MIDI_NOTE_ON_STATUS, channel, key, velocity);
SendMIDIMessage(&message, 3);
}
inline void AudioCard::SendNoteOff(MIDIChannel channel, MIDIValue key, MIDIValue velocity)
{
MIDIMessage message(MIDI_NOTE_OFF_STATUS, channel, key, velocity);
SendMIDIMessage(&message, 3);
}
inline void AudioCard::SendProgramChange(MIDIChannel channel, MIDIValue program)
{
MIDIMessage message(MIDI_PROGRAM_CHANGE_STATUS, channel, program);
SendMIDIMessage(&message, 2);
}
inline void AudioCard::SendController(MIDIChannel channel, MIDIValue controller, MIDIValue value)
{
MIDIMessage message(MIDI_CONTROLLER_STATUS, channel, controller, value);
SendMIDIMessage(&message, 3);
}
inline void AudioCard::SendPolyKeyPressure(MIDIChannel channel, MIDIValue key, MIDIValue value)
{
MIDIMessage message(MIDI_POLYKEY_STATUS, channel, key, value);
SendMIDIMessage(&message, 3);
}
inline void AudioCard::SendChannelPressure(MIDIChannel channel, MIDIValue value)
{
MIDIMessage message(MIDI_CHANNEL_PRESSURE_STATUS, channel, value);
SendMIDIMessage(&message, 2);
}
inline void AudioCard::SelectBank(MIDIChannel channel, MIDIValue bank)
{
SendController(channel, (MIDIValue)0, bank);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~ AudioChannel inlines ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//--------------------------------------------------------------------
// MIDI methods
//--------------------------------------------------------------------
//
inline void AudioChannel::SendNoteOn(MIDIValue key, MIDIValue velocity)
{
DEBUG_STREAM << "Sending note " << (int)key << " for bank " << (int)myBank << ", preset " << (int)myPreset << "." << std::endl << std::flush;
//Check(audioCard);
//audioCard->SendNoteOn(midiChannel,key,velocity);
}
inline void AudioChannel::SendNoteOff(MIDIValue key, MIDIValue velocity)
{
Check(audioCard);
audioCard->SendNoteOff(midiChannel,key,velocity);
}
inline void AudioChannel::SendProgramChange(MIDIValue program)
{
Check(audioCard);
myPreset = program;
audioCard->SendProgramChange(midiChannel,program);
}
inline void AudioChannel::SendController(MIDIValue controller, MIDIValue value)
{
Check(audioCard);
audioCard->SendController(midiChannel,controller,value);
}
inline void AudioChannel::SendPolyKeyPressure(MIDIValue key, MIDIValue value)
{
Check(audioCard);
audioCard->SendPolyKeyPressure(midiChannel,key,value);
}
inline void AudioChannel::SendChannelPressure(MIDIValue value)
{
Check(audioCard);
audioCard->SendChannelPressure(midiChannel,value);
}
inline void AudioChannel::SendPitchBend(MIDIPitchBend pitch_bend)
{
Check(audioCard);
audioCard->SendPitchBend(midiChannel,pitch_bend);
}
inline void AudioChannel::SendPitchBendRange(MIDIValue sensitivity)
{
Check(audioCard);
audioCard->SendPitchBendRange(midiChannel,sensitivity);
}
inline void AudioChannel::SelectEffect(MIDIEffectType type, MIDIValue effect)
{
Check(audioCard);
audioCard->SelectEffect(type,effect);
}
inline void AudioChannel::SendNRPN(MIDIValue paramNumber, MIDINRPNValue value)
{
Check(audioCard);
audioCard->SendNRPN(midiChannel,paramNumber,value);
}
inline void AudioChannel::SelectBank(MIDIValue bank)
{
Check(audioCard);
myBank = bank;
audioCard->SelectBank(midiChannel,bank);
}
inline void AudioChannel::Release()
{
Check(audioCard);
audioCard->ReleaseAudioChannel(this);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~ AudioHardware inlines ~~~~~~~~~~~~~~~~~~~~~~~~~~
inline AudioCard* AudioHardware::GetFrontCard()
{
Check(this);
return &frontCard;
}
inline AudioCard* AudioHardware::GetRearCard()
{
Check(this);
return &rearCard;
}*/