SRB2/tools/SRB2MP/SRB2MP.c

465 lines
9.7 KiB
C
Raw Permalink Normal View History

2014-03-15 16:59:03 +00:00
// SRB2MP.cpp : Defines the entry point for the application.
//
#include "StdAfx.h"
#include "lump.h"
#define APPTITLE "SRB2 Music Player"
#define APPVERSION "v0.1"
#define APPAUTHOR "SSNTails"
#define APPCOMPANY "Sonic Team Junior"
static FSOUND_STREAM *fmus = NULL;
static int fsoundchannel = -1;
static FMUSIC_MODULE *mod = NULL;
static struct wadfile* wfptr = NULL;
static inline VOID M_SetVolume(int volume)
{
if (mod && FMUSIC_GetType(mod) != FMUSIC_TYPE_NONE)
FMUSIC_SetMasterVolume(mod, volume);
if (fsoundchannel != -1)
FSOUND_SetVolume(fsoundchannel, volume);
}
static inline BOOL M_InitMusic(VOID)
{
if (FSOUND_GetVersion() < FMOD_VERSION)
{
printf("Error : You are using the wrong DLL version!\nYou should be using FMOD %.02f\n", FMOD_VERSION);
return FALSE;
}
#ifdef _DEBUG
FSOUND_SetOutput(FSOUND_OUTPUT_WINMM);
#endif
if (!FSOUND_Init(44100, 1, FSOUND_INIT_GLOBALFOCUS))
{
printf("%s\n", FMOD_ErrorString(FSOUND_GetError()));
return FALSE;
}
return TRUE;
}
static inline VOID M_FreeMusic(VOID)
{
if (mod)
{
FMUSIC_StopSong(mod);
FMUSIC_FreeSong(mod);
mod = NULL;
}
if (fmus)
{
FSOUND_Stream_Stop(fmus);
FSOUND_Stream_Close(fmus);
fmus = NULL;
fsoundchannel = -1;
}
}
static inline VOID M_ShutdownMusic(VOID)
{
M_FreeMusic();
FSOUND_Close();
//remove(musicfile); // Delete the temp file
}
static inline VOID M_PauseMusic(VOID)
{
if (mod && !FMUSIC_GetPaused(mod))
FMUSIC_SetPaused(mod, TRUE);
if (fsoundchannel != -1 && FSOUND_IsPlaying(fsoundchannel))
FSOUND_SetPaused(fsoundchannel, TRUE);
}
static inline VOID M_ResumeMusic(VOID)
{
if (mod && FMUSIC_GetPaused(mod))
FMUSIC_SetPaused(mod, FALSE);
if (fsoundchannel != -1 && FSOUND_GetPaused(fsoundchannel))
FSOUND_SetPaused(fsoundchannel, FALSE);
}
static inline VOID M_StopMusic(VOID)
{
if (mod)
FMUSIC_StopSong(mod);
if (fsoundchannel != -1 && fmus && FSOUND_IsPlaying(fsoundchannel))
FSOUND_Stream_Stop(fmus);
}
static inline VOID M_StartFMODSong(LPVOID data, int len, int looping, HWND hDlg)
{
const int loops = FSOUND_LOOP_NORMAL|FSOUND_LOADMEMORY;
const int nloop = FSOUND_LOADMEMORY;
M_FreeMusic();
if (looping)
mod = FMUSIC_LoadSongEx(data, 0, len, loops, NULL, 0);
else
mod = FMUSIC_LoadSongEx(data, 0, len, nloop, NULL, 0);
if (mod)
{
FMUSIC_SetLooping(mod, (signed char)looping);
FMUSIC_SetPanSeperation(mod, 0.0f);
}
else
{
if (looping)
fmus = FSOUND_Stream_Open(data, loops, 0, len);
else
fmus = FSOUND_Stream_Open(data, nloop, 0, len);
}
if (!fmus && !mod)
{
MessageBoxA(hDlg, FMOD_ErrorString(FSOUND_GetError()), "Error", MB_OK|MB_APPLMODAL);
return;
}
// Scan the OGG for the COMMENT= field for a custom loop point
if (looping && fmus)
{
const BYTE *origpos, *dataum = data;
size_t scan, size = len;
CHAR buffer[512];
BOOL titlefound = FALSE, artistfound = FALSE;
unsigned int loopstart = 0;
origpos = dataum;
for(scan = 0; scan < size; scan++)
{
if (!titlefound)
{
if (*dataum++ == 'T')
if (*dataum++ == 'I')
if (*dataum++ == 'T')
if (*dataum++ == 'L')
if (*dataum++ == 'E')
if (*dataum++ == '=')
{
size_t titlecount = 0;
CHAR title[256];
BYTE length = *(dataum-10) - 6;
while(titlecount < length)
title[titlecount++] = *dataum++;
title[titlecount] = '\0';
sprintf(buffer, "Title: %s", title);
SendMessage(GetDlgItem(hDlg, IDC_TITLE), WM_SETTEXT, 0, (LPARAM)(LPCSTR)buffer);
titlefound = TRUE;
}
}
}
dataum = origpos;
for(scan = 0; scan < size; scan++)
{
if (!artistfound)
{
if (*dataum++ == 'A')
if (*dataum++ == 'R')
if (*dataum++ == 'T')
if (*dataum++ == 'I')
if (*dataum++ == 'S')
if (*dataum++ == 'T')
if (*dataum++ == '=')
{
size_t artistcount = 0;
CHAR artist[256];
BYTE length = *(dataum-11) - 7;
while(artistcount < length)
artist[artistcount++] = *dataum++;
artist[artistcount] = '\0';
sprintf(buffer, "By: %s", artist);
SendMessage(GetDlgItem(hDlg, IDC_ARTIST), WM_SETTEXT, 0, (LPARAM)(LPCSTR)buffer);
artistfound = TRUE;
}
}
}
dataum = origpos;
for(scan = 0; scan < size; scan++)
{
if (*dataum++ == 'C'){
if (*dataum++ == 'O'){
if (*dataum++ == 'M'){
if (*dataum++ == 'M'){
if (*dataum++ == 'E'){
if (*dataum++ == 'N'){
if (*dataum++ == 'T'){
if (*dataum++ == '='){
if (*dataum++ == 'L'){
if (*dataum++ == 'O'){
if (*dataum++ == 'O'){
if (*dataum++ == 'P'){
if (*dataum++ == 'P'){
if (*dataum++ == 'O'){
if (*dataum++ == 'I'){
if (*dataum++ == 'N'){
if (*dataum++ == 'T'){
if (*dataum++ == '=')
{
size_t newcount = 0;
CHAR looplength[64];
while (*dataum != 1 && newcount < 63)
{
looplength[newcount++] = *dataum++;
}
looplength[newcount] = '\n';
loopstart = atoi(looplength);
}
else
dataum--;}
else
dataum--;}
else
dataum--;}
else
dataum--;}
else
dataum--;}
else
dataum--;}
else
dataum--;}
else
dataum--;}
else
dataum--;}
else
dataum--;}
else
dataum--;}
else
dataum--;}
else
dataum--;}
else
dataum--;}
else
dataum--;}
else
dataum--;}
else
dataum--;}
}
if (loopstart > 0)
{
const int length = FSOUND_Stream_GetLengthMs(fmus);
const int freq = 44100;
const unsigned int loopend = (unsigned int)((freq/1000.0f)*length-(freq/1000.0f));
if (!FSOUND_Stream_SetLoopPoints(fmus, loopstart, loopend))
{
printf("FMOD(Start,FSOUND_Stream_SetLoopPoints): %s\n",
FMOD_ErrorString(FSOUND_GetError()));
}
}
}
if (mod)
FMUSIC_PlaySong(mod);
if (fmus)
fsoundchannel = FSOUND_Stream_PlayEx(FSOUND_FREE, fmus, NULL, FALSE);
M_SetVolume(128);
}
static inline VOID FreeWADLumps(VOID)
{
M_FreeMusic();
if (wfptr) free_wadfile(wfptr);
wfptr = NULL;
}
static inline VOID ReadWADLumps(LPCSTR WADfilename, HWND hDlg)
{
HWND listbox = GetDlgItem(hDlg, IDC_PLAYLIST);
FILE* f;
struct lumplist *curlump;
SendMessage(listbox, LB_RESETCONTENT, 0, 0);
FreeWADLumps();
f = fopen(WADfilename, "rb");
wfptr = read_wadfile(f);
fclose(f);
/* start of C_LIST */
/* Loop through the lump list, printing lump info */
for(curlump = wfptr->head->next; curlump; curlump = curlump->next)
{
LPCSTR lumpname = get_lump_name(curlump->cl);
if (!strncmp(lumpname, "O_", 2) || !strncmp(lumpname, "D_", 2))
SendMessage(listbox, LB_ADDSTRING, 0, (LPARAM)(LPCSTR)get_lump_name(curlump->cl));
}
/* end of C_LIST */
}
//
// OpenWadfile
//
// Provides a common dialog box
// for selecting the desired wad file.
//
static inline VOID OpenWadfile(HWND hDlg)
{
OPENFILENAMEA ofn;
CHAR FileBuffer[256] = "";
ZeroMemory(&ofn, sizeof(ofn));
ofn.hwndOwner = hDlg;
ofn.lpstrFilter = "WAD Files\0*.wad\0All Files\0*.*\0\0";
ofn.lpstrInitialDir = NULL;
ofn.lpstrFile = FileBuffer;
ofn.lStructSize = sizeof(ofn);
ofn.nMaxFile = sizeof(FileBuffer);
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
if (GetOpenFileNameA(&ofn))
ReadWADLumps(FileBuffer, hDlg);
}
static inline VOID PlayLump(HWND hDlg)
{
HWND listbox = GetDlgItem(hDlg, IDC_PLAYLIST);
LRESULT cursel = SendMessage(listbox, LB_GETCURSEL, 0, 0);
/* Start of C_EXTRACT */
CHAR argv[9];
SendMessage(listbox, LB_GETTEXT, cursel, (LPARAM)(LPCSTR)argv);
/* Extract LUMPNAME FILENAME pairs */
if (wfptr)
{
struct lumplist *extracted;
printf("Extracting lump %s...\n", argv);
/* Find the lump to extract */
extracted = find_previous_lump(wfptr->head, NULL, argv);
if (extracted == NULL || (extracted = extracted->next) == NULL)
return;
/* Extract lump */
M_StartFMODSong(extracted->cl->data, extracted->cl->len, FALSE, hDlg);
/* end of extracting LUMPNAME FILENAME pairs */
} /* end of C_EXTRACT */
return;
}
static LRESULT CALLBACK MainWndproc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return DefWindowProc(hWnd, message, wParam, lParam);
}
static INT_PTR CALLBACK DialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_INITDIALOG:
M_InitMusic();
break;
case WM_CLOSE:
EndDialog(hDlg, message);
break;
case WM_DESTROY:
FreeWADLumps();
M_ShutdownMusic();
break;
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case 2:
EndDialog(hDlg, message);
return TRUE;
case IDC_ABOUT: // The About button.
{
char TempString[256];
sprintf(TempString, "%s %s by %s - %s", APPTITLE, APPVERSION, APPAUTHOR, APPCOMPANY);
MessageBoxA(hDlg, TempString, "About", MB_OK|MB_APPLMODAL);
}
return TRUE;
case IDC_OPEN:
OpenWadfile(hDlg);
return TRUE;
case IDC_PLAY:
PlayLump(hDlg);
return TRUE;
default:
break;
}
break;
}
}
return FALSE;
}
static inline VOID RegisterDialogClass(LPCSTR name, WNDPROC callback, HINSTANCE hInst)
{
WNDCLASSA wnd;
wnd.style = CS_HREDRAW | CS_VREDRAW;
wnd.cbWndExtra = DLGWINDOWEXTRA;
wnd.cbClsExtra = 0;
wnd.hCursor = LoadCursorA(NULL,(LPCSTR)MAKEINTRESOURCE(IDC_ARROW));
wnd.hIcon = LoadIcon(NULL,MAKEINTRESOURCE(IDI_ICON1));
wnd.hInstance = hInst;
wnd.lpfnWndProc = callback;
wnd.lpszClassName = name;
wnd.lpszMenuName = NULL;
wnd.hbrBackground = (HBRUSH)(COLOR_WINDOW);
if (!RegisterClassA(&wnd))
{
return;
}
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// Prevent multiples instances of this app.
CreateMutexA(NULL, TRUE, APPTITLE);
if (GetLastError() == ERROR_ALREADY_EXISTS)
return 0;
RegisterDialogClass("SRB2MP", MainWndproc, hInstance);
DialogBoxA(hInstance, (LPCSTR)IDD_MAIN, NULL, DialogProc);
return 0;
}