mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-21 05:09:34 -06:00
MusicMod: Moved it from Branches to Externals, I guess there usually is no Branches dir in the trunk dir, so this may look a little better
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2174 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
341
Externals/MusicMod/Main/Src/Main.cpp
vendored
Normal file
341
Externals/MusicMod/Main/Src/Main.cpp
vendored
Normal file
@ -0,0 +1,341 @@
|
||||
// Copyright (C) 2003-2008 Dolphin Project.
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, version 2.0.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License 2.0 for more details.
|
||||
|
||||
// A copy of the GPL 2.0 should have been included with the program.
|
||||
// If not, see http://www.gnu.org/licenses/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <windows.h>
|
||||
|
||||
#include "Common.h" // Common
|
||||
#include "IniFile.h"
|
||||
#include "ConsoleWindow.h"
|
||||
|
||||
#include "PowerPC/PowerPc.h" // Core
|
||||
|
||||
#include "../../../../Source/Core/DiscIO/Src/FileSystemGCWii.h" // This file has #include "Filesystem.h"
|
||||
#include "../../../../Source/Core/DiscIO/Src/VolumeCreator.h"
|
||||
|
||||
#include "../../Player/Src/PlayerExport.h" // Local player
|
||||
//////////////////////////////////
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Declarations and definitions
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
namespace MusicMod
|
||||
{
|
||||
|
||||
struct MyFilesStructure
|
||||
{
|
||||
std::string path;
|
||||
int offset; // Is int enough, how high does offset go?
|
||||
};
|
||||
|
||||
std::vector <MyFilesStructure> MyFiles;
|
||||
void StructSort (std::vector <MyFilesStructure> &MyFiles);
|
||||
|
||||
|
||||
// Playback
|
||||
std::string CurrentFile;
|
||||
std::string CurrentPlayFile;
|
||||
std::string CurrentPlayFilePath;
|
||||
std::string unique_gameid;
|
||||
|
||||
std::string MusicPath;
|
||||
|
||||
DiscIO::CFileSystemGCWii* my_pFileSystem;
|
||||
|
||||
int WritingFile = false;
|
||||
bool dllloaded = false;
|
||||
|
||||
extern bool bShowConsole; // Externally define
|
||||
extern int GlobalVolume;
|
||||
//////////////////////////////////
|
||||
|
||||
|
||||
// =======================================================================================
|
||||
// Supported music files
|
||||
// ---------------------------------------------------------------------------------------
|
||||
bool CheckFileEnding(std::string FileName)
|
||||
{
|
||||
if (
|
||||
(FileName.find(".adp") != std::string::npos) // 1080 Avalanche, Crash Bandicoot etc
|
||||
|| (FileName.find(".afc") != std::string::npos) // Zelda WW
|
||||
|| (FileName.find(".ast") != std::string::npos) // Zelda TP, Mario Kart
|
||||
|| (FileName.find(".dsp") != std::string::npos) // Metroid Prime
|
||||
|| (FileName.find(".hps") != std::string::npos) // SSB Melee
|
||||
)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
// =======================================================================================
|
||||
|
||||
|
||||
// =======================================================================================
|
||||
// A function to sort the filelist table after offset
|
||||
// ------------------------
|
||||
void StructSort (std::vector <MyFilesStructure> &MyFiles)
|
||||
{
|
||||
MyFilesStructure temp;
|
||||
|
||||
//Console::Print("StructSort > Begin\n");
|
||||
|
||||
for(int i = 0; i < MyFiles.size() - 1; i++)
|
||||
{
|
||||
for (int j = i + 1; j < MyFiles.size(); j++)
|
||||
{
|
||||
if (MyFiles[ i ].offset > MyFiles[ j ].offset) //comparing cost
|
||||
{
|
||||
temp = MyFiles[ i ]; // Swapping entire struct
|
||||
MyFiles[ i ] = MyFiles[ j ];
|
||||
MyFiles[ j ] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (long i=1; i<(long)MyFiles.size(); ++i)
|
||||
{
|
||||
std::cout << i << " " << MyFiles[i].path.c_str() << "#" << MyFiles[i].offset << "\n";
|
||||
}
|
||||
|
||||
//Console::Print("StructSort > Done\n");
|
||||
}
|
||||
// ============================
|
||||
|
||||
|
||||
// =======================================================================================
|
||||
/* Run these things once */
|
||||
// ------------------------
|
||||
void ShowConsole()
|
||||
{
|
||||
Console::Open(100, 2000, "MusicMod", true); // Give room for 2000 rows
|
||||
}
|
||||
|
||||
void Init()
|
||||
{
|
||||
// These things below will not need to be updated after a new game is started
|
||||
if (dllloaded) return;
|
||||
|
||||
// ---------------------------------------
|
||||
// Load config
|
||||
// ---------------------
|
||||
IniFile file;
|
||||
file.Load("Plainamp.ini");
|
||||
file.Get("Interface", "ShowConsole", &MusicMod::bShowConsole, false);
|
||||
file.Get("Plainamp", "Volume", &MusicMod::GlobalVolume, 125);
|
||||
// -------
|
||||
|
||||
// ---------------------------------------
|
||||
// Make a debugging window
|
||||
// ---------------------
|
||||
if(MusicMod::bShowConsole) ShowConsole();
|
||||
|
||||
// Write version
|
||||
#ifdef _M_X64
|
||||
Console::Print("64 bit version\n");
|
||||
#else
|
||||
Console::Print("32 bit version\n");
|
||||
#endif
|
||||
// -----------
|
||||
|
||||
// Set volume
|
||||
Player_Volume(MusicMod::GlobalVolume);
|
||||
|
||||
// Show DLL status
|
||||
Player_Main(MusicMod::bShowConsole);
|
||||
//play_file("c:\\demo36_02.ast");
|
||||
//Console::Print("DLL loaded\n");
|
||||
|
||||
dllloaded = true; // Do this once
|
||||
}
|
||||
// ============================
|
||||
|
||||
|
||||
// =======================================================================================
|
||||
/* This will read the GC file system. */
|
||||
// ------------------------
|
||||
void Main(std::string FileName)
|
||||
{
|
||||
//
|
||||
DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(FileName.c_str());
|
||||
|
||||
//
|
||||
my_pFileSystem = new DiscIO::CFileSystemGCWii(pVolume);
|
||||
|
||||
/* We have to sort the files according to offset so that out scan in Blob.cpp works.
|
||||
Because StructSort() only works for MyFilesStructure I copy the offset and filenames
|
||||
to a new vetor first. */
|
||||
MyFiles.resize(my_pFileSystem->m_FileInfoVector.size()); // Set size
|
||||
for (size_t i = 0; i < my_pFileSystem->m_FileInfoVector.size(); i++)
|
||||
{
|
||||
MyFiles.at(i).offset = my_pFileSystem->m_FileInfoVector.at(i).m_Offset;
|
||||
MyFiles.at(i).path = my_pFileSystem->m_FileInfoVector.at(i).m_FullPath;
|
||||
}
|
||||
|
||||
// Sort the files by offset
|
||||
StructSort(MyFiles);
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// Make Music directory
|
||||
// -------------------------
|
||||
LPSECURITY_ATTRIBUTES attr;
|
||||
attr = NULL;
|
||||
MusicPath = "Music\\";
|
||||
Console::Print("Created a Music directory\n");
|
||||
CreateDirectory(MusicPath.c_str(), attr);
|
||||
// ----------------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
|
||||
// =======================================================================================
|
||||
// Check if we should play this file
|
||||
// ---------------------------------------------------------------------------------------
|
||||
void CheckFile(std::string File, int FileNumber)
|
||||
{
|
||||
// Do nothing if we found the same file again
|
||||
if (CurrentFile == File) return;
|
||||
|
||||
//Console::Print(">>>> (%i)Current read %s <%u = %ux%i> <block %u>\n", i, CurrentFiles[i].path.c_str(), offset, CurrentFiles[i].offset, size);
|
||||
|
||||
// Check if it's a music file
|
||||
if (CheckFileEnding(File.c_str()))
|
||||
{
|
||||
/* Don't restart the playback if we find the same music file again. If the game is playing
|
||||
a streaming music file it may read from it once in a while, after it has read other
|
||||
files in between, if did not do this check we would restart the playback in those cases */
|
||||
if (CurrentPlayFile == File) return;
|
||||
|
||||
// Notify the user
|
||||
Console::Print("\n >>> (%i/%i) Match %s\n\n", FileNumber, MyFiles.size(), File.c_str());
|
||||
|
||||
// Save the matched file
|
||||
CurrentPlayFile = File;
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// We will now save the file to the PC hard drive
|
||||
// ------------------
|
||||
// Get the filename
|
||||
std::size_t pointer = File.find_last_of("\\");
|
||||
std::string fragment = File.substr (0, (pointer-0));
|
||||
int compare = File.length() - fragment.length(); // Get the length of the filename
|
||||
fragment = File.substr ((pointer+1), compare); // Now we have the filename
|
||||
|
||||
// Create the target file path
|
||||
std::string FilePath = (MusicPath + fragment);
|
||||
|
||||
WritingFile = true; // Avoid detecting the file we are writing
|
||||
Console::Print("Writing <%s> to <%s>\n", File.c_str(), FilePath.c_str());
|
||||
my_pFileSystem->ExportFile(File.c_str(), FilePath.c_str());
|
||||
WritingFile = false;
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// Play the file we found
|
||||
// ------------------
|
||||
if(dllloaded)
|
||||
{
|
||||
Player_Play((char*)FilePath.c_str()); // retype it from const char* to char*
|
||||
} else {
|
||||
Console::Print("Warning > Music DLL is not loaded");
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// Remove the last file, if any
|
||||
// ------------------
|
||||
if(CurrentPlayFilePath.length() > 0)
|
||||
{
|
||||
if(!remove(CurrentPlayFilePath.c_str()))
|
||||
{
|
||||
Console::Print("The program failed to remove <%s>\n", CurrentPlayFilePath.c_str());
|
||||
} else {
|
||||
Console::Print("The program removed <%s>\n", CurrentPlayFilePath.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// Save the current playing file
|
||||
// ------------------
|
||||
CurrentPlayFilePath = FilePath; // Save the filename so we can remove it later
|
||||
}
|
||||
|
||||
// Tell the user about the files we ignored
|
||||
Console::Print("(%i/%i) Ignored %s\n", FileNumber, MyFiles.size(), File.c_str());
|
||||
|
||||
// Update the current file
|
||||
CurrentFile = File;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Find the current filename for a certain offset on the GC fileystem
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
void FindFilename(u64 offset, u64 size)
|
||||
{
|
||||
// =======================================================================================
|
||||
/* Only do this test:
|
||||
1. After boot, not on ISO scan
|
||||
2. Not if offset = 0.
|
||||
3. Not when WritingFile. We will lead to calls back to here (Read) and it will mess
|
||||
upp the scanning */
|
||||
if(PowerPC::state == PowerPC::CPUState::CPU_RUNNING && offset != 0 && !WritingFile)
|
||||
{
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
/* Get the filename. Here we go through all files until we come to the file that has
|
||||
the matching offset. Before MyFiles has data this loop will go nowhere. We have to
|
||||
specify (MyFiles.size() - 1) because we will be reading MyFiles.at(i + 1).
|
||||
MyFiles.size() is the amount of files on the disc, and the last file is
|
||||
MyFiles.at(MyFiles.size() - 1) */
|
||||
// ---------------------------------------------------------------------------------------
|
||||
for (int i = 0; i < (int)(MyFiles.size() - 1); ++i)
|
||||
{
|
||||
// ---------------------------------------------------------------------------------------
|
||||
/* If we assume that myoffset is the begginning of every file this works.
|
||||
Suppose there are three files
|
||||
1 is 0 to 149
|
||||
2 is 150 to 170
|
||||
3 is 171 to 200
|
||||
If the offset is 160 the game is reading file number two, for example
|
||||
myoffset = 150: (myoffset >= offset) == false
|
||||
myoffset = 171: (myoffset >= offset) == true, break
|
||||
|
||||
However if the offset is 195 the game is reading the last file and we will get
|
||||
myoffset = 171: (myoffset >= offset) == false
|
||||
we therefore need to add the condition (offset > MyFiles[MyFiles.size() - 1].offset)
|
||||
to. */
|
||||
if (MyFiles[i + 1].offset >= offset || offset > MyFiles[MyFiles.size() - 1].offset)
|
||||
{
|
||||
// Now we know that the game is reading from MyFiles[i].path
|
||||
CheckFile(MyFiles[i].path, i);
|
||||
|
||||
// Stop checking
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // This ends the entire filescan
|
||||
// =======================================================================================
|
||||
}
|
||||
/////////////////////////////////
|
||||
|
||||
|
||||
} // end of namespace
|
Reference in New Issue
Block a user