#include <windows.h>
#include <stdio.h>
#include <zlib.h>
#include "fileinfo.h"
#include "vgm.h"
#include "gd3.h"
#include "common.h"
#include "wa_ipc.h"
#include "in2.h"
#include "resource.h"
extern In_Module mod;
// Ought to move these "globals" into a struct or something, just to make it less icky
extern char *TempHTMLFile;
extern char *CurrentURL;
extern char *CurrentURLFilename;
extern char *FilenameForInfoDlg;
extern int UseMB,MLJapanese, MLType, LoopForever, MLShowFM, NumLoops, PlaybackRate, FileInfoJapanese;
// forward declarations
int LoadInfo(char *filename, struct TFileTagInfo *fileinfo);
//-----------------------------------------------------------------
// Returns a formatted string for the file's length
// Doesn't scale it using the playback rate
//-----------------------------------------------------------------
char *FormatLength( char *buffer, struct TFileTagInfo *fileinfo )
{
char temp[1024];
PrintTime(buffer, fileinfo->tracklength / 1000.0 ); // total length
if ( fileinfo->looplength > 0 )
{
// file has a loop
if ( fileinfo->tracklength - fileinfo->looplength > 500 )
{
// intro > 500ms
strcat( buffer, " (" );
strcat( buffer, PrintTime( temp, ( fileinfo->tracklength - fileinfo->looplength ) / 1000.0 ) );
strcat( buffer, " intro and " );
strcat( buffer, PrintTime( temp, fileinfo->looplength / 1000.0 ) );
strcat( buffer, " loop)" );
}
else
{
// small or no intro
strcat( buffer, " (looped)" );
}
}
else
{
strcat( buffer, " (no loop)" );
}
return buffer;
}
//-----------------------------------------------------------------
// Show GD3 info as HTML
//-----------------------------------------------------------------
void InfoInBrowser(char *filename, int UseMB, int ForceOpen) {
FILE *f;
char *packname = NULL;
int i, j;
char *url;
char tempstr[1024]; // used for inline printf()s
const char What[10][32]={
"Track Title", "",
"Game Name", "",
"System Name", "",
"Track Author", "",
"Game Release Date", "VGM Creator"
};
struct TFileTagInfo fileinfo;
memset( &fileinfo, 0, sizeof(struct TFileTagInfo) );
if ( LoadInfo( filename, &fileinfo ) )
{
f = fopen(TempHTMLFile,"w"); // open temp HTML file for writing
if ( f )
{
// Put start text
fprintf(f,
#include "htmlbefore.txt"
);
// Add length row
fprintf( f, "<tr><td class=what>Length</td><td colspan=2 class=is>%s</td></tr>", FormatLength( tempstr, &fileinfo ) );
// Add file size row
fprintf( f, "<tr><td class=what>Size</td><td class=is colspan=2>%d bytes (%.2f bps)</td></tr>",
fileinfo.filesize,
fileinfo.bitrate
);
// first 8 strings are alternating English/Japanese
for ( i = GD3_TITLEEN; i <= GD3_AUTHORJP; ++i ) {
if ( i % 2 - 1 ) // odd number: add row title
fprintf( f, "<tr><td class=what>%s</td><td class=is>", What[i] );
if ( *(fileinfo.tags[i]) )
{
// string is not blank
for ( j = 0; *(fileinfo.tags[i] + j); j++ )
// write each character as a NCR
fprintf( f, "&#%d;", *(fileinfo.tags[i] + j) );
}
else
// put a NBSP for blanks to make the cell fill out properly
fprintf( f, " ");
if ( i % 2 ) // even number: end row
fprintf( f, "</td></tr>" );
else // odd number: continue row
fprintf( f, "</td><td class=is>" );
}
// Strings 8 to 10 have rows to themselves
for ( i = GD3_DATE; i < GD3_NOTES; ++i ) {
fprintf( f, "<tr><td class=what>%s</td><td colspan=2 class=is>", What[i] );
if ( *(fileinfo.tags[i]) ) // string is not blank
for ( j = 0; *(fileinfo.tags[i] + j); j++ )
fprintf( f, "&#%d;", *(fileinfo.tags[i] + j) );
else
fprintf( f, " " );
fprintf(f, "</td></tr>" );
}
if ( *(fileinfo.tags[GD3_NOTES]) )
{
// Notes (10th string) need some processing of line breaks
fprintf(f, "<tr><td class=what>Notes</td><td colspan=2 class=is>" );
for ( j = 0; *(fileinfo.tags[GD3_NOTES] + j); ++j ) {
if (*(fileinfo.tags[GD3_NOTES] + j) == '\n')
fprintf( f, "<br>" );
else
fprintf( f, "&#%d;", *(fileinfo.tags[GD3_NOTES] + j) );
}
// End of strings
fprintf( f, "</td></tr>" );
}
// Try for the pack readme
{
char *p;
FILE *freadme;
char *buffer;
char *readme;
BOOL success = FALSE;
readme = malloc( strlen( filename ) + 16 ); // plenty of space in all weird cases
if( readme )
{
p = strrchr( filename, '\\' ); // p points to the last \ in the filename
if ( p )
{
while( !success ) {
p = strstr( p, " - " ); // find first " - " after current position of p
if ( p ) {
strncpy( readme, filename, p - filename ); // copy filename up until the " - "
strcpy( readme + ( p - filename ), ".txt" ); // terminate it with a ".txt\0"
freadme = fopen( readme, "r" ); // try to open file
if ( freadme ) {
// save pack name for later use
packname = malloc( strlen( readme ) );
if ( packname ) {
strncpy( packname, readme, strlen( readme ) - 4 );
packname[ strlen( readme ) - 4 ] = '\0';
}
success = TRUE;
fprintf( f, "<tr><td class=what>Pack readme</td><td class=is colspan=2><textarea id=readme cols=50 rows=20 readonly>");
buffer = malloc( 1024 );
while ( fgets( buffer, 1024, freadme ) )
fputs( buffer, f );
free( buffer );
fprintf( f, "</textarea></td></tr>" );
fclose( freadme );
}
p++; // make it not find this " - " next iteration
} else break;
}
}
free(readme);
}
}
// Try for image
if ( packname ) {
FILE *fimage;
char *imagefile = malloc( strlen( packname ) + 10 );
BOOL foundit = FALSE;
sprintf( imagefile, "%s.png", packname );
if ( fimage = fopen( imagefile, "r" ) )
foundit = TRUE;
if ( !foundit )
{
sprintf( imagefile, "%s.gif", packname );
if ( fimage = fopen( imagefile, "r" ) )
foundit = TRUE;
}
if ( !foundit )
{
sprintf( imagefile, "%s.jpg", packname );
if ( fimage = fopen( imagefile, "r" ) )
foundit = TRUE;
}
if ( !foundit )
{
// try folder.jpg
char *p;
strcpy( imagefile, packname );
p = strrchr( imagefile, '\\' );
if ( p )
{
strcpy( p, "\\folder.jpg" );
if ( fimage = fopen( imagefile, "r" ) )
foundit = TRUE;
}
}
if ( foundit )
{
fclose( fimage );
fprintf(f,"<tr><td class=what>Pack image</td><td class=is colspan=2><img src=\"file:///%s\"></td></tr>", imagefile);
}
free( imagefile );
}
fputs("</table>",f);
fputs(
#include "htmlafter.txt"
,f
);
fclose(f);
if ( UseMB ) {
url = malloc( strlen( TempHTMLFile ) + 9 );
sprintf( url, "file:///%s", TempHTMLFile );
if ( ForceOpen ) SendMessage(mod.hMainWindow,WM_USER,(WPARAM)NULL,IPC_MBOPEN); // open minibrowser
SendMessage(mod.hMainWindow,WM_USER,(WPARAM)url,IPC_MBOPEN); // display file
free(url);
}
else ShellExecute(mod.hMainWindow,NULL,TempHTMLFile,NULL,NULL,SW_SHOWNORMAL);
}
}
}
//-----------------------------------------------------------------
// GD3 helper stuff
//-----------------------------------------------------------------
struct TFileTagInfo LastFileInfo;
//-----------------------------------------------------------------
// Get the track number for a given filename
// by trying to find its M3U playlist
//-----------------------------------------------------------------
int GetTrackNumber(char *filename) {
// assumes a filename "Streets of Rage II - Never Return Alive.vgz"
// will have a playlist "Streets of Rage II.m3u"
// returns track number, or 0 for not found
FILE *f;
char *playlist;
char *p;
char *fn;
char buff[1024]; // buffer for reading lines from file
int number=0;
int linenumber;
playlist=malloc(strlen(filename)+16); // plenty of space in all weird cases
if(playlist) {
p=strrchr(filename,'\\'); // p points to the last \ in the filename
if(p){
// isolate filename
fn=malloc(strlen(p));
if(fn) {
strcpy(fn,p+1);
while(number==0) {
p=strstr(p," - "); // find first " - " after current position of p
if(p) {
strncpy(playlist,filename,p-filename); // copy filename up until the " - "
strcpy(playlist+(p-filename),".m3u"); // terminate it with a ".m3u\0"
f=fopen(playlist,"r"); // try to open file
if(f) {
linenumber=1;
// read through file, a line at a time
while(fgets(buff,1024,f) && (number==0)) { // fgets will read in all characters up to and including the line break
if(strnicmp(buff,fn,strlen(fn))==0) {
// found it!
number=linenumber;
}
if((strlen(buff)>3)&&(buff[0]!='#')) linenumber++; // count lines that are (probably) valid but not #EXTINF lines
}
fclose(f);
}
p++; // make it not find this " - " next iteration
} else break;
}
free(fn);
}
}
free(playlist);
}
return number;
}
//-----------------------------------------------------------------
// Load the given file's GD3 info into the given TFileTagInfo struct
//-----------------------------------------------------------------
int LoadInfo(char *filename, struct TFileTagInfo *fileinfo)
{
// load info from filename into fileinfo
gzFile *fh;
struct TVGMHeader VGMHeader;
int i;
// Blank info
// Free pointed data first
free( fileinfo->filename );
for (i=0;i<NUMGD3TAGS;++i) {
free( fileinfo->tags[i] );
}
// Zero the struct - assuming zero is a nice field to initialise things to
memset( fileinfo, 0, sizeof(struct TFileTagInfo) );
// copy filename
fileinfo->filename = malloc(strlen(filename)+1);
strcpy(fileinfo->filename, filename);
// get file size
fileinfo->filesize = FileSize(filename);
// Start to read things in
fh=gzopen(filename,"rb");
if (fh==0) { // file not opened
return 0;
}
i=gzread(fh,&VGMHeader,sizeof(VGMHeader));
if ( (i < sizeof(VGMHeader))
|| (VGMHeader.VGMIdent != VGMIDENT)
|| ((VGMHeader.Version<MINVERSION) || ((VGMHeader.Version & REQUIREDMAJORVER)!=REQUIREDMAJORVER))
) {
gzclose(fh);
return 0;
}
// VGM header OK
fileinfo->tracklength = (int) (
(VGMHeader.TotalLength)
/44.1
*((PlaybackRate&&VGMHeader.RecordingRate)?(double)VGMHeader.RecordingRate/PlaybackRate:1)
);
fileinfo->looplength = (int) (
(VGMHeader.LoopLength)
/44.1
*((PlaybackRate&&VGMHeader.RecordingRate)?(double)VGMHeader.RecordingRate/PlaybackRate:1)
);
if ( LoopForever )
fileinfo->length = -1000;
else
fileinfo->length = fileinfo->tracklength + NumLoops * fileinfo->looplength;
// bytes * 8 = bits
// ms / 1000 = seconds
// thus (bytes * 8 ) / (ms / 1000) = bytes * 8000 / ms
fileinfo->bitrate = (float)fileinfo->filesize * 8000 / fileinfo->tracklength;
fileinfo->chips_used[VGM_CHIP_SN76489] = VGMHeader.PSGClock > 0;
fileinfo->chips_used[VGM_CHIP_YM2413] = VGMHeader.YM2413Clock > 0;
if (VGMHeader.Version<0x0110)
{
// VGM <1.10 only has one clock setting for all FM chips
fileinfo->chips_used[VGM_CHIP_YM2612] = fileinfo->chips_used[VGM_CHIP_YM2151] = fileinfo->chips_used[VGM_CHIP_YM2413];
}
else
{
fileinfo->chips_used[VGM_CHIP_YM2612] = VGMHeader.YM2612Clock > 0;
fileinfo->chips_used[VGM_CHIP_YM2151] = VGMHeader.YM2151Clock > 0;
}
_snprintf( fileinfo->vgmversion, 7, "%x.%02x", VGMHeader.Version >> 8, VGMHeader.Version & 0xff );
if (VGMHeader.GD3Offset>0) {
// GD3 tag exists
struct TGD3Header GD3Header;
gzseek(fh,VGMHeader.GD3Offset+0x14,SEEK_SET);
i=gzread(fh,&GD3Header,sizeof(GD3Header));
if (
(i==sizeof(GD3Header)) &&
(GD3Header.GD3Ident == GD3IDENT) &&
(GD3Header.Version>=MINGD3VERSION) &&
((GD3Header.Version & REQUIREDGD3MAJORVER)==REQUIREDGD3MAJORVER)
) {
// GD3 is acceptable version
wchar *GD3data,*p;
GD3data=malloc(GD3Header.Length); // Allocate memory for string data
gzread(fh,GD3data,GD3Header.Length); // Read it in
// convert into struct
p = GD3data;
for (i=0; i<NUMGD3TAGS; ++i)
{
int len;
// skip leading whitespace
while (*p && *p < 256 && isspace(*p))
p++;
// copy tag, exclude trailing whitespace
len = wcslen(p);
while (len > 0 && p[len-1] < 256 && isspace(p[len-1]))
len--;
fileinfo->tags[i] = malloc( (len + 1) * sizeof(wchar) );
if ( fileinfo->tags[i] )
{
wcsncpy( fileinfo->tags[i], p, len );
fileinfo->tags[i][len]=0; // null terminate
}
// special cases?
switch(i) {
case GD3_GAMEEN:
case GD3_GAMEJP: // album: append " (FM)" for FM soundtracks if wanted; hack: not for 7MHzish clocks, that's probably an old YM2612 header value
if ( MLShowFM
&& VGMHeader.YM2413Clock
&& (VGMHeader.YM2413Clock / 1000000)!=7 )
{
// re-allocate with a bit on the end and replace original
wchar *buffer = malloc( (len + 6)*sizeof(wchar) );
if ( buffer )
{
swprintf( buffer, L"%s (FM)", fileinfo->tags[i] );
free( fileinfo->tags[i] );
fileinfo->tags[i] = buffer;
}
}
break;
}
// move pointer on
p += wcslen(p)+1;
}
free(GD3data); // Free memory for string buffer
}
}
else
{
// blank GD3 entries
for (i=0; i<NUMGD3TAGS; ++i)
{
fileinfo->tags[i]=&L"";
}
}
gzclose(fh);
return 1;
// done!
}
//-----------------------------------------------------------------
// winampGetExtendedFileInfoW (Unicode) export
//-----------------------------------------------------------------
__declspec(dllexport) int winampGetExtendedFileInfoW(char *filename,char *metadata,wchar *ret,int retlen) {
// return zero on failure
int tagindex=GD3X_UNKNOWN;
// can't do anything with no buffer
if(!ret || !retlen)
return 0;
// first, tags that don't need to look at the file itself
if(stricmp(metadata,"type")==0) { // type
_snwprintf(ret,retlen,L"%d",MLType);
return 1;
}
if(stricmp(metadata,"track")==0) { // track number
int i=GetTrackNumber(filename);
if(i>0) {
_snwprintf(ret,retlen,L"%d",i);
return 1;
} else return 0;
}
// next, check if we've already looked at this file
if (!LastFileInfo.filename || strcmp(LastFileInfo.filename,filename)!=0)
{
LoadInfo(filename, &LastFileInfo);
// do another check on that filename in case it failed
if (!LastFileInfo.filename || strcmp(LastFileInfo.filename,filename)!=0)
return 0;
}
// now start returning stuff
*ret=0;
if(stricmp(metadata,"artist")==0) tagindex=GD3_AUTHOREN; // author
else if(stricmp(metadata,"length")==0) tagindex=GD3X_LENGTH; // length /ms
else if(stricmp(metadata,"title")==0) tagindex=GD3_TITLEEN; // track title
else if(stricmp(metadata,"album")==0) tagindex=GD3_GAMEEN; // game name
else if(stricmp(metadata,"comment")==0) tagindex=GD3_NOTES; // comment
else if(stricmp(metadata,"year")==0) tagindex=GD3_DATE; // year
else if(stricmp(metadata,"genre")==0) tagindex=GD3_SYSTEMEN; // system
#ifdef _DEBUG
if(tagindex==GD3X_UNKNOWN)printf("Unknown metadata type: \"%s\"",metadata); // debug: get metadata types
#endif
if((MLJapanese)&&(tagindex>=GD3_TITLEEN)&&(tagindex<=GD3_AUTHOREN)) tagindex++; // Increment index for Japanese
switch (tagindex) {
case GD3X_LENGTH:
_snwprintf(ret,retlen,L"%d",LastFileInfo.length);
break;
case GD3_TITLEEN: case GD3_TITLEJP: case GD3_GAMEEN: case GD3_GAMEJP: case GD3_SYSTEMEN: case GD3_SYSTEMJP:
case GD3_AUTHOREN: case GD3_AUTHORJP: case GD3_DATE: case GD3_RIPPER: case GD3_NOTES:
// copy from LastFileInfo, but check for empty ones and use the alternative
if (
( (LastFileInfo.tags[tagindex] == NULL) || (wcslen(LastFileInfo.tags[tagindex]) == 0) )
&&( tagindex <= GD3_AUTHORJP)
) {
// tweak index to point to alternative
if(tagindex%2) tagindex--;
else tagindex++;
}
if ( LastFileInfo.tags[tagindex] )
{
// special cases
switch(tagindex)
{
case GD3_DATE: // year: make it the first 4 digits
{
// try to detect various date formats
// Not yyyy/mm/dd:
// nn/nn/yy n/n/yy nn/n/yy n/nn/yy
// nn/nn/yyyy n/n/yyyy nn/n/yyyy n/nn/yyyy
// Should be:
// yyyy
// yyyy/mm
// yyyy/mm/dd
wchar *lastslash = wcsrchr( LastFileInfo.tags[tagindex], L'/' );
if (lastslash != NULL)
{
long year = wcstol(lastslash+1,NULL,10);
if (year > 31) // looks like a year
{
if ( year < 100 ) // 2-digit, yuck
year += 1900; // assume last century
_snwprintf(ret,retlen,L"%d",year);
}
}
if (!*ret)
{
// else, try the first bit
wcsncpy( ret, LastFileInfo.tags[tagindex], 4 );
}
}
break;
default:
// copy
wcsncpy( ret, LastFileInfo.tags[tagindex], retlen );
break;
}
}
break;
default:
// do nothing
return 0;
break;
}
if ( *ret == 0 )
// empty buffer: we didn't have anything to add
return 0;
else
return 1;
}
/*
//-----------------------------------------------------------------
// winampGetExtendedFileInfo (non-Unicode) export
// for old Winamps - should only be updated when something breaks, no new features please
// BUG: Winamp prefers this one, so I have to not provide it...
//-----------------------------------------------------------------
__declspec(dllexport) int winampGetExtendedFileInfo(char *filename,char *metadata,char *ret,int retlen) {
// return zero on failure
int tagindex=GD3X_UNKNOWN;
// can't do anything with no buffer
if(!ret || !retlen)
return 0;
// first, tags that don't need to look at the file itself
if(stricmp(metadata,"type")==0) { // type
_snprintf(ret,retlen,"%d",MLType);
return 1;
}
if(stricmp(metadata,"track")==0) { // track number
int i=GetTrackNumber(filename);
if(i>0) {
_snprintf(ret,retlen,"%d",i);
return 1;
} else return 0;
}
// next, check if we've already looked at this file
if (!LastFileInfo.filename || strcmp(LastFileInfo.filename,filename)!=0)
{
LoadInfo(filename, &LastFileInfo);
// do another check on that filename in case it failed
if (!LastFileInfo.filename || strcmp(LastFileInfo.filename,filename)!=0)
return 0;
}
// now start returning stuff
*ret=0;
if(stricmp(metadata,"artist")==0) tagindex=GD3_AUTHOREN; // author
else if(stricmp(metadata,"length")==0) tagindex=GD3X_LENGTH; // length /ms
else if(stricmp(metadata,"title")==0) tagindex=GD3_TITLEEN; // track title
else if(stricmp(metadata,"album")==0) tagindex=GD3_GAMEEN; // game name
else if(stricmp(metadata,"comment")==0) tagindex=GD3_NOTES; // comment
else if(stricmp(metadata,"year")==0) tagindex=GD3_DATE; // year
else if(stricmp(metadata,"genre")==0) tagindex=GD3_SYSTEMEN; // system
#ifdef _DEBUG
if(tagindex==GD3X_UNKNOWN)printf("Unknown metadata type: \"%s\"",metadata); // debug: get metadata types
#endif
if((MLJapanese)&&(tagindex>=GD3_TITLEEN)&&(tagindex<=GD3_AUTHOREN)) tagindex++; // Increment index for Japanese
switch (tagindex) {
case GD3X_LENGTH:
_snprintf(ret,retlen,"%d",LastFileInfo.length);
break;
case GD3_TITLEEN: case GD3_TITLEJP: case GD3_GAMEEN: case GD3_GAMEJP: case GD3_SYSTEMEN: case GD3_SYSTEMJP:
case GD3_AUTHOREN: case GD3_AUTHORJP: case GD3_DATE: case GD3_RIPPER: case GD3_NOTES:
// copy from LastFileInfo, but check for empty ones and use the alternative
if (
( (LastFileInfo.tags[tagindex] == NULL) || (wcslen(LastFileInfo.tags[tagindex]) == 0) )
&&( tagindex <= GD3_AUTHORJP)
) {
// tweak index to point to alternative
if(tagindex%2) tagindex--;
else tagindex++;
}
if ( LastFileInfo.tags[tagindex] )
// convert to MBCS
WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,LastFileInfo.tags[tagindex],-1,ret,retlen,NULL,NULL);
break;
default:
// do nothing
return 0;
break;
}
if ( *ret == 0 )
// empty buffer: we didn't have anything to add
return 0;
else
return 1;
}
*/
//-----------------------------------------------------------------
// File info dialogue callback function
// Have to store file info outside because it's called multiple times
//-----------------------------------------------------------------
struct TFileTagInfo InfoDialogFileInfo;
BOOL CALLBACK FileInfoDialogProc(HWND DlgWin,UINT wMessage,WPARAM wParam,LPARAM lParam) {
const int DlgFields[NUMGD3TAGS] = {
ebTitle, ebTitle,
ebName, ebName,
ebSystem, ebSystem,
ebAuthor, ebAuthor,
ebDate,
ebCreator,
ebNotes
};
switch (wMessage) { // process messages
case WM_INITDIALOG: {
//----------------------------------------------------------------
// Initialise dialogue
//----------------------------------------------------------------
int i;
char tempstr[1024];
if ( IsURL( FilenameForInfoDlg ) ) {
// Filename is a URL
if (
CurrentURLFilename && CurrentURL && (
( strcmp( FilenameForInfoDlg, CurrentURLFilename ) == 0) ||
( strcmp( FilenameForInfoDlg, CurrentURL ) == 0)
)
)
{
// If it's the current file, look at the temp file
// but display the URL
SetDlgItemText( DlgWin, ebFilename, CurrentURL );
FilenameForInfoDlg = CurrentURLFilename;
}
else
{
// If it's not the current file, no info
SetDlgItemText( DlgWin, ebFilename, FilenameForInfoDlg );
SetDlgItemText( DlgWin, ebNotes, "Information unavailable for this URL" );
DISABLECONTROL( DlgWin, btnInfoInBrowser );
return TRUE;
}
} else {
// Filename is not a URL
SetDlgItemText( DlgWin, ebFilename, FilenameForInfoDlg );
}
// Load metadata
LoadInfo( FilenameForInfoDlg, &InfoDialogFileInfo );
// VGM version
SetDlgItemText( DlgWin, ebVersion, InfoDialogFileInfo.vgmversion );
// Chips used
SETCHECKBOX( DlgWin, rbSN76489, InfoDialogFileInfo.chips_used[VGM_CHIP_SN76489] );
SETCHECKBOX( DlgWin, rbYM2413, InfoDialogFileInfo.chips_used[VGM_CHIP_YM2413] );
SETCHECKBOX( DlgWin, rbYM2612, InfoDialogFileInfo.chips_used[VGM_CHIP_YM2612] );
SETCHECKBOX( DlgWin, rbYM2151, InfoDialogFileInfo.chips_used[VGM_CHIP_YM2151] );
if ( InfoDialogFileInfo.chips_used[VGM_CHIP_YM2413] == InfoDialogFileInfo.chips_used[VGM_CHIP_YM2612]
&& InfoDialogFileInfo.chips_used[VGM_CHIP_YM2413] == InfoDialogFileInfo.chips_used[VGM_CHIP_YM2151] )
{
// looks like an old VGM file, so hide those extra boxes and rename the other one
SetDlgItemText( DlgWin, rbYM2413, "FM chips" );
HIDECONTROL( DlgWin, rbYM2612 );
HIDECONTROL( DlgWin, rbYM2151 );
}
// Size and bitrate
sprintf(
tempstr,
"%d bytes (%.2f bps)",
InfoDialogFileInfo.filesize,
InfoDialogFileInfo.bitrate
);
SetDlgItemText(DlgWin,ebSize,tempstr);
// Length
SetDlgItemText( DlgWin, ebLength, FormatLength( tempstr, &InfoDialogFileInfo ) );
// Set non-language-changing fields here
for ( i = GD3_DATE; i < NUMGD3TAGS; ++i ) {
if ( !SetDlgItemTextW( DlgWin, DlgFields[i], InfoDialogFileInfo.tags[i] ) )
{
// Widechar text setting failed, try WC2MB
char MBCSstring[1024 * 2] = "";
WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK, InfoDialogFileInfo.tags[i], -1, MBCSstring, 1024 * 2, NULL, NULL );
SetDlgItemTextA( DlgWin, DlgFields[i], MBCSstring );
}
}
// trigger English or Japanese for other fields
SETCHECKBOX( DlgWin, rbEnglish + FileInfoJapanese, TRUE );
PostMessage( DlgWin, WM_COMMAND, rbEnglish + FileInfoJapanese, 0);
return TRUE;
}
case WM_COMMAND:
//----------------------------------------------------------------
// Control messages
//----------------------------------------------------------------
switch (LOWORD(wParam)) {
case IDOK:
//----------------------------------------------------------------
// OK button
//----------------------------------------------------------------
FileInfoJapanese=IsDlgButtonChecked(DlgWin,rbJapanese);
EndDialog(DlgWin,0); // return 0 = OK
return TRUE;
case IDCANCEL:
//----------------------------------------------------------------
// [X], Esc, Alt+F4
//----------------------------------------------------------------
EndDialog(DlgWin,1); // return 1 = Cancel, stops further dialogues being opened
return TRUE;
case btnConfigure:
//----------------------------------------------------------------
// Configure Plugin
//----------------------------------------------------------------
mod.Config(DlgWin);
break;
case rbEnglish:
case rbJapanese:
//----------------------------------------------------------------
// English/Japanese
//----------------------------------------------------------------
{
int i;
// offset by 1 for japanese
const int offset = (LOWORD(wParam) == rbJapanese ? 1 : 0);
// fill in fields
for ( i = GD3_TITLEEN; i <= GD3_AUTHOREN; i += 2 ) {
if ( !SetDlgItemTextW( DlgWin, DlgFields[i + offset], InfoDialogFileInfo.tags[i + offset] ) )
{
// ASCII conversion fallback
char MBCSstring[1024 * 2] = "";
WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK, InfoDialogFileInfo.tags[i + offset], -1, MBCSstring, 1024 * 2, NULL, NULL );
SetDlgItemText( DlgWin, DlgFields[i + offset], MBCSstring );
}
}
}
break;
case btnInfoInBrowser:
//----------------------------------------------------------------
// Info In Browser
//----------------------------------------------------------------
InfoInBrowser( FilenameForInfoDlg, UseMB, TRUE );
break;
default:
break;
}
break;
}
return FALSE ; // return FALSE to signify message not processed
}