mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-22 05:45:38 +00:00
njz3: Proper quadrophonic audio support. Need 4+ speakers to take advantage otherwise down mixed to stereo.
This commit is contained in:
parent
5e61e2f388
commit
83e7b5f45d
|
@ -174,6 +174,7 @@
|
||||||
<drive_board>Wheel</drive_board>
|
<drive_board>Wheel</drive_board>
|
||||||
<real3d_status_bit_set_percent_of_frame>24</real3d_status_bit_set_percent_of_frame>
|
<real3d_status_bit_set_percent_of_frame>24</real3d_status_bit_set_percent_of_frame>
|
||||||
<netboard>true</netboard>
|
<netboard>true</netboard>
|
||||||
|
<audio>QuadFrontRear</audio>
|
||||||
<inputs>
|
<inputs>
|
||||||
<input type="common" />
|
<input type="common" />
|
||||||
<input type="vehicle" />
|
<input type="vehicle" />
|
||||||
|
@ -266,6 +267,7 @@
|
||||||
<mpeg_board>DSB2</mpeg_board>
|
<mpeg_board>DSB2</mpeg_board>
|
||||||
<drive_board>Wheel</drive_board>
|
<drive_board>Wheel</drive_board>
|
||||||
<netboard>true</netboard>
|
<netboard>true</netboard>
|
||||||
|
<audio>QuadFrontRear</audio>
|
||||||
<inputs>
|
<inputs>
|
||||||
<input type="common" />
|
<input type="common" />
|
||||||
<input type="vehicle" />
|
<input type="vehicle" />
|
||||||
|
@ -551,6 +553,7 @@
|
||||||
<platform>Sega Model 3</platform>
|
<platform>Sega Model 3</platform>
|
||||||
<stepping>2.1</stepping>
|
<stepping>2.1</stepping>
|
||||||
<drive_board>Wheel</drive_board>
|
<drive_board>Wheel</drive_board>
|
||||||
|
<audio>Stereo</audio>
|
||||||
<inputs>
|
<inputs>
|
||||||
<input type="common" />
|
<input type="common" />
|
||||||
<input type="vehicle" />
|
<input type="vehicle" />
|
||||||
|
@ -632,6 +635,7 @@
|
||||||
<platform>Sega Model 3</platform>
|
<platform>Sega Model 3</platform>
|
||||||
<stepping>2.1</stepping>
|
<stepping>2.1</stepping>
|
||||||
<drive_board>Wheel</drive_board>
|
<drive_board>Wheel</drive_board>
|
||||||
|
<audio>Stereo</audio>
|
||||||
<inputs>
|
<inputs>
|
||||||
<input type="common" />
|
<input type="common" />
|
||||||
<input type="vehicle" />
|
<input type="vehicle" />
|
||||||
|
@ -678,6 +682,7 @@
|
||||||
<platform>Sega Model 3</platform>
|
<platform>Sega Model 3</platform>
|
||||||
<stepping>2.1</stepping>
|
<stepping>2.1</stepping>
|
||||||
<drive_board>Wheel</drive_board>
|
<drive_board>Wheel</drive_board>
|
||||||
|
<audio>Stereo</audio>
|
||||||
<inputs>
|
<inputs>
|
||||||
<input type="common" />
|
<input type="common" />
|
||||||
<input type="vehicle" />
|
<input type="vehicle" />
|
||||||
|
@ -711,6 +716,7 @@
|
||||||
<platform>Sega Model 3</platform>
|
<platform>Sega Model 3</platform>
|
||||||
<stepping>2.1</stepping>
|
<stepping>2.1</stepping>
|
||||||
<drive_board>Wheel</drive_board>
|
<drive_board>Wheel</drive_board>
|
||||||
|
<audio>Stereo</audio>
|
||||||
<inputs>
|
<inputs>
|
||||||
<input type="common" />
|
<input type="common" />
|
||||||
<input type="vehicle" />
|
<input type="vehicle" />
|
||||||
|
@ -1030,6 +1036,7 @@
|
||||||
<stepping>1.5</stepping>
|
<stepping>1.5</stepping>
|
||||||
<drive_board>Wheel</drive_board>
|
<drive_board>Wheel</drive_board>
|
||||||
<netboard>true</netboard>
|
<netboard>true</netboard>
|
||||||
|
<audio>Stereo</audio>
|
||||||
<inputs>
|
<inputs>
|
||||||
<input type="common" />
|
<input type="common" />
|
||||||
<input type="vehicle" />
|
<input type="vehicle" />
|
||||||
|
@ -1360,6 +1367,7 @@
|
||||||
<mpeg_board>DSB1</mpeg_board>
|
<mpeg_board>DSB1</mpeg_board>
|
||||||
<drive_board>Wheel</drive_board>
|
<drive_board>Wheel</drive_board>
|
||||||
<netboard>true</netboard>
|
<netboard>true</netboard>
|
||||||
|
<audio>QuadFrontRear</audio>
|
||||||
<inputs>
|
<inputs>
|
||||||
<input type="common" />
|
<input type="common" />
|
||||||
<input type="vehicle" />
|
<input type="vehicle" />
|
||||||
|
@ -1444,6 +1452,7 @@
|
||||||
<mpeg_board>DSB1</mpeg_board>
|
<mpeg_board>DSB1</mpeg_board>
|
||||||
<drive_board>Wheel</drive_board>
|
<drive_board>Wheel</drive_board>
|
||||||
<netboard>true</netboard>
|
<netboard>true</netboard>
|
||||||
|
<audio>QuadFrontRear</audio>
|
||||||
<inputs>
|
<inputs>
|
||||||
<input type="common" />
|
<input type="common" />
|
||||||
<input type="vehicle" />
|
<input type="vehicle" />
|
||||||
|
@ -1478,6 +1487,7 @@
|
||||||
<mpeg_board>DSB1</mpeg_board>
|
<mpeg_board>DSB1</mpeg_board>
|
||||||
<drive_board>Wheel</drive_board>
|
<drive_board>Wheel</drive_board>
|
||||||
<netboard>true</netboard>
|
<netboard>true</netboard>
|
||||||
|
<audio>QuadFrontRear</audio>
|
||||||
<inputs>
|
<inputs>
|
||||||
<input type="common" />
|
<input type="common" />
|
||||||
<input type="vehicle" />
|
<input type="vehicle" />
|
||||||
|
@ -1550,6 +1560,7 @@
|
||||||
<mpeg_board>DSB1</mpeg_board>
|
<mpeg_board>DSB1</mpeg_board>
|
||||||
<drive_board>Wheel</drive_board>
|
<drive_board>Wheel</drive_board>
|
||||||
<netboard>true</netboard>
|
<netboard>true</netboard>
|
||||||
|
<audio>QuadFrontRear</audio>
|
||||||
<inputs>
|
<inputs>
|
||||||
<input type="common" />
|
<input type="common" />
|
||||||
<input type="vehicle" />
|
<input type="vehicle" />
|
||||||
|
@ -1597,6 +1608,7 @@
|
||||||
<drive_board>Wheel</drive_board>
|
<drive_board>Wheel</drive_board>
|
||||||
<pci_bridge>MPC106</pci_bridge>
|
<pci_bridge>MPC106</pci_bridge>
|
||||||
<netboard>true</netboard>
|
<netboard>true</netboard>
|
||||||
|
<audio>QuadFrontRear</audio>
|
||||||
<inputs>
|
<inputs>
|
||||||
<input type="common" />
|
<input type="common" />
|
||||||
<input type="vehicle" />
|
<input type="vehicle" />
|
||||||
|
@ -1891,6 +1903,7 @@
|
||||||
<mpeg_board>DSB2</mpeg_board>
|
<mpeg_board>DSB2</mpeg_board>
|
||||||
<drive_board>Wheel</drive_board>
|
<drive_board>Wheel</drive_board>
|
||||||
<netboard>true</netboard>
|
<netboard>true</netboard>
|
||||||
|
<audio>QuadMix</audio>
|
||||||
<inputs>
|
<inputs>
|
||||||
<input type="common" />
|
<input type="common" />
|
||||||
<input type="vehicle" />
|
<input type="vehicle" />
|
||||||
|
@ -1989,6 +2002,7 @@
|
||||||
<stepping>2.0</stepping>
|
<stepping>2.0</stepping>
|
||||||
<mpeg_board>DSB2</mpeg_board>
|
<mpeg_board>DSB2</mpeg_board>
|
||||||
<drive_board>Wheel</drive_board>
|
<drive_board>Wheel</drive_board>
|
||||||
|
<audio>QuadMix</audio>
|
||||||
<inputs>
|
<inputs>
|
||||||
<input type="common" />
|
<input type="common" />
|
||||||
<input type="vehicle" />
|
<input type="vehicle" />
|
||||||
|
@ -2098,6 +2112,7 @@
|
||||||
<mpeg_board>DSB2</mpeg_board>
|
<mpeg_board>DSB2</mpeg_board>
|
||||||
<drive_board>Wheel</drive_board>
|
<drive_board>Wheel</drive_board>
|
||||||
<real3d_status_bit_set_percent_of_frame>48</real3d_status_bit_set_percent_of_frame>
|
<real3d_status_bit_set_percent_of_frame>48</real3d_status_bit_set_percent_of_frame>
|
||||||
|
<audio>QuadMix</audio>
|
||||||
<inputs>
|
<inputs>
|
||||||
<input type="common" />
|
<input type="common" />
|
||||||
<input type="vehicle" />
|
<input type="vehicle" />
|
||||||
|
|
12
Src/Game.h
12
Src/Game.h
|
@ -14,6 +14,18 @@ struct Game
|
||||||
unsigned year = 0;
|
unsigned year = 0;
|
||||||
std::string stepping;
|
std::string stepping;
|
||||||
std::string mpeg_board;
|
std::string mpeg_board;
|
||||||
|
enum AudioTypes
|
||||||
|
{
|
||||||
|
MONO = 0, // Merge DSB+SCSP1+SCSP2 to 1 channel mono
|
||||||
|
STEREO_LR, // Merge DSP+SCSP1+SCSP2 to 2 channels stereo Left/Right (most common)
|
||||||
|
STEREO_RL, // Merge DSP+SCSP1+SCSP2 to 2 channels stereo reversed Right/Left
|
||||||
|
QUAD_1_FLR_2_RLR, // Split DSB+SCSP1 to FrontLeft/FrontRight and SCSP2 to RearLeft/RearRight (Daytona2)
|
||||||
|
QUAD_1_FRL_2_RRL, // Split DSB+SCSP1 to FrontRight/FrontLeft and SCSP2 to RearRight/RearLeft
|
||||||
|
QUAD_1_RLR_2_FLR, // Split DSB+SCSP1 to RearLeft/RearRight and SCSP2 to FrontLeft/FrontRight
|
||||||
|
QUAD_1_RRL_2_FRL, // Split DSB+SCSP1 to RearRight/RearLeft and SCSP2 to FrontRight/FrontLeft
|
||||||
|
QUAD_1_LR_2_FR_MIX, // Specific srally2: Split SCSP2 and mix first channel to DSB+SCP11 Front Left/Right and second to Read Left/Right
|
||||||
|
};
|
||||||
|
AudioTypes audio = STEREO_LR;
|
||||||
std::string pci_bridge; // overrides default PCI bridge type for stepping (empty string for default)
|
std::string pci_bridge; // overrides default PCI bridge type for stepping (empty string for default)
|
||||||
uint32_t real3d_pci_id = 0; // overrides default Real3D PCI ID for stepping (0 for default)
|
uint32_t real3d_pci_id = 0; // overrides default Real3D PCI ID for stepping (0 for default)
|
||||||
float real3d_status_bit_set_percent_of_frame = 0; // overrides default status bit timing (0 for default)
|
float real3d_status_bit_set_percent_of_frame = 0; // overrides default status bit timing (0 for default)
|
||||||
|
|
|
@ -198,6 +198,20 @@ static void PopulateGameInfo(Game *game, const Util::Config::Node &game_node)
|
||||||
game->year = game_node["identity/year"].ValueAsDefault<unsigned>(0);
|
game->year = game_node["identity/year"].ValueAsDefault<unsigned>(0);
|
||||||
game->stepping = game_node["hardware/stepping"].ValueAsDefault<std::string>("");
|
game->stepping = game_node["hardware/stepping"].ValueAsDefault<std::string>("");
|
||||||
game->mpeg_board = game_node["hardware/mpeg_board"].ValueAsDefault<std::string>("");
|
game->mpeg_board = game_node["hardware/mpeg_board"].ValueAsDefault<std::string>("");
|
||||||
|
std::map<std::string, Game::AudioTypes> audio_types
|
||||||
|
{
|
||||||
|
{ "", Game::STEREO_LR }, // default to stereo
|
||||||
|
{ "Mono", Game::MONO },
|
||||||
|
{ "Stereo", Game::STEREO_LR },
|
||||||
|
{ "StereoReversed", Game::STEREO_RL },
|
||||||
|
{ "QuadFrontRear", Game::QUAD_1_FLR_2_RLR },
|
||||||
|
{ "QuadFrontRearReversed", Game::QUAD_1_FRL_2_RRL },
|
||||||
|
{ "QuadRearFront", Game::QUAD_1_RLR_2_FLR },
|
||||||
|
{ "QuadRearFrontReversed", Game::QUAD_1_RRL_2_FRL },
|
||||||
|
{ "QuadMix", Game::QUAD_1_LR_2_FR_MIX}
|
||||||
|
};
|
||||||
|
std::string audio_type = game_node["hardware/audio"].ValueAsDefault<std::string>(std::string());
|
||||||
|
game->audio = audio_types[audio_type];
|
||||||
game->pci_bridge = game_node["hardware/pci_bridge"].ValueAsDefault<std::string>("");
|
game->pci_bridge = game_node["hardware/pci_bridge"].ValueAsDefault<std::string>("");
|
||||||
game->real3d_pci_id = game_node["hardware/real3d_pci_id"].ValueAsDefault<uint32_t>(0);
|
game->real3d_pci_id = game_node["hardware/real3d_pci_id"].ValueAsDefault<uint32_t>(0);
|
||||||
game->real3d_status_bit_set_percent_of_frame = game_node["hardware/real3d_status_bit_set_percent_of_frame"].ValueAsDefault<float>(0);
|
game->real3d_status_bit_set_percent_of_frame = game_node["hardware/real3d_status_bit_set_percent_of_frame"].ValueAsDefault<float>(0);
|
||||||
|
|
|
@ -725,7 +725,7 @@ void CLegacy3D::InsertVertex(ModelCache *Cache, const Vertex *V, const Poly *P,
|
||||||
// Specular shininess
|
// Specular shininess
|
||||||
GLfloat specularCoefficient = (GLfloat) ((P->header[0]>>26) & 0x3F) * (1.0f/63.0f);
|
GLfloat specularCoefficient = (GLfloat) ((P->header[0]>>26) & 0x3F) * (1.0f/63.0f);
|
||||||
int shinyBits = (P->header[6] >> 5) & 3;
|
int shinyBits = (P->header[6] >> 5) & 3;
|
||||||
float shininess = pow(2.0f, 1+shinyBits);
|
float shininess = std::pow(2.0f, 1.f + shinyBits);
|
||||||
if (!(P->header[0]&0x80)) //|| (shininess == 0)) // bit 0x80 seems to enable specular lighting
|
if (!(P->header[0]&0x80)) //|| (shininess == 0)) // bit 0x80 seems to enable specular lighting
|
||||||
{
|
{
|
||||||
specularCoefficient = 0.; // disable
|
specularCoefficient = 0.; // disable
|
||||||
|
|
|
@ -163,7 +163,7 @@ public:
|
||||||
virtual void AttachInputs(CInputs *InputsPtr) = 0;
|
virtual void AttachInputs(CInputs *InputsPtr) = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AttachInputs(InputsPtr):
|
* AttachOutputs(InputsPtr):
|
||||||
*
|
*
|
||||||
* Attaches OSD-managed outputs (cabinet lamps, etc.)
|
* Attaches OSD-managed outputs (cabinet lamps, etc.)
|
||||||
*
|
*
|
||||||
|
|
|
@ -472,6 +472,11 @@ UINT8 CModel3::ReadInputs(unsigned reg)
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
|
case 0x10: // Drive board
|
||||||
|
return OutputRegister[0];
|
||||||
|
case 0x14: // Lamps
|
||||||
|
return OutputRegister[1];
|
||||||
|
|
||||||
case 0x0C: // game-specific inputs
|
case 0x0C: // game-specific inputs
|
||||||
|
|
||||||
data = 0xFF;
|
data = 0xFF;
|
||||||
|
@ -651,9 +656,11 @@ void CModel3::WriteInputs(unsigned reg, UINT8 data)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x10: // Drive board
|
case 0x10: // Drive board
|
||||||
|
if (DriveBoard->IsAttached())
|
||||||
DriveBoard->Write(data);
|
DriveBoard->Write(data);
|
||||||
if (NULL != Outputs) // TODO - check gameInputs
|
if (NULL != Outputs) // TODO - check gameInputs
|
||||||
Outputs->SetValue(OutputRawDrive, data);
|
Outputs->SetValue(OutputRawDrive, data);
|
||||||
|
OutputRegister[0] = data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x14: // Lamp outputs (Daytona/Scud Race/Sega Rally/Le Mans 24)
|
case 0x14: // Lamp outputs (Daytona/Scud Race/Sega Rally/Le Mans 24)
|
||||||
|
@ -667,6 +674,7 @@ void CModel3::WriteInputs(unsigned reg, UINT8 data)
|
||||||
Outputs->SetValue(OutputLampLeader, !!(data&0x80));
|
Outputs->SetValue(OutputLampLeader, !!(data&0x80));
|
||||||
Outputs->SetValue(OutputRawLamps, data);
|
Outputs->SetValue(OutputRawLamps, data);
|
||||||
}
|
}
|
||||||
|
OutputRegister[1] = data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x24: // Serial FIFO 1
|
case 0x24: // Serial FIFO 1
|
||||||
|
@ -2017,7 +2025,8 @@ void CModel3::RunFrame(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
timings.frameTicks = CThread::GetTicks() - start;
|
timings.frameTicks = CThread::GetTicks() - start;
|
||||||
|
// Frame counter
|
||||||
|
timings.frameId++;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ThreadError:
|
ThreadError:
|
||||||
|
@ -2810,6 +2819,7 @@ void CModel3::Reset(void)
|
||||||
NetBoard->Reset();
|
NetBoard->Reset();
|
||||||
#endif
|
#endif
|
||||||
timings.frameTicks = 0;
|
timings.frameTicks = 0;
|
||||||
|
timings.frameId = 0;
|
||||||
|
|
||||||
DebugLog("Model 3 reset\n");
|
DebugLog("Model 3 reset\n");
|
||||||
}
|
}
|
||||||
|
@ -3176,7 +3186,7 @@ INetBoard *CModel3::GetNetBoard(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CModel3::CModel3(const Util::Config::Node &config)
|
CModel3::CModel3(Util::Config::Node &config)
|
||||||
: m_config(config),
|
: m_config(config),
|
||||||
m_multiThreaded(config["MultiThreaded"].ValueAs<bool>()),
|
m_multiThreaded(config["MultiThreaded"].ValueAs<bool>()),
|
||||||
m_gpuMultiThreaded(config["GPUMultiThreaded"].ValueAs<bool>()),
|
m_gpuMultiThreaded(config["GPUMultiThreaded"].ValueAs<bool>()),
|
||||||
|
|
|
@ -63,6 +63,7 @@ struct FrameTimings
|
||||||
UINT32 netTicks;
|
UINT32 netTicks;
|
||||||
#endif
|
#endif
|
||||||
UINT32 frameTicks;
|
UINT32 frameTicks;
|
||||||
|
UINT64 frameId;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -95,6 +96,8 @@ public:
|
||||||
void AttachInputs(CInputs *InputsPtr);
|
void AttachInputs(CInputs *InputsPtr);
|
||||||
void AttachOutputs(COutputs *OutputsPtr);
|
void AttachOutputs(COutputs *OutputsPtr);
|
||||||
bool Init(void);
|
bool Init(void);
|
||||||
|
// For Scripting tweaks
|
||||||
|
Util::Config::Node& GetConfig() { return this->m_config; }
|
||||||
|
|
||||||
// IPCIDevice interface
|
// IPCIDevice interface
|
||||||
UINT32 ReadPCIConfigSpace(unsigned device, unsigned reg, unsigned bits, unsigned width);
|
UINT32 ReadPCIConfigSpace(unsigned device, unsigned reg, unsigned bits, unsigned width);
|
||||||
|
@ -184,7 +187,7 @@ public:
|
||||||
* config Run-time configuration. The reference should be held because
|
* config Run-time configuration. The reference should be held because
|
||||||
* this changes at run-time.
|
* this changes at run-time.
|
||||||
*/
|
*/
|
||||||
CModel3(const Util::Config::Node &config);
|
CModel3(Util::Config::Node &config);
|
||||||
~CModel3(void);
|
~CModel3(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -228,7 +231,7 @@ private:
|
||||||
int RunDriveBoardThread(void); // Runs drive board thread (sync'd in step with render thread)
|
int RunDriveBoardThread(void); // Runs drive board thread (sync'd in step with render thread)
|
||||||
|
|
||||||
// Runtime configuration
|
// Runtime configuration
|
||||||
const Util::Config::Node &m_config;
|
Util::Config::Node &m_config;
|
||||||
bool m_multiThreaded;
|
bool m_multiThreaded;
|
||||||
bool m_gpuMultiThreaded;
|
bool m_gpuMultiThreaded;
|
||||||
|
|
||||||
|
@ -262,6 +265,7 @@ private:
|
||||||
UINT8 *driveROM; // 32 KB drive board ROM (Z80 program) (optional)
|
UINT8 *driveROM; // 32 KB drive board ROM (Z80 program) (optional)
|
||||||
UINT8 *netRAM; // 64 KB RAM
|
UINT8 *netRAM; // 64 KB RAM
|
||||||
UINT8 *netBuffer; // 128 KB buffer
|
UINT8 *netBuffer; // 128 KB buffer
|
||||||
|
UINT8 OutputRegister[2]; // Input/output register for driveboard and lamps
|
||||||
|
|
||||||
// Banked CROM
|
// Banked CROM
|
||||||
UINT8 *cromBank; // currently mapped in CROM bank
|
UINT8 *cromBank; // currently mapped in CROM bank
|
||||||
|
@ -321,7 +325,6 @@ private:
|
||||||
INetBoard *NetBoard; // Net board
|
INetBoard *NetBoard; // Net board
|
||||||
bool m_runNetBoard;
|
bool m_runNetBoard;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -350,16 +350,25 @@ bool CSoundBoard::RunFrame(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memset(audioL, 0, 44100/60*sizeof(INT16));
|
memset(audioFL, 0, 44100/60*sizeof(INT16));
|
||||||
memset(audioR, 0, 44100/60*sizeof(INT16));
|
memset(audioFR, 0, 44100/60*sizeof(INT16));
|
||||||
|
memset(audioRL, 0, 44100/60*sizeof(INT16));
|
||||||
|
memset(audioRR, 0, 44100/60*sizeof(INT16));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run DSB and mix with existing audio
|
// Run DSB and mix with existing audio
|
||||||
if (NULL != DSB)
|
if (NULL != DSB) {
|
||||||
DSB->RunFrame(audioL, audioR);
|
// Will need to mix with proper front, rear channels or both (game specific)
|
||||||
|
bool mixDSBWithFront = true; // Everything to front channels for now
|
||||||
|
// Case "both" not handled for now
|
||||||
|
if (mixDSBWithFront)
|
||||||
|
DSB->RunFrame(audioFL, audioFR);
|
||||||
|
else
|
||||||
|
DSB->RunFrame(audioRL, audioRR);
|
||||||
|
}
|
||||||
|
|
||||||
// Output the audio buffers
|
// Output the audio buffers
|
||||||
bool bufferFull = OutputAudio(44100/60, audioL, audioR, m_config["FlipStereo"].ValueAs<bool>());
|
bool bufferFull = OutputAudio(44100/60, audioFL, audioFR, audioRL, audioRR, m_config["FlipStereo"].ValueAs<bool>());
|
||||||
|
|
||||||
#ifdef SUPERMODEL_LOG_AUDIO
|
#ifdef SUPERMODEL_LOG_AUDIO
|
||||||
// Output to binary file
|
// Output to binary file
|
||||||
|
@ -446,9 +455,13 @@ void CSoundBoard::AttachDSB(CDSB *DSBPtr)
|
||||||
// Offsets of memory regions within sound board's pool
|
// Offsets of memory regions within sound board's pool
|
||||||
#define OFFSET_RAM1 0 // 1 MB SCSP1 RAM
|
#define OFFSET_RAM1 0 // 1 MB SCSP1 RAM
|
||||||
#define OFFSET_RAM2 0x100000 // 1 MB SCSP2 RAM
|
#define OFFSET_RAM2 0x100000 // 1 MB SCSP2 RAM
|
||||||
#define OFFSET_AUDIO_LEFT 0x200000 // 1470 bytes (16 bits, 44.1 KHz, 1/60th second) left audio channel
|
#define LENGTH_CHANNEL_BUFFER 0x5BE
|
||||||
#define OFFSET_AUDIO_RIGHT 0x2005BE // 1470 bytes right audio channel
|
#define OFFSET_AUDIO_FRONTLEFT 0x200000 // 1470 bytes (16 bits, 44.1 KHz, 1/60th second) left audio channel
|
||||||
#define MEMORY_POOL_SIZE (0x100000 + 0x100000 + 0x5BE + 0x5BE)
|
#define OFFSET_AUDIO_FRONTRIGHT (OFFSET_AUDIO_FRONTLEFT + LENGTH_CHANNEL_BUFFER) // 1470 bytes right audio channel
|
||||||
|
#define OFFSET_AUDIO_REARLEFT (OFFSET_AUDIO_FRONTRIGHT + LENGTH_CHANNEL_BUFFER) // 1470 bytes (16 bits, 44.1 KHz, 1/60th second) left audio channel
|
||||||
|
#define OFFSET_AUDIO_REARRIGHT (OFFSET_AUDIO_REARLEFT + LENGTH_CHANNEL_BUFFER) // 1470 bytes right audio channel
|
||||||
|
|
||||||
|
#define MEMORY_POOL_SIZE (0x100000 + 0x100000 + 4*LENGTH_CHANNEL_BUFFER)
|
||||||
|
|
||||||
bool CSoundBoard::Init(const UINT8 *soundROMPtr, const UINT8 *sampleROMPtr)
|
bool CSoundBoard::Init(const UINT8 *soundROMPtr, const UINT8 *sampleROMPtr)
|
||||||
{
|
{
|
||||||
|
@ -469,8 +482,10 @@ bool CSoundBoard::Init(const UINT8 *soundROMPtr, const UINT8 *sampleROMPtr)
|
||||||
// Set up memory pointers
|
// Set up memory pointers
|
||||||
ram1 = &memoryPool[OFFSET_RAM1];
|
ram1 = &memoryPool[OFFSET_RAM1];
|
||||||
ram2 = &memoryPool[OFFSET_RAM2];
|
ram2 = &memoryPool[OFFSET_RAM2];
|
||||||
audioL = (INT16 *) &memoryPool[OFFSET_AUDIO_LEFT];
|
audioFL = (INT16*)&memoryPool[OFFSET_AUDIO_FRONTLEFT];
|
||||||
audioR = (INT16 *) &memoryPool[OFFSET_AUDIO_RIGHT];
|
audioFR = (INT16*)&memoryPool[OFFSET_AUDIO_FRONTRIGHT];
|
||||||
|
audioRL = (INT16*)&memoryPool[OFFSET_AUDIO_REARLEFT];
|
||||||
|
audioRR = (INT16*)&memoryPool[OFFSET_AUDIO_REARRIGHT];
|
||||||
|
|
||||||
// Initialize 68K core
|
// Initialize 68K core
|
||||||
M68KSetContext(&M68K);
|
M68KSetContext(&M68K);
|
||||||
|
@ -480,7 +495,7 @@ bool CSoundBoard::Init(const UINT8 *soundROMPtr, const UINT8 *sampleROMPtr)
|
||||||
M68KGetContext(&M68K);
|
M68KGetContext(&M68K);
|
||||||
|
|
||||||
// Initialize SCSPs
|
// Initialize SCSPs
|
||||||
SCSP_SetBuffers(audioL, audioR, 44100/60);
|
SCSP_SetBuffers(audioFL, audioFR, audioRL, audioRR, 44100/60);
|
||||||
SCSP_SetCB(SCSP68KRunCallback, SCSP68KIRQCallback);
|
SCSP_SetCB(SCSP68KRunCallback, SCSP68KIRQCallback);
|
||||||
if (OKAY != SCSP_Init(m_config, 2))
|
if (OKAY != SCSP_Init(m_config, 2))
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
@ -514,8 +529,10 @@ CSoundBoard::CSoundBoard(const Util::Config::Node &config)
|
||||||
memoryPool = NULL;
|
memoryPool = NULL;
|
||||||
ram1 = NULL;
|
ram1 = NULL;
|
||||||
ram2 = NULL;
|
ram2 = NULL;
|
||||||
audioL = NULL;
|
audioFL = NULL;
|
||||||
audioR = NULL;
|
audioFR = NULL;
|
||||||
|
audioRL = NULL;
|
||||||
|
audioRR = NULL;
|
||||||
soundROM = NULL;
|
soundROM = NULL;
|
||||||
sampleROM = NULL;
|
sampleROM = NULL;
|
||||||
|
|
||||||
|
@ -553,8 +570,10 @@ CSoundBoard::~CSoundBoard(void)
|
||||||
}
|
}
|
||||||
ram1 = NULL;
|
ram1 = NULL;
|
||||||
ram2 = NULL;
|
ram2 = NULL;
|
||||||
audioL = NULL;
|
audioFL = NULL;
|
||||||
audioR = NULL;
|
audioFR = NULL;
|
||||||
|
audioRL = NULL;
|
||||||
|
audioRR = NULL;
|
||||||
soundROM = NULL;
|
soundROM = NULL;
|
||||||
sampleROM = NULL;
|
sampleROM = NULL;
|
||||||
|
|
||||||
|
|
|
@ -203,7 +203,8 @@ private:
|
||||||
UINT8 ctrlReg; // control register: ROM banking
|
UINT8 ctrlReg; // control register: ROM banking
|
||||||
|
|
||||||
// Audio
|
// Audio
|
||||||
INT16 *audioL, *audioR; // left and right audio channels (1/60th second, 44.1 KHz)
|
INT16* audioFL, * audioFR; // left and right front audio channels (1/60th second, 44.1 KHz)
|
||||||
|
INT16* audioRL, * audioRR; // left and right rear audio channels (1/60th second, 44.1 KHz)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -29,26 +29,29 @@
|
||||||
#define INCLUDED_AUDIO_H
|
#define INCLUDED_AUDIO_H
|
||||||
|
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
#include "Util/NewConfig.h"
|
||||||
|
#include "Game.h"
|
||||||
|
|
||||||
typedef void (*AudioCallbackFPtr)(void *data);
|
typedef void (*AudioCallbackFPtr)(void *data);
|
||||||
|
|
||||||
extern void SetAudioCallback(AudioCallbackFPtr callback, void *data);
|
extern void SetAudioCallback(AudioCallbackFPtr callback, void *data);
|
||||||
|
|
||||||
extern void SetAudioEnabled(bool enabled);
|
extern void SetAudioEnabled(bool enabled);
|
||||||
|
extern void SetAudioType(Game::AudioTypes type);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OpenAudio()
|
* OpenAudio()
|
||||||
*
|
*
|
||||||
* Initializes the audio system.
|
* Initializes the audio system.
|
||||||
*/
|
*/
|
||||||
extern bool OpenAudio();
|
extern bool OpenAudio(const Util::Config::Node& config);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OutputAudio(unsigned numSamples, *INT16 leftBuffer, *INT16 rightBuffer)
|
* OutputAudio(unsigned numSamples, *INT16 leftBuffer, *INT16 rightBuffer)
|
||||||
*
|
*
|
||||||
* Sends a chunk of two-channel audio with the given number of samples to the audio system.
|
* Sends a chunk of two-channel audio with the given number of samples to the audio system.
|
||||||
*/
|
*/
|
||||||
extern bool OutputAudio(unsigned numSamples, INT16 *leftBuffer, INT16 *rightBuffer, bool flipStereo);
|
extern bool OutputAudio(unsigned numSamples, INT16* leftFrontBuffer, INT16* rightFrontBuffer, INT16* leftRearBuffer, INT16* rightRearBuffer, bool flipStereo);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CloseAudio()
|
* CloseAudio()
|
||||||
|
|
|
@ -104,3 +104,12 @@ void COutputs::SetValue(EOutputs output, UINT8 value)
|
||||||
if (firstSet || value != prevValue)
|
if (firstSet || value != prevValue)
|
||||||
SendOutput(output, prevValue, value);
|
SendOutput(output, prevValue, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool COutputs::HasValue(EOutputs output)
|
||||||
|
{
|
||||||
|
int idx = (unsigned)output;
|
||||||
|
if (idx < 0 || idx >= NUM_OUTPUTS)
|
||||||
|
return false;
|
||||||
|
return !m_first[output];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,14 @@ public:
|
||||||
*/
|
*/
|
||||||
void SetValue(EOutputs output, UINT8 value);
|
void SetValue(EOutputs output, UINT8 value);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HasValue(EOutputs output)
|
||||||
|
*
|
||||||
|
* Returns if the value has been set at least once,
|
||||||
|
* meaning it is used by the game.
|
||||||
|
*/
|
||||||
|
bool HasValue(EOutputs output);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/*
|
/*
|
||||||
* COutputs():
|
* COutputs():
|
||||||
|
|
|
@ -28,6 +28,29 @@
|
||||||
* defined to encompass both channels so for, e.g., 16-bit audio as used here,
|
* defined to encompass both channels so for, e.g., 16-bit audio as used here,
|
||||||
* a sample is 4 bytes. Static assertions are employed to ensure that the
|
* a sample is 4 bytes. Static assertions are employed to ensure that the
|
||||||
* initial set up of the buffer is correct.
|
* initial set up of the buffer is correct.
|
||||||
|
*
|
||||||
|
* Model 3 Audio is always 4 channels. SCSP1 is usually for each front
|
||||||
|
* channels (on CN8 connector) and SCSP2 for rear channels (on CN7).
|
||||||
|
* The downmix to 2 channels will be performed here in case supermodel audio
|
||||||
|
* subsystem does not allow such playback.
|
||||||
|
* The default DSB board is supposed to be plug and mixed with the front output
|
||||||
|
* channel. The rear channel is usually plugged to the gullbow speakers that
|
||||||
|
* are present in most model 3 racing cabinets, while front speakers are only
|
||||||
|
* present in Daytona2, Scud Race, Sega Rally 2.
|
||||||
|
* As each cabinet as its own wiring, with different mixing, the games.xml
|
||||||
|
* database will provide which can of mixing should be applied for each game.
|
||||||
|
*
|
||||||
|
* From twin uk cabinet diagrams, at least:
|
||||||
|
* - lemans24: only stereo on rear speakers (gullbox) on front channels SCSP1/CN8.
|
||||||
|
* - scud race: DSB mixed with SCSP2/CN7 for rear (gullbox) speakers, front
|
||||||
|
* connected to SCSP1/CN8.
|
||||||
|
* - daytona2: front on SCSP1/CN8, rear on SCSP2/CN7
|
||||||
|
* - srally2: SCSP2/CN7 gives left/right, and SCSP1/CN8 is split in 2 channels:
|
||||||
|
* mono front, mono rear. These two channels are them mixed with L/R to give
|
||||||
|
* the quad output.
|
||||||
|
* - oceanhun: SCSP1/CN8 and SCSP2/CN7 are mixed together for stereo output.
|
||||||
|
* Others are unknown so far, but it is expected that most Step 2.x games should
|
||||||
|
* have quad output.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Audio.h"
|
#include "Audio.h"
|
||||||
|
@ -38,16 +61,38 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
// Model3 audio output is 44.1KHz 2-channel sound and frame rate is 60fps
|
// Model3 audio output is 44.1KHz 4-channel sound and frame rate is 60fps
|
||||||
#define SAMPLE_RATE 44100
|
#define SAMPLE_RATE_M3 (44100)
|
||||||
#define NUM_CHANNELS 2
|
#define SUPERMODEL_FPS (60.0f)
|
||||||
#define SUPERMODEL_FPS 60
|
#define MODEL3_FPS (57.53f)
|
||||||
|
|
||||||
#define BYTES_PER_SAMPLE (NUM_CHANNELS * sizeof(INT16))
|
#define MAX_SND_FREQ (75)
|
||||||
#define SAMPLES_PER_FRAME (SAMPLE_RATE / SUPERMODEL_FPS)
|
#define MIN_SND_FREQ (45)
|
||||||
#define BYTES_PER_FRAME (SAMPLES_PER_FRAME * BYTES_PER_SAMPLE)
|
#define MAX_LATENCY (100)
|
||||||
|
|
||||||
#define MAX_LATENCY 100
|
#define NUM_CHANNELS_M3 (4)
|
||||||
|
|
||||||
|
Game::AudioTypes AudioType;
|
||||||
|
int nbHostAudioChannels = NUM_CHANNELS_M3; // Number of channels on host
|
||||||
|
|
||||||
|
#define SAMPLES_PER_FRAME_M3 (INT32)(SAMPLE_RATE_M3 / MODEL3_FPS)
|
||||||
|
|
||||||
|
#define BYTES_PER_SAMPLE_M3 (NUM_CHANNELS_M3 * sizeof(INT16))
|
||||||
|
#define BYTES_PER_FRAME_M3 (SAMPLES_PER_FRAME_M3 * BYTES_PER_SAMPLE_M3)
|
||||||
|
|
||||||
|
|
||||||
|
static int samples_per_frame_host = SAMPLES_PER_FRAME_M3;
|
||||||
|
static int bytes_per_sample_host = BYTES_PER_SAMPLE_M3;
|
||||||
|
static int bytes_per_frame_host = BYTES_PER_FRAME_M3;
|
||||||
|
|
||||||
|
// Balance percents for mixer
|
||||||
|
float BalanceLeftRight = 0; // 0 mid balance, 100: left only, -100:right only
|
||||||
|
float BalanceFrontRear = 0; // 0 mid balance, 100: front only, -100:right only
|
||||||
|
// Mixer factor (depends on values above)
|
||||||
|
float balanceFactorFrontLeft = 1.0f;
|
||||||
|
float balanceFactorFrontRight = 1.0f;
|
||||||
|
float balanceFactorRearLeft = 1.0f;
|
||||||
|
float balanceFactorRearRight = 1.0f;
|
||||||
|
|
||||||
static bool enabled = true; // True if sound output is enabled
|
static bool enabled = true; // True if sound output is enabled
|
||||||
static constexpr unsigned latency = 20; // Audio latency to use (ie size of audio buffer) as percentage of max buffer size
|
static constexpr unsigned latency = 20; // Audio latency to use (ie size of audio buffer) as percentage of max buffer size
|
||||||
|
@ -69,6 +114,9 @@ static unsigned overRuns = 0; // Number of buffer over-runs that have occu
|
||||||
static AudioCallbackFPtr callback = NULL; // Pointer to audio callback that is called when audio buffer is less than half empty
|
static AudioCallbackFPtr callback = NULL; // Pointer to audio callback that is called when audio buffer is less than half empty
|
||||||
static void* callbackData = NULL; // Pointer to data to be passed to audio callback when it is called
|
static void* callbackData = NULL; // Pointer to data to be passed to audio callback when it is called
|
||||||
|
|
||||||
|
static const Util::Config::Node* s_config = 0;
|
||||||
|
|
||||||
|
|
||||||
void SetAudioCallback(AudioCallbackFPtr newCallback, void* newData)
|
void SetAudioCallback(AudioCallbackFPtr newCallback, void* newData)
|
||||||
{
|
{
|
||||||
// Lock audio whilst changing callback pointers
|
// Lock audio whilst changing callback pointers
|
||||||
|
@ -85,6 +133,27 @@ void SetAudioEnabled(bool newEnabled)
|
||||||
enabled = newEnabled;
|
enabled = newEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set game audio mixing type
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type"></param>
|
||||||
|
void SetAudioType(Game::AudioTypes type)
|
||||||
|
{
|
||||||
|
AudioType = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static INT16 AddAndClampINT16(INT32 x, INT32 y)
|
||||||
|
{
|
||||||
|
INT32 sum = x + y;
|
||||||
|
if (sum > INT16_MAX) {
|
||||||
|
sum = INT16_MAX;
|
||||||
|
}
|
||||||
|
if (sum < INT16_MIN) {
|
||||||
|
sum = INT16_MIN;
|
||||||
|
}
|
||||||
|
return (INT16)sum;
|
||||||
|
}
|
||||||
|
|
||||||
static void PlayCallback(void* data, Uint8* stream, int len)
|
static void PlayCallback(void* data, Uint8* stream, int len)
|
||||||
{
|
{
|
||||||
//printf("PlayCallback(%d) [writePos = %u, writeWrapped = %s, playPos = %u, audioBufferSize = %u]\n",
|
//printf("PlayCallback(%d) [writePos = %u, writeWrapped = %s, playPos = %u, audioBufferSize = %u]\n",
|
||||||
|
@ -107,7 +176,7 @@ static void PlayCallback(void *data, Uint8 *stream, int len)
|
||||||
if (underRunLoop)
|
if (underRunLoop)
|
||||||
{
|
{
|
||||||
// If loop, then move play position back to beginning of data in buffer
|
// If loop, then move play position back to beginning of data in buffer
|
||||||
playPos = adjWritePos + BYTES_PER_FRAME;
|
playPos = adjWritePos + bytes_per_frame_host;
|
||||||
|
|
||||||
// Check if play position has moved past end of buffer
|
// Check if play position has moved past end of buffer
|
||||||
if (playPos >= audioBufferSize)
|
if (playPos >= audioBufferSize)
|
||||||
|
@ -175,7 +244,7 @@ static void PlayCallback(void *data, Uint8 *stream, int len)
|
||||||
// Move play position forward for next time
|
// Move play position forward for next time
|
||||||
playPos += len;
|
playPos += len;
|
||||||
|
|
||||||
bool bufferFull = adjWritePos + 2 * BYTES_PER_FRAME > playPos + audioBufferSize;
|
bool bufferFull = adjWritePos + 2 * bytes_per_frame_host > playPos + audioBufferSize;
|
||||||
|
|
||||||
// Check if play position has moved past end of buffer
|
// Check if play position has moved past end of buffer
|
||||||
if (playPos >= audioBufferSize)
|
if (playPos >= audioBufferSize)
|
||||||
|
@ -190,31 +259,135 @@ static void PlayCallback(void *data, Uint8 *stream, int len)
|
||||||
callback(callbackData);
|
callback(callbackData);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MixChannels(unsigned numSamples, INT16 *leftBuffer, INT16 *rightBuffer, void *dest, bool flipStereo)
|
static void MixChannels(unsigned numSamples, INT16* leftFrontBuffer, INT16* rightFrontBuffer, INT16* leftRearBuffer, INT16* rightRearBuffer, void* dest, bool flipStereo)
|
||||||
{
|
{
|
||||||
INT16* p = (INT16*)dest;
|
INT16* p = (INT16*)dest;
|
||||||
|
|
||||||
#if (NUM_CHANNELS == 1)
|
if (nbHostAudioChannels == 1) {
|
||||||
for (unsigned i = 0; i < numSamples; i++)
|
for (unsigned i = 0; i < numSamples; i++) {
|
||||||
*p++ = leftBuffer[i] + rightBuffer[i]; // TODO: these should probably be clipped!
|
INT16 monovalue = AddAndClampINT16(
|
||||||
#else
|
(INT32)(leftFrontBuffer[i] * balanceFactorFrontLeft) + (INT32)(rightFrontBuffer[i] * balanceFactorFrontRight),
|
||||||
|
(INT32)(leftRearBuffer[i] * balanceFactorRearLeft) + (INT32)(rightRearBuffer[i] * balanceFactorRearRight));
|
||||||
|
*p++ = monovalue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Flip again left/right if configured in audio
|
||||||
|
switch (AudioType) {
|
||||||
|
case Game::STEREO_RL:
|
||||||
|
case Game::QUAD_1_FRL_2_RRL:
|
||||||
|
case Game::QUAD_1_RRL_2_FRL:
|
||||||
|
flipStereo = !flipStereo;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now order channels according to audio type
|
||||||
|
if (nbHostAudioChannels == 2) {
|
||||||
|
for (unsigned i = 0; i < numSamples; i++) {
|
||||||
|
INT16 leftvalue = AddAndClampINT16((INT32)(leftFrontBuffer[i] * balanceFactorFrontLeft), (INT32)(leftRearBuffer[i] * balanceFactorRearLeft));
|
||||||
|
INT16 rightvalue = AddAndClampINT16((INT32)(rightFrontBuffer[i]*balanceFactorFrontRight), (INT32)(rightRearBuffer[i]*balanceFactorRearRight));
|
||||||
if (flipStereo) // swap left and right channels
|
if (flipStereo) // swap left and right channels
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < numSamples; i++)
|
*p++ = rightvalue;
|
||||||
|
*p++ = leftvalue;
|
||||||
|
} else {
|
||||||
|
*p++ = leftvalue;
|
||||||
|
*p++ = rightvalue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (nbHostAudioChannels == 4) {
|
||||||
|
for (unsigned i = 0; i < numSamples; i++) {
|
||||||
|
INT16 frontLeftValue = (INT16)(leftFrontBuffer[i]*balanceFactorFrontLeft);
|
||||||
|
INT16 frontRightValue = (INT16)(rightFrontBuffer[i]*balanceFactorFrontRight);
|
||||||
|
INT16 rearLeftValue = (INT16)(leftRearBuffer[i]*balanceFactorRearLeft);
|
||||||
|
INT16 rearRightValue = (INT16)(rightRearBuffer[i]*balanceFactorRearRight);
|
||||||
|
|
||||||
|
// Check game audio type
|
||||||
|
switch (AudioType) {
|
||||||
|
case Game::MONO: {
|
||||||
|
INT16 monovalue = AddAndClampINT16(AddAndClampINT16(frontLeftValue, frontRightValue), AddAndClampINT16(rearLeftValue, rearRightValue));
|
||||||
|
*p++ = monovalue;
|
||||||
|
*p++ = monovalue;
|
||||||
|
*p++ = monovalue;
|
||||||
|
*p++ = monovalue;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Game::STEREO_LR:
|
||||||
|
case Game::STEREO_RL: {
|
||||||
|
INT16 leftvalue = AddAndClampINT16(frontLeftValue, frontRightValue);
|
||||||
|
INT16 rightvalue = AddAndClampINT16(rearLeftValue, rearRightValue);
|
||||||
|
if (flipStereo) // swap left and right channels
|
||||||
{
|
{
|
||||||
*p++ = rightBuffer[i];
|
*p++ = rightvalue;
|
||||||
*p++ = leftBuffer[i];
|
*p++ = leftvalue;
|
||||||
|
*p++ = rightvalue;
|
||||||
|
*p++ = leftvalue;
|
||||||
|
} else {
|
||||||
|
*p++ = leftvalue;
|
||||||
|
*p++ = rightvalue;
|
||||||
|
*p++ = leftvalue;
|
||||||
|
*p++ = rightvalue;
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
else // correct stereo
|
|
||||||
|
case Game::QUAD_1_FLR_2_RLR:
|
||||||
|
case Game::QUAD_1_FRL_2_RRL: {
|
||||||
|
// Normal channels Front Left/Right then Rear Left/Right
|
||||||
|
if (flipStereo) // swap left and right channels
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < numSamples; i++)
|
*p++ = frontRightValue;
|
||||||
|
*p++ = frontLeftValue;
|
||||||
|
*p++ = rearRightValue;
|
||||||
|
*p++ = rearLeftValue;
|
||||||
|
} else {
|
||||||
|
*p++ = frontLeftValue;
|
||||||
|
*p++ = frontRightValue;
|
||||||
|
*p++ = rearLeftValue;
|
||||||
|
*p++ = rearRightValue;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Game::QUAD_1_RLR_2_FLR:
|
||||||
|
case Game::QUAD_1_RRL_2_FRL:
|
||||||
|
// Reversed channels Front/Rear Left then Front/Rear Right
|
||||||
|
if (flipStereo) // swap left and right channels
|
||||||
{
|
{
|
||||||
*p++ = leftBuffer[i];
|
*p++ = rearRightValue;
|
||||||
*p++ = rightBuffer[i];
|
*p++ = rearLeftValue;
|
||||||
|
*p++ = frontRightValue;
|
||||||
|
*p++ = frontLeftValue;
|
||||||
|
} else {
|
||||||
|
*p++ = rearLeftValue;
|
||||||
|
*p++ = rearRightValue;
|
||||||
|
*p++ = frontLeftValue;
|
||||||
|
*p++ = frontRightValue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Game::QUAD_1_LR_2_FR_MIX:
|
||||||
|
// Split mix: one goes to left/right, other front/rear (mono)
|
||||||
|
// =>Remix all!
|
||||||
|
INT16 newfrontLeftValue = AddAndClampINT16(frontLeftValue, rearLeftValue);
|
||||||
|
INT16 newfrontRightValue = AddAndClampINT16(frontLeftValue, rearRightValue);
|
||||||
|
INT16 newrearLeftValue = AddAndClampINT16(frontRightValue, rearLeftValue);
|
||||||
|
INT16 newrearRightValue = AddAndClampINT16(frontRightValue, rearRightValue);
|
||||||
|
|
||||||
|
if (flipStereo) // swap left and right channels
|
||||||
|
{
|
||||||
|
*p++ = newfrontRightValue;
|
||||||
|
*p++ = newfrontLeftValue;
|
||||||
|
*p++ = newrearRightValue;
|
||||||
|
*p++ = newrearLeftValue;
|
||||||
|
} else {
|
||||||
|
*p++ = newfrontLeftValue;
|
||||||
|
*p++ = newfrontRightValue;
|
||||||
|
*p++ = newrearLeftValue;
|
||||||
|
*p++ = newrearRightValue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // NUM_CHANNELS
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -228,35 +401,96 @@ static void LogAudioInfo(SDL_AudioSpec *fmt)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool OpenAudio()
|
/// <summary>
|
||||||
|
/// Prepare audio subsystem on host.
|
||||||
|
/// The requested channels is deduced, and SDL will make sure it is compatible with this.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="config"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool OpenAudio(const Util::Config::Node& config)
|
||||||
{
|
{
|
||||||
|
s_config = &config;
|
||||||
// Initialize SDL audio sub-system
|
// Initialize SDL audio sub-system
|
||||||
if (SDL_InitSubSystem(SDL_INIT_AUDIO) != 0)
|
if (SDL_InitSubSystem(SDL_INIT_AUDIO) != 0)
|
||||||
return ErrorLog("Unable to initialize SDL audio sub-system: %s\n", SDL_GetError());
|
return ErrorLog("Unable to initialize SDL audio sub-system: %s\n", SDL_GetError());
|
||||||
|
|
||||||
// Set up audio specification
|
// Number of channels requested in config (default is 4)
|
||||||
SDL_AudioSpec fmt;
|
nbHostAudioChannels = (int)s_config->Get("NbSoundChannels").ValueAs<int>();
|
||||||
memset(&fmt, 0, sizeof(SDL_AudioSpec));
|
|
||||||
fmt.freq = SAMPLE_RATE;
|
|
||||||
fmt.channels = NUM_CHANNELS;
|
|
||||||
fmt.format = AUDIO_S16SYS;
|
|
||||||
fmt.samples = playSamples;
|
|
||||||
fmt.callback = PlayCallback;
|
|
||||||
|
|
||||||
// Force SDL to use the format we requested; it will convert if necessary
|
// If game is only stereo or mono, enforce host to reduce number of channels
|
||||||
if (SDL_OpenAudio(&fmt, nullptr) < 0)
|
switch (AudioType) {
|
||||||
|
case Game::MONO:
|
||||||
|
nbHostAudioChannels = std::min(nbHostAudioChannels, 1);
|
||||||
|
break;
|
||||||
|
case Game::STEREO_LR:
|
||||||
|
case Game::STEREO_RL:
|
||||||
|
nbHostAudioChannels = std::min(nbHostAudioChannels, 2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Mixer Balance
|
||||||
|
float balancelr = (float)s_config->Get("BalanceLeftRight").ValueAs<float>();
|
||||||
|
if (balancelr < -100.0f)
|
||||||
|
balancelr = -100.0f;
|
||||||
|
else if (balancelr > 100.0f)
|
||||||
|
balancelr = 100.0f;
|
||||||
|
balancelr *= 0.01f;
|
||||||
|
BalanceLeftRight = balancelr;
|
||||||
|
|
||||||
|
float balancefr = (float)s_config->Get("BalanceFrontRear").ValueAs<float>();
|
||||||
|
if (balancefr < -100.0f)
|
||||||
|
balancefr = -100.0f;
|
||||||
|
else if (balancefr > 100.0f)
|
||||||
|
balancefr = 100.0f;
|
||||||
|
balancefr *= 0.01f;
|
||||||
|
BalanceFrontRear = balancefr;
|
||||||
|
|
||||||
|
balanceFactorFrontLeft = (BalanceLeftRight < 0.f ? 1.f + BalanceLeftRight : 1.f) * (BalanceFrontRear < 0 ? 1.f + BalanceFrontRear : 1.f);
|
||||||
|
balanceFactorFrontRight = (BalanceLeftRight > 0.f ? 1.f - BalanceLeftRight : 1.f) * (BalanceFrontRear < 0 ? 1.f + BalanceFrontRear : 1.f);
|
||||||
|
balanceFactorRearLeft = (BalanceLeftRight < 0.f ? 1.f + BalanceLeftRight : 1.f) * (BalanceFrontRear > 0 ? 1.f - BalanceFrontRear : 1.f);
|
||||||
|
balanceFactorRearRight = (BalanceLeftRight > 0.f ? 1.f - BalanceLeftRight : 1.f) * (BalanceFrontRear > 0 ? 1.f - BalanceFrontRear : 1.f);
|
||||||
|
|
||||||
|
// Set up audio specification
|
||||||
|
SDL_AudioSpec desired;
|
||||||
|
memset(&desired, 0, sizeof(SDL_AudioSpec));
|
||||||
|
desired.freq = SAMPLE_RATE_M3;
|
||||||
|
// Number of host channels to use (choice limited to 1,2,4)
|
||||||
|
desired.channels = nbHostAudioChannels;
|
||||||
|
desired.format = AUDIO_S16SYS;
|
||||||
|
desired.samples = playSamples;
|
||||||
|
desired.callback = PlayCallback;
|
||||||
|
|
||||||
|
// Now force SDL to use the format we requested (nullptr); it will convert if necessary
|
||||||
|
if (SDL_OpenAudio(&desired, nullptr) < 0) {
|
||||||
|
if (desired.channels==2) {
|
||||||
return ErrorLog("Unable to open 44.1KHz 2-channel audio with SDL: %s\n", SDL_GetError());
|
return ErrorLog("Unable to open 44.1KHz 2-channel audio with SDL: %s\n", SDL_GetError());
|
||||||
|
} else if (desired.channels==4) {
|
||||||
|
return ErrorLog("Unable to open 44.1KHz 4-channel audio with SDL: %s\n", SDL_GetError());
|
||||||
|
} else {
|
||||||
|
return ErrorLog("Unable to open 44.1KHz channel audio with SDL: %s\n", SDL_GetError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float soundFreq_Hz = (float)s_config->Get("SoundFreq").ValueAs<float>();
|
||||||
|
if (soundFreq_Hz>MAX_SND_FREQ)
|
||||||
|
soundFreq_Hz = MAX_SND_FREQ;
|
||||||
|
if (soundFreq_Hz<MIN_SND_FREQ)
|
||||||
|
soundFreq_Hz = MIN_SND_FREQ;
|
||||||
|
samples_per_frame_host = (INT32)(SAMPLE_RATE_M3 / soundFreq_Hz);
|
||||||
|
bytes_per_sample_host = (nbHostAudioChannels * sizeof(INT16));
|
||||||
|
bytes_per_frame_host = (samples_per_frame_host * bytes_per_sample_host);
|
||||||
|
|
||||||
|
|
||||||
// Create audio buffer
|
// Create audio buffer
|
||||||
constexpr uint32_t bufferSize = SAMPLE_RATE * BYTES_PER_SAMPLE * latency / MAX_LATENCY;
|
uint32_t bufferSize = ((SAMPLE_RATE_M3 * latency) / MAX_LATENCY) * bytes_per_sample_host;
|
||||||
static_assert(bufferSize % BYTES_PER_SAMPLE == 0, "must be an integer multiple of the sample size");
|
if (!(bufferSize % bytes_per_sample_host == 0)) {
|
||||||
|
return ErrorLog("must be an integer multiple of the sample size\n");
|
||||||
|
}
|
||||||
audioBufferSize = bufferSize;
|
audioBufferSize = bufferSize;
|
||||||
|
|
||||||
int minBufferSize = 3 * BYTES_PER_FRAME;
|
int minBufferSize = 3 * bytes_per_frame_host;
|
||||||
audioBufferSize = std::max<int>(minBufferSize, audioBufferSize);
|
audioBufferSize = std::max<int>(minBufferSize, audioBufferSize);
|
||||||
audioBuffer = new(std::nothrow) INT8[audioBufferSize];
|
audioBuffer = new(std::nothrow) INT8[audioBufferSize];
|
||||||
if (audioBuffer == NULL)
|
if (audioBuffer == NULL) {
|
||||||
{
|
|
||||||
float audioBufMB = (float)audioBufferSize / (float)0x100000;
|
float audioBufMB = (float)audioBufferSize / (float)0x100000;
|
||||||
return ErrorLog("Insufficient memory for audio latency buffer (need %1.1f MB).", audioBufMB);
|
return ErrorLog("Insufficient memory for audio latency buffer (need %1.1f MB).", audioBufMB);
|
||||||
}
|
}
|
||||||
|
@ -264,12 +498,17 @@ bool OpenAudio()
|
||||||
|
|
||||||
// Set initial play position to be beginning of buffer and initial write position to be half-way into buffer
|
// Set initial play position to be beginning of buffer and initial write position to be half-way into buffer
|
||||||
playPos = 0;
|
playPos = 0;
|
||||||
constexpr uint32_t endOfBuffer = bufferSize - BYTES_PER_FRAME;
|
uint32_t endOfBuffer = bufferSize - bytes_per_frame_host;
|
||||||
constexpr uint32_t midpointAfterFirstFrameUnaligned = BYTES_PER_FRAME + (bufferSize - BYTES_PER_FRAME) / 2;
|
uint32_t midpointAfterFirstFrameUnaligned = bytes_per_frame_host + (bufferSize - bytes_per_frame_host) / 2;
|
||||||
constexpr uint32_t extraPaddingNeeded = (BYTES_PER_SAMPLE - midpointAfterFirstFrameUnaligned % BYTES_PER_SAMPLE) % BYTES_PER_SAMPLE;
|
uint32_t extraPaddingNeeded = (bytes_per_frame_host - midpointAfterFirstFrameUnaligned % bytes_per_frame_host) % bytes_per_frame_host;
|
||||||
constexpr uint32_t midpointAfterFirstFrame = midpointAfterFirstFrameUnaligned + extraPaddingNeeded;
|
uint32_t midpointAfterFirstFrame = midpointAfterFirstFrameUnaligned + extraPaddingNeeded;
|
||||||
static_assert(endOfBuffer % BYTES_PER_SAMPLE == 0, "make sure we are aligned to a sample boundary otherwise underrun/overrun adjustment will end up shifting playback by one channel causing stereo to flip");
|
if (!((endOfBuffer % (nbHostAudioChannels*sizeof(INT16))) == 0)) {
|
||||||
static_assert(midpointAfterFirstFrame % BYTES_PER_SAMPLE == 0,"error");
|
return ErrorLog("must be an integer multiple of the sample size\n");
|
||||||
|
}
|
||||||
|
if (!((midpointAfterFirstFrame % nbHostAudioChannels*sizeof(INT16)) == 0)) {
|
||||||
|
return ErrorLog("must be an integer multiple of the sample size\n");
|
||||||
|
}
|
||||||
|
|
||||||
writePos = std::min<int>(endOfBuffer, midpointAfterFirstFrame);
|
writePos = std::min<int>(endOfBuffer, midpointAfterFirstFrame);
|
||||||
writeWrapped = false;
|
writeWrapped = false;
|
||||||
|
|
||||||
|
@ -282,7 +521,7 @@ bool OpenAudio()
|
||||||
return OKAY;
|
return OKAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OutputAudio(unsigned numSamples, INT16 *leftBuffer, INT16 *rightBuffer, bool flipStereo)
|
bool OutputAudio(unsigned numSamples, INT16* leftFrontBuffer, INT16* rightFrontBuffer, INT16* leftRearBuffer, INT16* rightRearBuffer, bool flipStereo)
|
||||||
{
|
{
|
||||||
//printf("OutputAudio(%u) [writePos = %u, writeWrapped = %s, playPos = %u, audioBufferSize = %u]\n",
|
//printf("OutputAudio(%u) [writePos = %u, writeWrapped = %s, playPos = %u, audioBufferSize = %u]\n",
|
||||||
// numSamples, writePos, (writeWrapped ? "true" : "false"), playPos, audioBufferSize);
|
// numSamples, writePos, (writeWrapped ? "true" : "false"), playPos, audioBufferSize);
|
||||||
|
@ -292,21 +531,21 @@ bool OutputAudio(unsigned numSamples, INT16 *leftBuffer, INT16 *rightBuffer, boo
|
||||||
INT16* src;
|
INT16* src;
|
||||||
|
|
||||||
// Number of samples should never be more than max number of samples per frame
|
// Number of samples should never be more than max number of samples per frame
|
||||||
if (numSamples > SAMPLES_PER_FRAME)
|
if (numSamples > (unsigned)samples_per_frame_host)
|
||||||
numSamples = SAMPLES_PER_FRAME;
|
numSamples = samples_per_frame_host;
|
||||||
|
|
||||||
// Mix together left and right channels into single chunk of data
|
// Mix together left and right channels into single chunk of data
|
||||||
INT16 mixBuffer[NUM_CHANNELS * SAMPLES_PER_FRAME];
|
INT16 mixBuffer[NUM_CHANNELS_M3 * (SAMPLE_RATE_M3 / MIN_SND_FREQ)];
|
||||||
MixChannels(numSamples, leftBuffer, rightBuffer, mixBuffer, flipStereo);
|
MixChannels(numSamples, leftFrontBuffer, rightFrontBuffer, leftRearBuffer, rightRearBuffer, mixBuffer, flipStereo);
|
||||||
|
|
||||||
// Lock SDL audio callback so that it doesn't interfere with following code
|
// Lock SDL audio callback so that it doesn't interfere with following code
|
||||||
SDL_LockAudio();
|
SDL_LockAudio();
|
||||||
|
|
||||||
// Calculate number of bytes for current sound chunk
|
// Calculate number of bytes for current sound chunk
|
||||||
UINT32 numBytes = numSamples * BYTES_PER_SAMPLE;
|
UINT32 numBytes = numSamples * bytes_per_sample_host;
|
||||||
|
|
||||||
// Get end of current play region (writing must occur past this point)
|
// Get end of current play region (writing must occur past this point)
|
||||||
UINT32 playEndPos = playPos + BYTES_PER_FRAME;
|
UINT32 playEndPos = playPos + bytes_per_frame_host;
|
||||||
|
|
||||||
// Undo any wrap-around of the write position that may have occured to create following ordering: playPos < playEndPos < writePos
|
// Undo any wrap-around of the write position that may have occured to create following ordering: playPos < playEndPos < writePos
|
||||||
if (playEndPos > writePos && writeWrapped)
|
if (playEndPos > writePos && writeWrapped)
|
||||||
|
@ -324,7 +563,7 @@ bool OutputAudio(unsigned numSamples, INT16 *leftBuffer, INT16 *rightBuffer, boo
|
||||||
if (underRunLoop)
|
if (underRunLoop)
|
||||||
{
|
{
|
||||||
// If loop, then move play position back to beginning of data in buffer
|
// If loop, then move play position back to beginning of data in buffer
|
||||||
playPos = writePos + numBytes + BYTES_PER_FRAME;
|
playPos = writePos + numBytes + bytes_per_frame_host;
|
||||||
|
|
||||||
// Check if play position has moved past end of buffer
|
// Check if play position has moved past end of buffer
|
||||||
if (playPos >= audioBufferSize)
|
if (playPos >= audioBufferSize)
|
||||||
|
@ -351,7 +590,7 @@ bool OutputAudio(unsigned numSamples, INT16 *leftBuffer, INT16 *rightBuffer, boo
|
||||||
// Check if write position has caught up with play region and now overlaps it (ie buffer over-run)
|
// Check if write position has caught up with play region and now overlaps it (ie buffer over-run)
|
||||||
bool overRun = writePos + numBytes > playPos + audioBufferSize;
|
bool overRun = writePos + numBytes > playPos + audioBufferSize;
|
||||||
|
|
||||||
bool bufferFull = writePos + 2 * BYTES_PER_FRAME > playPos + audioBufferSize;
|
bool bufferFull = writePos + 2 * bytes_per_frame_host > playPos + audioBufferSize;
|
||||||
|
|
||||||
// Move write position back to within buffer
|
// Move write position back to within buffer
|
||||||
if (writePos >= audioBufferSize)
|
if (writePos >= audioBufferSize)
|
||||||
|
|
|
@ -58,16 +58,17 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
#ifdef SUPERMODEL_WIN32
|
||||||
|
#include "DirectInputSystem.h"
|
||||||
|
#include "WinOutputs.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "Supermodel.h"
|
#include "Supermodel.h"
|
||||||
#include "Util/Format.h"
|
#include "Util/Format.h"
|
||||||
#include "Util/NewConfig.h"
|
#include "Util/NewConfig.h"
|
||||||
#include "Util/ConfigBuilders.h"
|
#include "Util/ConfigBuilders.h"
|
||||||
#include "GameLoader.h"
|
#include "GameLoader.h"
|
||||||
#include "SDLInputSystem.h"
|
#include "SDLInputSystem.h"
|
||||||
#ifdef SUPERMODEL_WIN32
|
|
||||||
#include "DirectInputSystem.h"
|
|
||||||
#include "WinOutputs.h"
|
|
||||||
#endif
|
|
||||||
#include "SDLIncludes.h"
|
#include "SDLIncludes.h"
|
||||||
#include "Debugger/SupermodelDebugger.h"
|
#include "Debugger/SupermodelDebugger.h"
|
||||||
#include "Graphics/Legacy3D/Legacy3D.h"
|
#include "Graphics/Legacy3D/Legacy3D.h"
|
||||||
|
@ -91,7 +92,7 @@ static Util::Config::Node s_runtime_config("Global");
|
||||||
Display Management
|
Display Management
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
static SDL_Window *s_window = nullptr;
|
SDL_Window *s_window = nullptr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Position and size of rectangular region within OpenGL display to render to.
|
* Position and size of rectangular region within OpenGL display to render to.
|
||||||
|
@ -837,7 +838,7 @@ static void SuperSleep(UINT32 time)
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#ifdef SUPERMODEL_DEBUGGER
|
#ifdef SUPERMODEL_DEBUGGER
|
||||||
int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *Inputs, COutputs *Outputs, std::shared_ptr<Debugger::CDebugger> Debugger)
|
int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *Inputs, COutputs *Outputs, IScripting* scripting, std::shared_ptr<Debugger::CDebugger> Debugger)
|
||||||
{
|
{
|
||||||
std::shared_ptr<CLogger> oldLogger;
|
std::shared_ptr<CLogger> oldLogger;
|
||||||
#else
|
#else
|
||||||
|
@ -880,7 +881,8 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
|
||||||
PrintGLInfo(false, true, false);
|
PrintGLInfo(false, true, false);
|
||||||
|
|
||||||
// Initialize audio system
|
// Initialize audio system
|
||||||
if (OKAY != OpenAudio())
|
SetAudioType(game.audio);
|
||||||
|
if (OKAY != OpenAudio(s_runtime_config))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// Hide mouse if fullscreen, enable crosshairs for gun games
|
// Hide mouse if fullscreen, enable crosshairs for gun games
|
||||||
|
@ -1388,6 +1390,10 @@ static Util::Config::Node DefaultConfig()
|
||||||
// CSoundBoard
|
// CSoundBoard
|
||||||
config.Set("EmulateSound", true);
|
config.Set("EmulateSound", true);
|
||||||
config.Set("Balance", "0");
|
config.Set("Balance", "0");
|
||||||
|
config.Set("BalanceLeftRight", "0");
|
||||||
|
config.Set("BalanceFrontRear", "0");
|
||||||
|
config.Set("NbSoundChannels", "4");
|
||||||
|
config.Set("SoundFreq", "57.6"); // 60.0f? 57.524160f?
|
||||||
// CDSB
|
// CDSB
|
||||||
config.Set("EmulateDSB", true);
|
config.Set("EmulateDSB", true);
|
||||||
config.Set("SoundVolume", "100");
|
config.Set("SoundVolume", "100");
|
||||||
|
@ -1454,8 +1460,8 @@ static Util::Config::Node DefaultConfig()
|
||||||
static void Title(void)
|
static void Title(void)
|
||||||
{
|
{
|
||||||
puts("Supermodel: A Sega Model 3 Arcade Emulator (Version " SUPERMODEL_VERSION ")");
|
puts("Supermodel: A Sega Model 3 Arcade Emulator (Version " SUPERMODEL_VERSION ")");
|
||||||
puts("Copyright 2011-2021 by Bart Trzynadlowski, Nik Henson, Ian Curtis,");
|
puts("Copyright 2011-2022 by Bart Trzynadlowski, Nik Henson, Ian Curtis, Harry Tuttle,");
|
||||||
puts(" Harry Tuttle, and Spindizzi\n");
|
puts(" Spindizzi, gm_mathew and njz3\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Help(void)
|
static void Help(void)
|
||||||
|
@ -1510,6 +1516,7 @@ static void Help(void)
|
||||||
puts(" when Digital Sound Board is present [Default: 100]");
|
puts(" when Digital Sound Board is present [Default: 100]");
|
||||||
puts(" -music-volume=<vol> Digital Sound Board volume in % [Default: 100]");
|
puts(" -music-volume=<vol> Digital Sound Board volume in % [Default: 100]");
|
||||||
puts(" -balance=<bal> Relative front/rear balance in % [Default: 0]");
|
puts(" -balance=<bal> Relative front/rear balance in % [Default: 0]");
|
||||||
|
puts(" -channels=<c> Number of sound channels to use on host [Default: 4]");
|
||||||
puts(" -flip-stereo Swap left and right audio channels");
|
puts(" -flip-stereo Swap left and right audio channels");
|
||||||
puts(" -no-sound Disable sound board emulation (sound effects)");
|
puts(" -no-sound Disable sound board emulation (sound effects)");
|
||||||
puts(" -no-dsb Disable Digital Sound Board (MPEG music)");
|
puts(" -no-dsb Disable Digital Sound Board (MPEG music)");
|
||||||
|
@ -1585,6 +1592,8 @@ static ParsedCommandLine ParseCommandLine(int argc, char **argv)
|
||||||
{ "-sound-volume", "SoundVolume" },
|
{ "-sound-volume", "SoundVolume" },
|
||||||
{ "-music-volume", "MusicVolume" },
|
{ "-music-volume", "MusicVolume" },
|
||||||
{ "-balance", "Balance" },
|
{ "-balance", "Balance" },
|
||||||
|
{ "-channels", "NbSoundChannels" },
|
||||||
|
{ "-soundfreq", "SoundFreq" },
|
||||||
{ "-input-system", "InputSystem" },
|
{ "-input-system", "InputSystem" },
|
||||||
{ "-outputs", "Outputs" },
|
{ "-outputs", "Outputs" },
|
||||||
{ "-log-output", "LogOutput" },
|
{ "-log-output", "LogOutput" },
|
||||||
|
|
|
@ -57,6 +57,7 @@ CWinOutputs::~CWinOutputs()
|
||||||
// Broadcast a shutdown message
|
// Broadcast a shutdown message
|
||||||
if (m_hwnd)
|
if (m_hwnd)
|
||||||
PostMessage(HWND_BROADCAST, m_onStop, (WPARAM)m_hwnd, 0);
|
PostMessage(HWND_BROADCAST, m_onStop, (WPARAM)m_hwnd, 0);
|
||||||
|
DeleteWindowClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWinOutputs::Initialize()
|
bool CWinOutputs::Initialize()
|
||||||
|
@ -143,7 +144,19 @@ bool CWinOutputs::CreateWindowClass()
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
bool CWinOutputs::DeleteWindowClass()
|
||||||
|
{
|
||||||
|
if (!s_createdClass)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Register class
|
||||||
|
if (UnregisterClass(OUTPUT_WINDOW_CLASS, GetModuleHandle(NULL))) {
|
||||||
|
s_createdClass = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
bool CWinOutputs::AllocateMessageId(UINT ®Id, LPCSTR str)
|
bool CWinOutputs::AllocateMessageId(UINT ®Id, LPCSTR str)
|
||||||
{
|
{
|
||||||
regId = RegisterWindowMessage(str);
|
regId = RegisterWindowMessage(str);
|
||||||
|
|
|
@ -94,6 +94,7 @@ private:
|
||||||
* Registers the window class and sets up OutputWindowProcCallback to process all messages sent to the emulator window.
|
* Registers the window class and sets up OutputWindowProcCallback to process all messages sent to the emulator window.
|
||||||
*/
|
*/
|
||||||
static bool CreateWindowClass();
|
static bool CreateWindowClass();
|
||||||
|
static bool DeleteWindowClass();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OutputWindowProcCallback(hwnd, msg, wParam, lParam):
|
* OutputWindowProcCallback(hwnd, msg, wParam, lParam):
|
||||||
|
|
|
@ -89,12 +89,15 @@ bool legacySound; // For LegacySound (SCSP DSP) config option.
|
||||||
// These globals control the operation of the SCSP, they are no longer extern and are set through SCSP_SetBuffers(). --Bart
|
// These globals control the operation of the SCSP, they are no longer extern and are set through SCSP_SetBuffers(). --Bart
|
||||||
float SoundClock; // Originally titled SysFPS; seems to be for the sound CPU.
|
float SoundClock; // Originally titled SysFPS; seems to be for the sound CPU.
|
||||||
const float Freq = 76;
|
const float Freq = 76;
|
||||||
signed short *bufferl;
|
signed short* bufferfl;
|
||||||
signed short *bufferr;
|
signed short* bufferfr;
|
||||||
|
signed short* bufferrl;
|
||||||
|
signed short* bufferrr;
|
||||||
int length;
|
int length;
|
||||||
int cnts;
|
int cnts;
|
||||||
|
|
||||||
signed int *buffertmpl,*buffertmpr; // these are allocated inside this file
|
signed int* buffertmpfl, * buffertmpfr; // these are allocated inside this file
|
||||||
|
signed int* buffertmprl, * buffertmprr; // these are allocated inside this file
|
||||||
|
|
||||||
unsigned int srate=44100;
|
unsigned int srate=44100;
|
||||||
|
|
||||||
|
@ -759,19 +762,32 @@ bool SCSP_Init(const Util::Config::Node &config, int n)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LFO_Init();
|
LFO_Init();
|
||||||
buffertmpl = NULL;
|
buffertmpfl = NULL;
|
||||||
buffertmpr = NULL;
|
buffertmpfr = NULL;
|
||||||
buffertmpl=(signed int*) malloc(44100*sizeof(signed int));
|
buffertmprl = NULL;
|
||||||
if (NULL == buffertmpl)
|
buffertmprr = NULL;
|
||||||
|
buffertmpfl=(signed int*) malloc(44100*sizeof(signed int));
|
||||||
|
if (NULL == buffertmpfl)
|
||||||
return ErrorLog("Insufficient memory for internal SCSP buffers.");
|
return ErrorLog("Insufficient memory for internal SCSP buffers.");
|
||||||
buffertmpr=(signed int*) malloc(44100*sizeof(signed int));
|
buffertmpfr=(signed int*) malloc(44100*sizeof(signed int));
|
||||||
if (NULL == buffertmpl)
|
if (NULL == buffertmpfr)
|
||||||
{
|
{
|
||||||
free(buffertmpl);
|
free(buffertmpfr);
|
||||||
return ErrorLog("Insufficient memory for internal SCSP buffers.");
|
return ErrorLog("Insufficient memory for internal SCSP buffers.");
|
||||||
}
|
}
|
||||||
memset(buffertmpl,0,44100*sizeof(signed int));
|
|
||||||
memset(buffertmpr,0,44100*sizeof(signed int));
|
buffertmprl=(signed int*)malloc(44100*sizeof(signed int));
|
||||||
|
if (NULL == buffertmprl)
|
||||||
|
return ErrorLog("Insufficient memory for internal SCSP buffers.");
|
||||||
|
buffertmprr=(signed int*)malloc(44100*sizeof(signed int));
|
||||||
|
if (NULL == buffertmprr)
|
||||||
|
return ErrorLog("Insufficient memory for internal SCSP buffers.");
|
||||||
|
|
||||||
|
|
||||||
|
memset(buffertmpfl, 0, 44100*sizeof(signed int));
|
||||||
|
memset(buffertmpfr, 0, 44100*sizeof(signed int));
|
||||||
|
memset(buffertmprl, 0, 44100*sizeof(signed int));
|
||||||
|
memset(buffertmprr, 0, 44100*sizeof(signed int));
|
||||||
SCSPs->data[0x20 / 2] = 0;
|
SCSPs->data[0x20 / 2] = 0;
|
||||||
TimCnt[0] = 0xffff;
|
TimCnt[0] = 0xffff;
|
||||||
TimCnt[1] = 0xffff;
|
TimCnt[1] = 0xffff;
|
||||||
|
@ -781,8 +797,10 @@ bool SCSP_Init(const Util::Config::Node &config, int n)
|
||||||
MIDILock = CThread::CreateMutex();
|
MIDILock = CThread::CreateMutex();
|
||||||
if (NULL == MIDILock)
|
if (NULL == MIDILock)
|
||||||
{
|
{
|
||||||
free(buffertmpl);
|
free(buffertmpfl);
|
||||||
free(buffertmpr);
|
free(buffertmpfr);
|
||||||
|
free(buffertmprl);
|
||||||
|
free(buffertmprr);
|
||||||
return ErrorLog("Unable to create MIDI mutex!");
|
return ErrorLog("Unable to create MIDI mutex!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1544,19 +1562,23 @@ void SCSP_DoMasterSamples(int nsamples)
|
||||||
balance /= 100.0f;
|
balance /= 100.0f;
|
||||||
float masterBalance = 1.0f + balance;
|
float masterBalance = 1.0f + balance;
|
||||||
float slaveBalance = 1.0f - balance;
|
float slaveBalance = 1.0f - balance;
|
||||||
signed short *bufl, *bufr;
|
signed short* buffl, * buffr;
|
||||||
|
signed short* bufrl, * bufrr;
|
||||||
|
|
||||||
INT32 sl, s, i;
|
INT32 sl, s, i;
|
||||||
|
|
||||||
bufl = bufferl;
|
buffl = bufferfl;
|
||||||
bufr = bufferr;
|
buffr = bufferfr;
|
||||||
|
bufrl = bufferrl;
|
||||||
|
bufrr = bufferrr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate samples
|
* Generate samples
|
||||||
*/
|
*/
|
||||||
for (s = 0; s < nsamples; ++s)
|
for (s = 0; s < nsamples; ++s)
|
||||||
{
|
{
|
||||||
signed int smpl = 0, smpr = 0;
|
signed int smpfl = 0, smpfr = 0;
|
||||||
|
signed int smprl = 0, smprr = 0;
|
||||||
|
|
||||||
for (sl = 0; sl < 32; ++sl)
|
for (sl = 0; sl < 32; ++sl)
|
||||||
{
|
{
|
||||||
|
@ -1578,12 +1600,12 @@ void SCSP_DoMasterSamples(int nsamples)
|
||||||
SCSPDSP_SetSample(&SCSPs[0].DSP, (sample*LPANTABLE[Enc]) >> (SHIFT - 2), ISEL(slot), IMXL(slot));
|
SCSPDSP_SetSample(&SCSPs[0].DSP, (sample*LPANTABLE[Enc]) >> (SHIFT - 2), ISEL(slot), IMXL(slot));
|
||||||
Enc = ((TL(slot)) << 0x0) | ((DIPAN(slot)) << 0x8) | ((DISDL(slot)) << 0xd);
|
Enc = ((TL(slot)) << 0x0) | ((DIPAN(slot)) << 0x8) | ((DISDL(slot)) << 0xd);
|
||||||
#ifdef RB_VOLUME
|
#ifdef RB_VOLUME
|
||||||
smpl += (sample * volume[TL(slot) + pan_left[DIPAN(slot)]]) >> 17;
|
smpfl += (sample * volume[TL(slot) + pan_left[DIPAN(slot)]]) >> 17;
|
||||||
smpr += (sample * volume[TL(slot) + pan_right[DIPAN(slot)]]) >> 17;
|
smpfr += (sample * volume[TL(slot) + pan_right[DIPAN(slot)]]) >> 17;
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
smpl += (sample*LPANTABLE[Enc]) >> SHIFT;
|
smpfl += (sample*LPANTABLE[Enc]) >> SHIFT;
|
||||||
smpr += (sample*RPANTABLE[Enc]) >> SHIFT;
|
smpfr += (sample*RPANTABLE[Enc]) >> SHIFT;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1615,11 +1637,11 @@ void SCSP_DoMasterSamples(int nsamples)
|
||||||
Enc = ((TL(slot)) << 0x0) | ((DIPAN(slot)) << 0x8) | ((DISDL(slot)) << 0xd);
|
Enc = ((TL(slot)) << 0x0) | ((DIPAN(slot)) << 0x8) | ((DISDL(slot)) << 0xd);
|
||||||
{
|
{
|
||||||
#ifdef RB_VOLUME
|
#ifdef RB_VOLUME
|
||||||
smpl += (sample * volume[TL(slot) + pan_left[DIPAN(slot)]]) >> 17;
|
smprl += (sample * volume[TL(slot) + pan_left[DIPAN(slot)]]) >> 17;
|
||||||
smpr += (sample * volume[TL(slot) + pan_right[DIPAN(slot)]]) >> 17;
|
smprr += (sample * volume[TL(slot) + pan_right[DIPAN(slot)]]) >> 17;
|
||||||
#else
|
#else
|
||||||
smpl += (sample*LPANTABLE[Enc]) >> SHIFT;
|
smprl += (sample*LPANTABLE[Enc]) >> SHIFT;
|
||||||
smpr += (sample*RPANTABLE[Enc]) >> SHIFT;
|
smprr += (sample*RPANTABLE[Enc]) >> SHIFT;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1650,8 +1672,8 @@ void SCSP_DoMasterSamples(int nsamples)
|
||||||
{
|
{
|
||||||
// For legacy option, 14 is the most reasonable value I can set at the moment for the EFSDL slot. - Paul
|
// For legacy option, 14 is the most reasonable value I can set at the moment for the EFSDL slot. - Paul
|
||||||
UINT16 Enc = ((EFPAN(slot)) << 0x8) | ((EFSDL(slot)) << 0xe);
|
UINT16 Enc = ((EFPAN(slot)) << 0x8) | ((EFSDL(slot)) << 0xe);
|
||||||
smpl += (int)(masterBalance*(float)(((SCSPs[0].DSP.EFREG[i] * LPANTABLE[Enc]) >> SHIFT)));
|
smpfl += (int)(masterBalance*(float)(((SCSPs[0].DSP.EFREG[i] * LPANTABLE[Enc]) >> SHIFT)));
|
||||||
smpr += (int)(masterBalance*(float)(((SCSPs[0].DSP.EFREG[i] * RPANTABLE[Enc]) >> SHIFT)));
|
smpfr += (int)(masterBalance*(float)(((SCSPs[0].DSP.EFREG[i] * RPANTABLE[Enc]) >> SHIFT)));
|
||||||
}
|
}
|
||||||
if (HasSlaveSCSP)
|
if (HasSlaveSCSP)
|
||||||
{
|
{
|
||||||
|
@ -1659,8 +1681,8 @@ void SCSP_DoMasterSamples(int nsamples)
|
||||||
if (EFSDL(slot))
|
if (EFSDL(slot))
|
||||||
{
|
{
|
||||||
UINT16 Enc = ((EFPAN(slot)) << 0x8) | ((EFSDL(slot)) << 0xe);
|
UINT16 Enc = ((EFPAN(slot)) << 0x8) | ((EFSDL(slot)) << 0xe);
|
||||||
smpl += (int)(slaveBalance*(float)(((SCSPs[1].DSP.EFREG[i] * LPANTABLE[Enc]) >> SHIFT)));
|
smprl += (int)(slaveBalance*(float)(((SCSPs[1].DSP.EFREG[i] * LPANTABLE[Enc]) >> SHIFT)));
|
||||||
smpr += (int)(slaveBalance*(float)(((SCSPs[1].DSP.EFREG[i] * RPANTABLE[Enc]) >> SHIFT)));
|
smprr += (int)(slaveBalance*(float)(((SCSPs[1].DSP.EFREG[i] * RPANTABLE[Enc]) >> SHIFT)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1668,8 +1690,8 @@ void SCSP_DoMasterSamples(int nsamples)
|
||||||
if (EFSDL(slot))
|
if (EFSDL(slot))
|
||||||
{
|
{
|
||||||
UINT16 Enc = ((EFPAN(slot)) << 0x8) | ((EFSDL(slot)) << 0xd);
|
UINT16 Enc = ((EFPAN(slot)) << 0x8) | ((EFSDL(slot)) << 0xd);
|
||||||
smpl += (int)(masterBalance*(float)(((SCSPs[0].DSP.EFREG[i] * LPANTABLE[Enc]) >> SHIFT)));
|
smpfl += (int)(masterBalance*(float)(((SCSPs[0].DSP.EFREG[i] * LPANTABLE[Enc]) >> SHIFT)));
|
||||||
smpr += (int)(masterBalance*(float)(((SCSPs[0].DSP.EFREG[i] * RPANTABLE[Enc]) >> SHIFT)));
|
smpfr += (int)(masterBalance*(float)(((SCSPs[0].DSP.EFREG[i] * RPANTABLE[Enc]) >> SHIFT)));
|
||||||
}
|
}
|
||||||
if (HasSlaveSCSP)
|
if (HasSlaveSCSP)
|
||||||
{
|
{
|
||||||
|
@ -1677,26 +1699,41 @@ void SCSP_DoMasterSamples(int nsamples)
|
||||||
if (EFSDL(slot))
|
if (EFSDL(slot))
|
||||||
{
|
{
|
||||||
UINT16 Enc = ((EFPAN(slot)) << 0x8) | ((EFSDL(slot)) << 0xd);
|
UINT16 Enc = ((EFPAN(slot)) << 0x8) | ((EFSDL(slot)) << 0xd);
|
||||||
smpl += (int)(slaveBalance*(float)(((SCSPs[1].DSP.EFREG[i] * LPANTABLE[Enc]) >> SHIFT)));
|
smprl += (int)(slaveBalance*(float)(((SCSPs[1].DSP.EFREG[i] * LPANTABLE[Enc]) >> SHIFT)));
|
||||||
smpr += (int)(slaveBalance*(float)(((SCSPs[1].DSP.EFREG[i] * RPANTABLE[Enc]) >> SHIFT)));
|
smprr += (int)(slaveBalance*(float)(((SCSPs[1].DSP.EFREG[i] * RPANTABLE[Enc]) >> SHIFT)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DAC18B(SCSP))
|
if (DAC18B((&SCSP[0])))
|
||||||
{
|
{
|
||||||
smpl = ICLIP18(smpl);
|
smpfl = ICLIP18(smpfl);
|
||||||
smpr = ICLIP18(smpr);
|
smpfr = ICLIP18(smpfr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
smpl = ICLIP16(smpl >> 2);
|
smpfl = ICLIP16(smpfl >> 2);
|
||||||
smpr = ICLIP16(smpr >> 2);
|
smpfr = ICLIP16(smpfr >> 2);
|
||||||
}
|
}
|
||||||
*bufl++ = ICLIP16(smpl);
|
*buffl++ = ICLIP16(smpfl);
|
||||||
*bufr++ = ICLIP16(smpr);
|
*buffr++ = ICLIP16(smpfr);
|
||||||
|
|
||||||
|
if (HasSlaveSCSP)
|
||||||
|
{
|
||||||
|
if (DAC18B((&SCSPs[1])))
|
||||||
|
{
|
||||||
|
smprl = ICLIP18(smprl);
|
||||||
|
smprr = ICLIP18(smprr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
smprl = ICLIP16(smprl >> 2);
|
||||||
|
smprr = ICLIP16(smprr >> 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*bufrl++ = ICLIP16(smprl);
|
||||||
|
*bufrr++ = ICLIP16(smprr);
|
||||||
|
|
||||||
SCSP_TimersAddTicks(1);
|
SCSP_TimersAddTicks(1);
|
||||||
CheckPendingIRQ();
|
CheckPendingIRQ();
|
||||||
|
@ -2107,11 +2144,14 @@ void SCSP_LoadState(CBlockFile *StateFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SCSP_SetBuffers(INT16 *leftBufferPtr, INT16 *rightBufferPtr, int bufferLength)
|
void SCSP_SetBuffers(INT16 *leftBufferPtr, INT16 *rightBufferPtr, INT16* leftRearBufferPtr, INT16* rightRearBufferPtr, int bufferLength)
|
||||||
{
|
{
|
||||||
SoundClock = 76;
|
SoundClock = 76;
|
||||||
bufferl = leftBufferPtr;
|
bufferfl = leftBufferPtr;
|
||||||
bufferr = rightBufferPtr;
|
bufferfr = rightBufferPtr;
|
||||||
|
bufferrl = leftRearBufferPtr;
|
||||||
|
bufferrr = rightRearBufferPtr;
|
||||||
|
|
||||||
length = bufferLength;
|
length = bufferLength;
|
||||||
cnts = 0; // what is this for? seems unimportant but need to find out
|
cnts = 0; // what is this for? seems unimportant but need to find out
|
||||||
}
|
}
|
||||||
|
@ -2121,10 +2161,14 @@ void SCSP_Deinit(void)
|
||||||
#ifdef USEDSP
|
#ifdef USEDSP
|
||||||
free(SCSP->MIXBuf);
|
free(SCSP->MIXBuf);
|
||||||
#endif
|
#endif
|
||||||
free(buffertmpl);
|
free(buffertmpfl);
|
||||||
free(buffertmpr);
|
free(buffertmpfr);
|
||||||
|
free(buffertmprl);
|
||||||
|
free(buffertmprr);
|
||||||
delete MIDILock;
|
delete MIDILock;
|
||||||
buffertmpl = NULL;
|
buffertmpfl = NULL;
|
||||||
buffertmpr = NULL;
|
buffertmpfr = NULL;
|
||||||
|
buffertmprl = NULL;
|
||||||
|
buffertmprr = NULL;
|
||||||
MIDILock = NULL;
|
MIDILock = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ UINT32 SCSP_Slave_r32(UINT32 addr);
|
||||||
// Supermodel interface functions
|
// Supermodel interface functions
|
||||||
void SCSP_SaveState(CBlockFile *StateFile);
|
void SCSP_SaveState(CBlockFile *StateFile);
|
||||||
void SCSP_LoadState(CBlockFile *StateFile);
|
void SCSP_LoadState(CBlockFile *StateFile);
|
||||||
void SCSP_SetBuffers(INT16 *leftBufferPtr, INT16 *rightBufferPtr, int bufferLength);
|
void SCSP_SetBuffers(INT16 *leftBufferPtr, INT16 *rightBufferPtr, INT16* leftRearBufferPtr, INT16* rightRearBufferPtr, int bufferLength);
|
||||||
void SCSP_Deinit(void);
|
void SCSP_Deinit(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,28 +21,29 @@
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
<ProjectGuid>{1248CF7C-B122-461C-9624-196AEFAE5046}</ProjectGuid>
|
<ProjectGuid>{1248CF7C-B122-461C-9624-196AEFAE5046}</ProjectGuid>
|
||||||
<RootNamespace>Musashi68K</RootNamespace>
|
<RootNamespace>Musashi68K</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
|
|
@ -22,24 +22,24 @@
|
||||||
<ProjectName>SDL2</ProjectName>
|
<ProjectName>SDL2</ProjectName>
|
||||||
<ProjectGuid>{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}</ProjectGuid>
|
<ProjectGuid>{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}</ProjectGuid>
|
||||||
<RootNamespace>SDL</RootNamespace>
|
<RootNamespace>SDL</RootNamespace>
|
||||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
<ImportGroup Label="ExtensionSettings">
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
|
|
@ -22,24 +22,24 @@
|
||||||
<ProjectName>SDL2main</ProjectName>
|
<ProjectName>SDL2main</ProjectName>
|
||||||
<ProjectGuid>{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}</ProjectGuid>
|
<ProjectGuid>{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}</ProjectGuid>
|
||||||
<RootNamespace>SDLmain</RootNamespace>
|
<RootNamespace>SDLmain</RootNamespace>
|
||||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
<ImportGroup Label="ExtensionSettings">
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
|
|
@ -22,24 +22,24 @@
|
||||||
<ProjectName>SDL2_net</ProjectName>
|
<ProjectName>SDL2_net</ProjectName>
|
||||||
<ProjectGuid>{8AB3504F-5E58-4910-AFE8-7A1E595AC3F4}</ProjectGuid>
|
<ProjectGuid>{8AB3504F-5E58-4910-AFE8-7A1E595AC3F4}</ProjectGuid>
|
||||||
<RootNamespace>SDL_net</RootNamespace>
|
<RootNamespace>SDL_net</RootNamespace>
|
||||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
<ImportGroup Label="ExtensionSettings">
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
|
|
@ -22,29 +22,29 @@
|
||||||
<ProjectGuid>{B114BBD9-8AEA-4DAE-B367-A66A804CB3DD}</ProjectGuid>
|
<ProjectGuid>{B114BBD9-8AEA-4DAE-B367-A66A804CB3DD}</ProjectGuid>
|
||||||
<RootNamespace>Supermodel</RootNamespace>
|
<RootNamespace>Supermodel</RootNamespace>
|
||||||
<Keyword>Win32Proj</Keyword>
|
<Keyword>Win32Proj</Keyword>
|
||||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
|
|
@ -25,22 +25,22 @@
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
<UseOfMfc>false</UseOfMfc>
|
<UseOfMfc>false</UseOfMfc>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
<UseOfMfc>false</UseOfMfc>
|
<UseOfMfc>false</UseOfMfc>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
<UseOfMfc>false</UseOfMfc>
|
<UseOfMfc>false</UseOfMfc>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
<UseOfMfc>false</UseOfMfc>
|
<UseOfMfc>false</UseOfMfc>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
|
Loading…
Reference in a new issue