nestopia/source/win32/NstDialogImageInfo.cpp
2022-11-19 14:09:39 -05:00

370 lines
13 KiB
C++

////////////////////////////////////////////////////////////////////////////////////////
//
// Nestopia - NES/Famicom emulator written in C++
//
// Copyright (C) 2003-2008 Martin Freij
//
// This file is part of Nestopia.
//
// Nestopia 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; either version 2 of the License, or
// (at your option) any later version.
//
// Nestopia 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 for more details.
//
// You should have received a copy of the GNU General Public License
// along with Nestopia; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////////////
#include "NstWindowParam.hpp"
#include "NstResourceString.hpp"
#include "NstManagerEmulator.hpp"
#include "NstDialogImageInfo.hpp"
#include "../core/api/NstApiCartridge.hpp"
#include "../core/api/NstApiFds.hpp"
#include "../core/api/NstApiNsf.hpp"
namespace Nestopia
{
namespace Window
{
ImageInfo::ImageInfo(Managers::Emulator& e)
:
dialog (IDD_IMAGE_INFO,WM_INITDIALOG,this,&ImageInfo::OnInitDialog),
emulator (e)
{
}
ibool ImageInfo::OnInitDialog(Param&)
{
struct Table
{
static void Tab(HeapString* const strings,const uint count,const bool fixed)
{
if (fixed)
{
uint maxTab = 0;
for (uint i=0; i < count; ++i)
maxTab = NST_MAX(maxTab,strings[i].Length());
maxTab += 2;
for (uint i=0; i < count; ++i)
{
if (uint pos = strings[i].Length())
{
strings[i].Resize( maxTab );
strings[i][pos] = ':';
while (++pos < maxTab)
strings[i][pos] = ' ';
}
}
}
else for (uint i=0; i < count; ++i)
{
if (strings[i].Length())
strings[i] << ": ";
}
}
static void Output(HeapString& output,HeapString* const strings,const uint count)
{
for (uint i=0; i < count; ++i)
{
if (strings[i].Length())
{
output << strings[i];
if (i < count-1)
output << "\r\n";
}
}
}
};
HeapString text;
const bool fixedFont = dialog.Edit(IDC_IMAGE_INFO_EDIT).FixedFont();
if (emulator.IsCart())
{
typedef Nes::Cartridge::Profile Profile;
enum
{
SP_H = Profile::Board::SOLDERPAD_H,
SP_V = Profile::Board::SOLDERPAD_V
};
const Profile& profile = *Nes::Cartridge(emulator).GetProfile();
HeapString types[] =
{
!profile.game.title.empty() ? Resource::String( IDS_TEXT_NAME ) : HeapString(),
!profile.game.altTitle.empty() ? Resource::String( IDS_TEXT_ALTNAME ) : HeapString(),
!profile.game.publisher.empty() ? Resource::String( IDS_TEXT_PUBLISHER ) : HeapString(),
!profile.game.developer.empty() ? Resource::String( IDS_TEXT_DEVELOPER ) : HeapString(),
!profile.game.region.empty() ? Resource::String( IDS_TEXT_REGION ) : HeapString(),
profile.game.players ? Resource::String( IDS_TEXT_PLAYERS ) : HeapString(),
Resource::String( IDS_TEXT_FILE ),
Resource::String( IDS_TEXT_DIRECTORY ),
Resource::String( IDS_TEXT_SOFTPATCHED ),
"CRC",
"SHA-1",
Resource::String( IDS_TEXT_SYSTEM ),
Resource::String( IDS_TEXT_BOARD ),
profile.board.GetPrg() ? "PRG-ROM" : HeapString(),
profile.board.GetChr() ? "CHR-ROM" : HeapString(),
profile.board.GetVram() ? "V-RAM" : HeapString(),
profile.board.GetWram() ? "W-RAM" : HeapString(),
!profile.board.chips.empty() ? Resource::String( IDS_TEXT_CHIPS ) : HeapString(),
profile.board.solderPads & (SP_H|SP_V) ? Resource::String( IDS_TEXT_SOLDERPAD ) : HeapString(),
Resource::String( IDS_TEXT_BATTERY ),
profile.board.HasBattery() ? Resource::String( IDS_TEXT_FILE ) : HeapString(),
profile.board.HasBattery() ? Resource::String( IDS_TEXT_DIRECTORY ) : HeapString(),
Resource::String( IDS_TEXT_DUMP )
};
Table::Tab( types, sizeof(array(types)), fixedFont );
if (!profile.game.title.empty())
types[0] << profile.game.title.c_str();
if (!profile.game.altTitle.empty())
types[1] << profile.game.altTitle.c_str();
if (!profile.game.publisher.empty())
types[2] << profile.game.publisher.c_str();
if (!profile.game.developer.empty())
types[3] << profile.game.developer.c_str();
if (!profile.game.region.empty())
types[4] << profile.game.region.c_str();
if (profile.game.players)
types[5] << profile.game.players;
types[6] << emulator.GetImagePath().File();
types[7] << emulator.GetImagePath().Directory();
types[8] << Resource::String( profile.patched ? IDS_TEXT_YES : IDS_TEXT_NO );;
{
char sha1[41] = {0};
char crc32[9] = {0};
profile.hash.Get( sha1, crc32 );
types[9] << crc32;
types[10] << sha1;
}
types[11] << Resource::String
(
profile.system.type == Profile::System::VS_UNISYSTEM ? IDS_TEXT_VSUNISYSTEM :
profile.system.type == Profile::System::VS_DUALSYSTEM ? IDS_TEXT_VSDUALSYSTEM :
profile.system.type == Profile::System::PLAYCHOICE_10 ? IDS_TEXT_PLAYCHOICE10 :
profile.system.type == Profile::System::NES_PAL ? IDS_TEXT_NES_PAL :
profile.system.type == Profile::System::NES_PAL_A ? IDS_TEXT_NES_PAL_A :
profile.system.type == Profile::System::NES_PAL_B ? IDS_TEXT_NES_PAL_B :
profile.system.type == Profile::System::FAMICOM ? IDS_TEXT_FAMICOM :
profile.system.type == Profile::System::DENDY ? IDS_TEXT_DENDY :
IDS_TEXT_NES_NTSC
);
types[12] << profile.board.type.c_str();
if (profile.board.mapper && profile.board.mapper != Profile::Board::NO_MAPPER)
types[12] << ", " << Resource::String( IDS_TEXT_MAPPER ) << ' ' << profile.board.mapper;
if (const uint prg = profile.board.GetPrg())
types[13] << (prg % 1024 ? prg : prg / 1024) << (prg % 1024 ? " bytes" : "k");
if (const uint chr = profile.board.GetChr())
types[14] << (chr % 1024 ? chr : chr / 1024) << (chr % 1024 ? " bytes" : "k");
if (const uint vram = profile.board.GetVram())
types[15] << (vram % 1024 ? vram : vram / 1024) << (vram % 1024 ? " bytes" : "k");
if (const uint wram = profile.board.GetWram())
types[16] << (wram % 1024 ? wram : wram / 1024) << (wram % 1024 ? " bytes" : "k");
for (uint i=0, n=profile.board.chips.size(); i < n; ++i)
{
if (i)
types[17] << ", ";
types[17] << profile.board.chips[i].type.c_str();
}
if (profile.board.solderPads & (SP_H|SP_V))
{
types[18] << "H:" << ((profile.board.solderPads & SP_H) ? '1' : '0')
<< " V:" << ((profile.board.solderPads & SP_V) ? '1' : '0');
}
types[19] << Resource::String( profile.board.HasBattery() ? IDS_TEXT_YES : IDS_TEXT_NO );
if (profile.board.HasBattery())
{
types[20] << emulator.GetSavePath().File();
types[21] << emulator.GetSavePath().Directory();
}
types[22] << Resource::String
(
profile.dump.state == Profile::Dump::OK ? IDS_TEXT_OK :
profile.dump.state == Profile::Dump::BAD ? IDS_TEXT_BAD :
IDS_TEXT_UNKNOWN
);
Table::Output( text, types, sizeof(array(types)) );
}
else if (emulator.IsFds())
{
const Nes::Fds fds(emulator);
std::vector<HeapString> types( 3 + NST_MAX(fds.GetNumSides()/2,1) );
types[0] = Resource::String( IDS_TEXT_FILE );
types[1] = Resource::String( IDS_TEXT_DIRECTORY );
types[2] = Resource::String( IDS_TEXT_HEADER );
for (uint i=3, n=types.size(); i < n; ++i)
types[i] = Resource::String( IDS_TEXT_DISK ).Invoke( i-3+1 );
Table::Tab( &types.front(), types.size(), fixedFont );
types[0] << emulator.GetImagePath().File();
types[1] << emulator.GetImagePath().Directory();
types[2] << Resource::String( fds.HasHeader() ? IDS_TEXT_YES : IDS_TEXT_NO );
for (uint i=0, n=fds.GetNumSides(); i < n; ++i)
{
Nes::Fds::DiskData data;
fds.GetDiskData( i, data );
uint size = 0;
for (Nes::Fds::DiskData::Files::const_iterator it(data.files.begin()), end(data.files.end()); it != end; ++it)
size += it->data.size();
types[3+i/2] << (i % 2 ? ", B: " : "A: ")
<< (size / 1024)
<< "k "
<< Resource::String( IDS_TEXT_IN_FILES ).Invoke( data.files.size() );
if (!data.raw.empty())
types[3+i/2] << ", " << Resource::String( IDS_TEXT_TRAILING_DATA ).Invoke( data.raw.size() );
}
Table::Output( text, &types.front(), types.size() );
}
else if (emulator.IsNsf())
{
const Nes::Nsf nsf(emulator);
HeapString types[] =
{
Resource::String( IDS_TEXT_FILE ),
Resource::String( IDS_TEXT_DIRECTORY ),
*nsf.GetName() ? Resource::String( IDS_TEXT_NAME ) : HeapString(),
*nsf.GetArtist() ? Resource::String( IDS_TEXT_ARTIST ) : HeapString(),
*nsf.GetCopyright() ? Resource::String( IDS_TEXT_COPYRIGHT ) : HeapString(),
Resource::String( IDS_TEXT_REGION ),
Resource::String( IDS_TEXT_SONGS ),
nsf.GetNumSongs() > 1 ? Resource::String( IDS_TEXT_STARTINGSONG ) : HeapString(),
Resource::String( IDS_TEXT_EXTRACHIPS ),
Resource::String( IDS_TEXT_BANKSWITCHING ),
Resource::String( IDS_TEXT_LOADADDRESS ),
Resource::String( IDS_TEXT_INITADDRESS ),
Resource::String( IDS_TEXT_PLAYADDRESS )
};
Table::Tab( types, sizeof(array(types)), fixedFont );
types[0] << emulator.GetImagePath().File();
types[1] << emulator.GetImagePath().Directory();
if (*nsf.GetName())
types[2].Import( nsf.GetName() );
if (*nsf.GetArtist())
types[3].Import( nsf.GetArtist() );
if (*nsf.GetCopyright())
types[4].Import( nsf.GetCopyright() );
types[5] <<
(
nsf.GetMode() == Nes::Nsf::TUNE_MODE_NTSC ? "NTSC" :
nsf.GetMode() == Nes::Nsf::TUNE_MODE_PAL ? "PAL" :
"NTSC/PAL"
);
types[6] << nsf.GetNumSongs();
if (nsf.GetNumSongs() > 1)
types[7] << (nsf.GetStartingSong() + 1);
if (const uint chips = nsf.GetChips())
{
cstring c = "";
if ( chips & Nes::Nsf::CHIP_MMC5 ) { types[8] << "MMC5"; c = "+"; }
if ( chips & Nes::Nsf::CHIP_VRC6 ) { types[8] << c << "VRC6"; c = "+"; }
if ( chips & Nes::Nsf::CHIP_VRC7 ) { types[8] << c << "VRC7"; c = "+"; }
if ( chips & Nes::Nsf::CHIP_N163 ) { types[8] << c << "N163"; c = "+"; }
if ( chips & Nes::Nsf::CHIP_S5B ) { types[8] << c << "Sunsoft5B"; c = "+"; }
if ( chips & Nes::Nsf::CHIP_FDS ) { types[8] << c << "FDS"; c = "+"; }
}
else
{
types[8] << Resource::String( IDS_TEXT_NO );
}
types[9] << Resource::String( nsf.UsesBankSwitching() ? IDS_TEXT_YES : IDS_TEXT_NO );
types[10] << HexString( 16, nsf.GetLoadAddress() );
types[11] << HexString( 16, nsf.GetInitAddress() );
types[12] << HexString( 16, nsf.GetPlayAddress() );
Table::Output( text, types, sizeof(array(types)) );
}
if (text.Length())
{
dialog.Edit(IDC_IMAGE_INFO_EDIT) << text.Ptr();
Point size( dialog.Edit(IDC_IMAGE_INFO_EDIT).GetMaxTextSize() );
Point delta( dialog.Edit(IDC_IMAGE_INFO_EDIT).GetWindow().Size() );
if (size.x > delta.x)
{
size.x = delta.x;
size.y += ::GetSystemMetrics(SM_CXVSCROLL);
::ShowScrollBar( dialog.Control(IDC_IMAGE_INFO_EDIT).GetWindow(), SB_HORZ, true );
}
if (size != delta)
{
dialog.Edit(IDC_IMAGE_INFO_EDIT).GetWindow().Size() = size;
delta -= size;
dialog.Control(IDOK).GetWindow().Position() -= delta;
dialog.Size() -= delta;
}
}
return true;
}
}
}