Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added game info tags to XBMC

XBMC can now load metadata from game images. The following types of game images are currently supported: GBA, GB/GBC. CFileItem::IsGame() can be used to determine if the file item has a game info tag loaded.
  • Loading branch information...
commit ae51bc975f44797fd854e70822a2a5f074ebeda5 1 parent c35f173
@garbear authored
View
1  Makefile.in
@@ -46,6 +46,7 @@ DIRECTORY_ARCHIVES=$(DVDPLAYER_ARCHIVES) \
xbmc/filesystem/MusicDatabaseDirectory/musicdatabasedirectory.a \
xbmc/filesystem/VideoDatabaseDirectory/videodatabasedirectory.a \
xbmc/filesystem/filesystem.a \
+ xbmc/games/tags/gameinfotags.a \
xbmc/guilib/guilib.a \
xbmc/input/input.a \
xbmc/interfaces/info/info.a \
View
1  configure.in
@@ -2401,6 +2401,7 @@ OUTPUT_FILES="Makefile \
xbmc/peripherals/devices/Makefile \
xbmc/android/activity/Makefile \
xbmc/android/loader/Makefile \
+ xbmc/games/tags/Makefile \
xbmc/main/Makefile"
if test "$use_skin_touched" = "yes"; then
View
8 project/VS2010Express/XBMC.vcxproj
@@ -581,6 +581,10 @@
<ClCompile Include="..\..\xbmc\filesystem\ZipDirectory.cpp" />
<ClCompile Include="..\..\xbmc\filesystem\ZipFile.cpp" />
<ClCompile Include="..\..\xbmc\filesystem\ZipManager.cpp" />
+ <ClCompile Include="..\..\xbmc\games\tags\GameboyTag.cpp" />
+ <ClCompile Include="..\..\xbmc\games\tags\GameInfoTag.cpp" />
+ <ClCompile Include="..\..\xbmc\games\tags\GameInfoTagLoader.cpp" />
+ <ClCompile Include="..\..\xbmc\games\tags\GBATag.cpp" />
<ClCompile Include="..\..\xbmc\GUIInfoManager.cpp" />
<ClCompile Include="..\..\xbmc\GUILargeTextureManager.cpp" />
<ClCompile Include="..\..\xbmc\guilib\AnimatedGif.cpp" />
@@ -1042,6 +1046,10 @@
<ClInclude Include="..\..\xbmc\filesystem\windows\WINFileSMB.h" />
<ClInclude Include="..\..\xbmc\filesystem\windows\WINSMBDirectory.h" />
<ClInclude Include="..\..\xbmc\guilib\cximage.h" />
+ <ClInclude Include="..\..\xbmc\games\tags\GameboyTag.h" />
+ <ClInclude Include="..\..\xbmc\games\tags\GameInfoTag.h" />
+ <ClInclude Include="..\..\xbmc\games\tags\GameInfoTagLoader.h" />
+ <ClInclude Include="..\..\xbmc\games\tags\GBATag.h" />
<ClInclude Include="..\..\xbmc\guilib\GUIKeyboard.h" />
<ClInclude Include="..\..\xbmc\guilib\GUIKeyboardFactory.h" />
<ClInclude Include="..\..\xbmc\guilib\iimage.h" />
View
30 project/VS2010Express/XBMC.vcxproj.filters
@@ -286,6 +286,12 @@
<Filter Include="settings\windows">
<UniqueIdentifier>{1a1eb956-43d1-4709-9467-ce471d54941d}</UniqueIdentifier>
</Filter>
+ <Filter Include="games">
+ <UniqueIdentifier>{7ff3350b-07f8-483b-958c-0edd6081e7a7}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="games\tags">
+ <UniqueIdentifier>{c19c485e-b24e-4c45-bb0a-6d41a429f505}</UniqueIdentifier>
+ </Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\xbmc\win32\pch.cpp">
@@ -2982,6 +2988,18 @@
<ClCompile Include="..\..\xbmc\input\windows\WINJoystickXInput.cpp">
<Filter>input\windows</Filter>
</ClCompile>
+ <ClCompile Include="..\..\xbmc\games\tags\GameboyTag.cpp">
+ <Filter>games\tags</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\xbmc\games\tags\GameInfoTag.cpp">
+ <Filter>games\tags</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\xbmc\games\tags\GameInfoTagLoader.cpp">
+ <Filter>games\tags</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\xbmc\games\tags\GBATag.cpp">
+ <Filter>games\tags</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\xbmc\win32\pch.h">
@@ -5828,6 +5846,18 @@
<ClInclude Include="..\..\xbmc\input\windows\WINJoystickXInput.h">
<Filter>input\windows</Filter>
</ClInclude>
+ <ClInclude Include="..\..\xbmc\games\tags\GameboyTag.h">
+ <Filter>games\tags</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\xbmc\games\tags\GameInfoTag.h">
+ <Filter>games\tags</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\xbmc\games\tags\GameInfoTagLoader.h">
+ <Filter>games\tags</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\xbmc\games\tags\GBATag.h">
+ <Filter>games\tags</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\xbmc\win32\XBMC_PC.rc">
View
85 xbmc/FileItem.cpp
@@ -57,6 +57,8 @@
#include "utils/Variant.h"
#include "music/karaoke/karaokelyricsfactory.h"
#include "utils/Mime.h"
+#include "games/tags/GameInfoTag.h"
+#include "games/tags/GameInfoTagLoader.h"
using namespace std;
using namespace XFILE;
@@ -64,6 +66,7 @@ using namespace PLAYLIST;
using namespace MUSIC_INFO;
using namespace PVR;
using namespace EPG;
+using namespace GAME_INFO;
CFileItem::CFileItem(const CSong& song)
{
@@ -74,6 +77,7 @@ CFileItem::CFileItem(const CSong& song)
m_pvrRecordingInfoTag = NULL;
m_pvrTimerInfoTag = NULL;
m_pictureInfoTag = NULL;
+ m_gameInfoTag = NULL;
Reset();
SetFromSong(song);
@@ -88,6 +92,7 @@ CFileItem::CFileItem(const CStdString &path, const CAlbum& album)
m_pvrRecordingInfoTag = NULL;
m_pvrTimerInfoTag = NULL;
m_pictureInfoTag = NULL;
+ m_gameInfoTag = NULL;
Reset();
m_strPath = path;
@@ -104,6 +109,7 @@ CFileItem::CFileItem(const CMusicInfoTag& music)
m_pvrRecordingInfoTag = NULL;
m_pvrTimerInfoTag = NULL;
m_pictureInfoTag = NULL;
+ m_gameInfoTag = NULL;
Reset();
SetLabel(music.GetTitle());
m_strPath = music.GetURL();
@@ -121,6 +127,7 @@ CFileItem::CFileItem(const CVideoInfoTag& movie)
m_pvrRecordingInfoTag = NULL;
m_pvrTimerInfoTag = NULL;
m_pictureInfoTag = NULL;
+ m_gameInfoTag = NULL;
Reset();
SetFromVideoInfoTag(movie);
@@ -249,6 +256,7 @@ CFileItem::CFileItem(const CArtist& artist)
m_pvrRecordingInfoTag = NULL;
m_pvrTimerInfoTag = NULL;
m_pictureInfoTag = NULL;
+ m_gameInfoTag = NULL;
Reset();
SetLabel(artist.strArtist);
m_strPath = artist.strArtist;
@@ -266,6 +274,7 @@ CFileItem::CFileItem(const CGenre& genre)
m_pvrRecordingInfoTag = NULL;
m_pvrTimerInfoTag = NULL;
m_pictureInfoTag = NULL;
+ m_gameInfoTag = NULL;
Reset();
SetLabel(genre.strGenre);
m_strPath = genre.strGenre;
@@ -283,6 +292,7 @@ CFileItem::CFileItem(const CFileItem& item): CGUIListItem()
m_pvrRecordingInfoTag = NULL;
m_pvrTimerInfoTag = NULL;
m_pictureInfoTag = NULL;
+ m_gameInfoTag = NULL;
*this = item;
}
@@ -295,6 +305,7 @@ CFileItem::CFileItem(const CGUIListItem& item)
m_pvrRecordingInfoTag = NULL;
m_pvrTimerInfoTag = NULL;
m_pictureInfoTag = NULL;
+ m_gameInfoTag = NULL;
Reset();
// not particularly pretty, but it gets around the issue of Reset() defaulting
// parameters in the CGUIListItem base class.
@@ -310,6 +321,7 @@ CFileItem::CFileItem(void)
m_pvrRecordingInfoTag = NULL;
m_pvrTimerInfoTag = NULL;
m_pictureInfoTag = NULL;
+ m_gameInfoTag = NULL;
Reset();
}
@@ -323,6 +335,7 @@ CFileItem::CFileItem(const CStdString& strLabel)
m_pvrRecordingInfoTag = NULL;
m_pvrTimerInfoTag = NULL;
m_pictureInfoTag = NULL;
+ m_gameInfoTag = NULL;
Reset();
SetLabel(strLabel);
}
@@ -336,6 +349,7 @@ CFileItem::CFileItem(const CStdString& strPath, bool bIsFolder)
m_pvrRecordingInfoTag = NULL;
m_pvrTimerInfoTag = NULL;
m_pictureInfoTag = NULL;
+ m_gameInfoTag = NULL;
Reset();
m_strPath = strPath;
m_bIsFolder = bIsFolder;
@@ -353,6 +367,7 @@ CFileItem::CFileItem(const CMediaSource& share)
m_pvrRecordingInfoTag = NULL;
m_pvrTimerInfoTag = NULL;
m_pictureInfoTag = NULL;
+ m_gameInfoTag = NULL;
Reset();
m_bIsFolder = true;
m_bIsShareOrDrive = true;
@@ -383,6 +398,7 @@ CFileItem::~CFileItem(void)
delete m_pvrRecordingInfoTag;
delete m_pvrTimerInfoTag;
delete m_pictureInfoTag;
+ delete m_gameInfoTag;
m_musicInfoTag = NULL;
m_videoInfoTag = NULL;
@@ -391,6 +407,7 @@ CFileItem::~CFileItem(void)
m_pvrRecordingInfoTag = NULL;
m_pvrTimerInfoTag = NULL;
m_pictureInfoTag = NULL;
+ m_gameInfoTag = NULL;
}
const CFileItem& CFileItem::operator=(const CFileItem& item)
@@ -497,6 +514,18 @@ const CFileItem& CFileItem::operator=(const CFileItem& item)
m_pictureInfoTag = NULL;
}
+ if (item.HasGameInfoTag())
+ {
+ m_gameInfoTag = GetGameInfoTag();
+ if (m_gameInfoTag)
+ *m_gameInfoTag = *item.m_gameInfoTag;
+ }
+ else
+ {
+ delete m_gameInfoTag;
+ m_gameInfoTag = NULL;
+ }
+
m_lStartOffset = item.m_lStartOffset;
m_lStartPartNumber = item.m_lStartPartNumber;
m_lEndOffset = item.m_lEndOffset;
@@ -559,6 +588,8 @@ void CFileItem::Reset()
m_pvrTimerInfoTag=NULL;
delete m_pictureInfoTag;
m_pictureInfoTag=NULL;
+ delete m_gameInfoTag;
+ m_gameInfoTag = NULL;
m_extrainfo.Empty();
m_specialSort = SortSpecialNone;
ClearProperties();
@@ -615,6 +646,13 @@ void CFileItem::Archive(CArchive& ar)
}
else
ar << 0;
+ if (m_gameInfoTag)
+ {
+ ar << 1;
+ ar << *m_gameInfoTag;
+ }
+ else
+ ar << 0;
}
else
{
@@ -654,6 +692,9 @@ void CFileItem::Archive(CArchive& ar)
ar >> iType;
if (iType == 1)
ar >> *GetPictureInfoTag();
+ ar >> iType;
+ if (iType == 1)
+ ar >> *GetGameInfoTag();
SetInvalid();
}
@@ -679,6 +720,9 @@ void CFileItem::Serialize(CVariant& value) const
if (m_pictureInfoTag)
(*m_pictureInfoTag).Serialize(value["pictureInfoTag"]);
+
+ if (m_gameInfoTag)
+ (*m_gameInfoTag).Serialize(value["gameInfoTag"]);
}
void CFileItem::ToSortable(SortItem &sortable)
@@ -720,6 +764,9 @@ void CFileItem::ToSortable(SortItem &sortable)
if (HasPVRChannelInfoTag())
GetPVRChannelInfoTag()->ToSortable(sortable);
+
+ if (HasGameInfoTag())
+ GetGameInfoTag()->ToSortable(sortable);
}
bool CFileItem::Exists(bool bUseCache /* = true */) const
@@ -764,6 +811,7 @@ bool CFileItem::IsVideo() const
if (HasMusicInfoTag()) return false;
if (HasPictureInfoTag()) return false;
if (IsPVRRecording()) return true;
+ if (HasGameInfoTag()) return false;
if (IsHDHomeRun() || IsTuxBox() || URIUtils::IsDVD(m_strPath) || IsSlingbox())
return true;
@@ -841,6 +889,7 @@ bool CFileItem::IsAudio() const
if (HasMusicInfoTag()) return true;
if (HasVideoInfoTag()) return false;
if (HasPictureInfoTag()) return false;
+ if (HasGameInfoTag()) return false;
if (IsCDDA()) return true;
CStdString extension;
@@ -863,6 +912,16 @@ bool CFileItem::IsAudio() const
return (g_settings.m_musicExtensions.Find(extension) != -1);
}
+bool CFileItem::IsGame() const
+{
+ if (HasGameInfoTag()) return true;
+ if (HasVideoInfoTag()) return false;
+ if (HasMusicInfoTag()) return false;
+ if (HasPictureInfoTag()) return false;
+
+ return false;
+}
+
bool CFileItem::IsKaraoke() const
{
if ( !IsAudio())
@@ -879,6 +938,7 @@ bool CFileItem::IsPicture() const
if (HasPictureInfoTag()) return true;
if (HasMusicInfoTag()) return false;
if (HasVideoInfoTag()) return false;
+ if (HasGameInfoTag()) return false;
return CUtil::IsPicture(m_strPath);
}
@@ -1455,6 +1515,8 @@ void CFileItem::UpdateInfo(const CFileItem &item, bool replaceLabels /*=true*/)
*GetMusicInfoTag() = *item.GetMusicInfoTag();
if (item.HasPictureInfoTag())
*GetPictureInfoTag() = *item.GetPictureInfoTag();
+ if (item.HasGameInfoTag())
+ *GetGameInfoTag() = *item.GetGameInfoTag();
if (replaceLabels && !item.GetLabel().IsEmpty())
SetLabel(item.GetLabel());
@@ -3041,6 +3103,21 @@ bool CFileItem::LoadMusicTag()
return false;
}
+bool CFileItem::LoadGameTag()
+{
+ // Already loaded?
+ if (HasGameInfoTag() && m_gameInfoTag->Loaded())
+ return true;
+
+ // Load tag from file
+ CLog::Log(LOGDEBUG, "%s: loading tag information for file: %s", __FUNCTION__, m_strPath.c_str());
+
+ if (CGameInfoTagLoader::Get().Load(m_strPath, *GetGameInfoTag()))
+ return true;
+
+ return false;
+}
+
void CFileItemList::Swap(unsigned int item1, unsigned int item2)
{
if (item1 != item2 && item1 < m_items.size() && item2 < m_items.size())
@@ -3141,6 +3218,14 @@ MUSIC_INFO::CMusicInfoTag* CFileItem::GetMusicInfoTag()
return m_musicInfoTag;
}
+GAME_INFO::CGameInfoTag* CFileItem::GetGameInfoTag()
+{
+ if (!m_gameInfoTag)
+ m_gameInfoTag = new GAME_INFO::CGameInfoTag;
+
+ return m_gameInfoTag;
+}
+
CStdString CFileItem::FindTrailer() const
{
CStdString strFile2;
View
19 xbmc/FileItem.h
@@ -53,6 +53,10 @@ namespace PVR
class CPVRTimerInfoTag;
}
class CPictureInfoTag;
+namespace GAME_INFO
+{
+ class CGameInfoTag;
+}
class CAlbum;
class CArtist;
@@ -109,6 +113,7 @@ class CFileItem :
bool IsPicture() const;
bool IsLyrics() const;
bool IsAudio() const;
+ bool IsGame() const;
bool IsKaraoke() const;
bool IsCUESheet() const;
bool IsInternetStream(const bool bStrictCheck = false) const;
@@ -262,6 +267,18 @@ class CFileItem :
return m_pictureInfoTag;
}
+ inline bool HasGameInfoTag() const
+ {
+ return m_gameInfoTag != NULL;
+ }
+
+ GAME_INFO::CGameInfoTag* GetGameInfoTag();
+
+ inline const GAME_INFO::CGameInfoTag* GetGameInfoTag() const
+ {
+ return m_gameInfoTag;
+ }
+
CPictureInfoTag* GetPictureInfoTag();
/*!
@@ -326,6 +343,7 @@ class CFileItem :
CStdString FindTrailer() const;
virtual bool LoadMusicTag();
+ virtual bool LoadGameTag();
/* returns the content type of this item if known. will lookup for http streams */
const CStdString& GetMimeType(bool lookup = true) const;
@@ -401,6 +419,7 @@ class CFileItem :
PVR::CPVRRecording* m_pvrRecordingInfoTag;
PVR::CPVRTimerInfoTag * m_pvrTimerInfoTag;
CPictureInfoTag* m_pictureInfoTag;
+ GAME_INFO::CGameInfoTag* m_gameInfoTag;
bool m_bIsAlbum;
};
View
85 xbmc/games/tags/GBATag.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2012 Garrett Brown
+ * Copyright (C) 2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * 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; either version 2, or (at your option)
+ * any later version.
+ *
+ * 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "GBATag.h"
+#include "GameboyTag.h"
+#include "filesystem/File.h"
+#include "utils/log.h"
+#include "utils/URIUtils.h"
+#include "utils/StdString.h"
+
+using namespace GAME_INFO;
+using namespace XFILE;
+
+
+// Constants and file format data from VBA-M project
+// http://sourceforge.net/projects/vbam
+// This code references VBA-M at r1118, later commits may contain fixes
+
+void CGBATag::Load(const CStdString& strPath, CGameInfoTag &gameInfoTag)
+{
+ CStdString strExtension;
+ URIUtils::GetExtension(strPath, strExtension);
+
+ if (strExtension.Equals(".elf"))
+ {
+ // ELF files not supported yet
+ return;
+ }
+
+ // Open the file and read in the data
+ CFile file;
+ if (!file.Open(strPath))
+ return;
+
+ // Useful data is all ASCII, fortunately. Some stats like main unit code,
+ // device type, version and CRC are omitted here.
+ unsigned char data[0xb0 + 3]; // Until the end of the publisher ID bytes
+ if (file.Read(data, sizeof(data)) != sizeof(data))
+ return;
+
+ // The properties below must all be ASCII text
+ if (!AllASCII(data + 0xa0, 12) ||
+ !AllASCII(data + 0xac, 4) ||
+ !AllASCII(data + 0xb0, 2))
+ {
+ CLog::Log(LOGERROR, "CGBATag: Non-ASCII data encountered while reading image parameters");
+ return;
+ }
+
+ // Title: $a0, 12 bytes
+ gameInfoTag.SetTitle(std::string(reinterpret_cast<char*>(data) + 0xa0, 12));
+
+ // ID: $ac, 4 bytes
+ gameInfoTag.SetID(std::string(reinterpret_cast<char*>(data) + 0xac, 4));
+
+ // Publisher: $b0, 2 bytes
+ gameInfoTag.SetPublisher(CGameboyTag::TranslatePublisher(reinterpret_cast<char*>(data) + 0xb0));
+}
+
+bool CGBATag::AllASCII(unsigned char *b, unsigned int size)
+{
+ for (unsigned int i = 0; i < size; i++)
+ if (b[i] < 32 || b[i] > 126)
+ return false;
+ return true;
+}
View
36 xbmc/games/tags/GBATag.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2012 Garrett Brown
+ * Copyright (C) 2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * 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; either version 2, or (at your option)
+ * any later version.
+ *
+ * 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+#pragma once
+
+#include "GameInfoTag.h"
+
+namespace GAME_INFO
+{
+ class CGBATag
+ {
+ public:
+ static void Load(const CStdString& strPath, CGameInfoTag &gameInfoTag);
+
+ private:
+ static bool AllASCII(unsigned char *b, unsigned int size);
+ };
+}
View
130 xbmc/games/tags/GameInfoTag.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2012 Garrett Brown
+ * Copyright (C) 2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * 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; either version 2, or (at your option)
+ * any later version.
+ *
+ * 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "GameInfoTag.h"
+#include "utils/Variant.h"
+
+using namespace GAME_INFO;
+
+CGameInfoTag::CGameInfoTag()
+{
+ Reset();
+}
+
+CGameInfoTag::CGameInfoTag(const CGameInfoTag &tag)
+{
+ *this = tag;
+}
+
+void CGameInfoTag::Reset()
+{
+ m_bLoaded = false;
+ m_strURL.Empty();
+ m_strPlatform.Empty();
+ m_strName.Empty();
+ m_strCode.Empty();
+ m_strRegion.Empty();
+ m_strPublisher.Empty();
+ m_strFormat.Empty();
+ m_strCartridgeType.Empty();
+}
+
+const CGameInfoTag &CGameInfoTag::operator=(const CGameInfoTag &tag)
+{
+ if (this != &tag)
+ {
+ m_bLoaded = tag.m_bLoaded;
+ m_strURL = tag.m_strURL;
+ m_strPlatform = tag.m_strPlatform;
+ m_strName = tag.m_strName;
+ m_strCode = tag.m_strCode;
+ m_strRegion = tag.m_strRegion;
+ m_strPublisher = tag.m_strPublisher;
+ m_strFormat = tag.m_strFormat;
+ m_strCartridgeType = tag.m_strCartridgeType;
+ }
+ return *this;
+}
+
+bool CGameInfoTag::operator!=(const CGameInfoTag &tag) const
+{
+ if (this != &tag)
+ {
+ // Two tags can't be equal if they aren't loaded
+ if (!m_bLoaded || !tag.m_bLoaded) return true;
+ if (m_strURL != tag.m_strURL) return true;
+ if (m_strPlatform != tag.m_strPlatform) return true;
+ if (m_strName != tag.m_strName) return true;
+ if (m_strCode != tag.m_strCode) return true;
+ if (m_strRegion != tag.m_strRegion) return true;
+ if (m_strPublisher != tag.m_strPublisher) return true;
+ if (m_strFormat != tag.m_strFormat) return true;
+ if (m_strCartridgeType != tag.m_strCartridgeType) return true;
+ }
+ return false;
+}
+
+void CGameInfoTag::Archive(CArchive &ar)
+{
+ if (ar.IsStoring())
+ {
+ ar << m_bLoaded;
+ ar << m_strURL;
+ ar << m_strPlatform;
+ ar << m_strName;
+ ar << m_strCode;
+ ar << m_strRegion;
+ ar << m_strPublisher;
+ ar << m_strFormat;
+ ar << m_strCartridgeType;
+ }
+ else
+ {
+ ar >> m_bLoaded;
+ ar >> m_strURL;
+ ar >> m_strPlatform;
+ ar >> m_strName;
+ ar >> m_strCode;
+ ar >> m_strRegion;
+ ar >> m_strPublisher;
+ ar >> m_strFormat;
+ ar >> m_strCartridgeType;
+ }
+}
+
+void CGameInfoTag::Serialize(CVariant &value) const
+{
+ value["loaded"] = m_bLoaded;
+ value["url"] = m_strURL;
+ value["platform"] = m_strPlatform;
+ value["name"] = m_strName;
+ value["id"] = m_strCode;
+ value["region"] = m_strRegion;
+ value["publisher"] = m_strPublisher;
+ value["format"] = m_strFormat;
+ value["cartridgetype"] = m_strCartridgeType;
+}
+
+void CGameInfoTag::ToSortable(SortItem &sortable)
+{
+ // No database entries for games (...yet)
+}
View
91 xbmc/games/tags/GameInfoTag.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2012 Garrett Brown
+ * Copyright (C) 2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * 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; either version 2, or (at your option)
+ * any later version.
+ *
+ * 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+#pragma once
+
+#include "utils/Archive.h"
+#include "utils/ISerializable.h"
+#include "utils/ISortable.h"
+
+
+namespace GAME_INFO
+{
+ class CGameInfoTag : public IArchivable, public ISerializable, public ISortable
+ {
+ public:
+ CGameInfoTag();
+ CGameInfoTag(const CGameInfoTag &tag);
+ const CGameInfoTag &operator=(const CGameInfoTag &tag);
+ ~CGameInfoTag() { }
+ void Reset();
+ bool operator!=(const CGameInfoTag &tag) const;
+
+ bool Loaded() const { return m_bLoaded; }
+ void SetLoaded(bool bOnOff = true) { m_bLoaded = bOnOff; }
+
+ // File path
+ const CStdString& GetURL() const { return m_strURL; }
+ void SetURL(const CStdString& strURL) { m_strURL = strURL; }
+
+ // Platform
+ const CStdString& GetPlatform() const { return m_strPlatform; }
+ void SetPlatform(const CStdString& strPlatform) { m_strPlatform = strPlatform; }
+
+ // Title
+ const CStdString& GetTitle() const { return m_strName; }
+ void SetTitle(const CStdString& strName) { m_strName = strName; }
+
+ // Game Code (ID)
+ const CStdString& GetID() const { return m_strCode; }
+ void SetID(const CStdString& strCode) { m_strCode = strCode; }
+
+ // Region
+ const CStdString& GetRegion() const { return m_strRegion; }
+ void SetRegion(const CStdString& strRegion) { m_strRegion = strRegion; }
+
+ // Publisher / Licensee
+ const CStdString& GetPublisher() const { return m_strPublisher; }
+ void SetPublisher(const CStdString& strPublisher) { m_strPublisher = strPublisher; }
+
+ // Format (PAL/NTSC); this is empty iff Region is empty
+ const CStdString& GetFormat() const { return m_strFormat; }
+ void SetFormat(const CStdString& strFormat) { m_strFormat = strFormat; }
+
+ // Cartridge Type, e.g. ROM+MBC5+RAM+BATT
+ const CStdString& GetCartridgeType() const { return m_strCartridgeType; }
+ void SetCartridgeType(const CStdString& strCartridgeType) { m_strCartridgeType = strCartridgeType; }
+
+ virtual void Archive(CArchive &ar);
+ virtual void Serialize(CVariant &value) const;
+ virtual void ToSortable(SortItem &sortable);
+
+ private:
+ bool m_bLoaded;
+ CStdString m_strURL;
+ CStdString m_strPlatform;
+ CStdString m_strName;
+ CStdString m_strCode;
+ CStdString m_strRegion;
+ CStdString m_strPublisher;
+ CStdString m_strFormat;
+ CStdString m_strCartridgeType;
+ };
+}
View
231 xbmc/games/tags/GameInfoTagLoader.cpp
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2012 Garrett Brown
+ * Copyright (C) 2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * 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; either version 2, or (at your option)
+ * any later version.
+ *
+ * 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "GameInfoTagLoader.h"
+#include "GameboyTag.h"
+#include "GBATag.h"
+#include "utils/log.h"
+#include "utils/StringUtils.h"
+#include "utils/URIUtils.h"
+
+using namespace GAME_INFO;
+
+// Lookups are made using comparisons between case-insensitive alphanumeric
+// strings. "CD-i" will match "CDi", "CD_I" and "CD I"
+static PlatformInfo platformInfo[] =
+{ // ID Name Ports Extensions
+ { PLATFORM_UNKNOWN, "", -1, "" },
+ { PLATFORM_AMBIGUOUS, "", -1, ".zip|.iso|.bin" },
+ { PLATFORM_3D0, "3DO", -1, "" },
+ { PLATFORM_AMIGA, "Amiga", -1, "" },
+ { PLATFORM_AMIGA_CD32, "Amiga CD32", -1, "" },
+ { PLATFORM_AMSTRAD_CPC, "Amstrad CPC", -1, "" },
+ { PLATFORM_APPLE_II, "Apple II", -1, "" },
+ { PLATFORM_ATARI_2600, "Atari 2600", -1, "" },
+ { PLATFORM_ATARI_5200, "Atari 5200", -1, "" },
+ { PLATFORM_ATARI_7800, "Atari 7800", -1, "" },
+ { PLATFORM_ATARI_8_BIT, "Atari 8-bit", -1, "" },
+ { PLATFORM_ATARI_ST, "Atari ST", -1, "" },
+ { PLATFORM_BBC_MICRO, "BBC Micro", -1, "" },
+ { PLATFORM_BREW, "BREW", -1, "" },
+ { PLATFORM_CD_I, "CD-i", -1, "" },
+ { PLATFORM_CHANNEL_F, "Channel F", -1, "" },
+ { PLATFORM_COLECO_VISION, "ColecoVision", -1, "" },
+ { PLATFORM_COMMODORE_128, "Commodore 128", -1, "" },
+ { PLATFORM_COMMODORE_64, "Commodore 64", -1, "" },
+ { PLATFORM_COMMODORE_PET_CBM, "Commodore PET/CBM", -1, "" },
+ { PLATFORM_DOJA, "DoJa", -1, "" },
+ { PLATFORM_DOS, "DOS", -1, "" },
+ { PLATFORM_DRAGON_32_64, "Dragon 32/64", -1, "" },
+ { PLATFORM_DREAMCAST, "Dreamcast", -1, "" },
+ { PLATFORM_ELECTRON, "Electron", -1, "" },
+ { PLATFORM_EXEN, "ExEn", -1, "" },
+ { PLATFORM_GAMEBOY, "Game Boy", -1, ".gb" },
+ { PLATFORM_GAMEBOY_ADVANCE, "Game Boy Advance", -1, ".gba|.agb|.elf|.mb|.bin" },
+ { PLATFORM_GAMEBOY_COLOR, "Game Boy Color", -1, ".gbc|.cgb|.sgb" },
+ { PLATFORM_GAMECUBE, "GameCube", -1, "" },
+ { PLATFORM_GAME_GEAR, "Game Gear", -1, "" },
+ { PLATFORM_GENESIS, "Genesis", -1, "" },
+ { PLATFORM_GIZMONDO, "Gizmondo", -1, "" },
+ { PLATFORM_INTELLIVISION, "Intellivision", -1, "" },
+ { PLATFORM_JAGUAR, "Jaguar", -1, "" },
+ { PLATFORM_LINUX, "Linux", -1, "" },
+ { PLATFORM_LYNX, "Lynx", -1, "" },
+ { PLATFORM_MACINTOSH, "Macintosh", -1, "" },
+ { PLATFORM_MAME, "MAME", -1, "" },
+ { PLATFORM_MOPHUN, "Mophun", -1, "" },
+ { PLATFORM_MSX, "MSX", -1, "" },
+ { PLATFORM_NEO_GEO, "Neo Geo", -1, "" },
+ { PLATFORM_NEO_GEO_CD, "Neo Geo CD", -1, "" },
+ { PLATFORM_NEO_GEO_POCKET, "Neo Geo Pocket", -1, "" },
+ { PLATFORM_NEO_GEO_POCKET_COLOR, "Neo Geo Pocket Color", -1, "" },
+ { PLATFORM_NES, "NES", -1, "" },
+ { PLATFORM_N_GAGE, "N-Gage", -1, "" },
+ { PLATFORM_NINTENDO_64, "Nintendo 64", -1, "" },
+ { PLATFORM_NINTENDO_DS, "Nintendo DS", -1, "" },
+ { PLATFORM_NINTENDO_DSI, "Nintendo DSi", -1, "" },
+ { PLATFORM_ODYSSEY, "Odyssey", -1, "" },
+ { PLATFORM_ODYSSEY_2, "Odyssey 2", -1, "" },
+ { PLATFORM_PC_88, "PC-88", -1, "" },
+ { PLATFORM_PC_98, "PC-98", -1, "" },
+ { PLATFORM_PC_BOOTER, "PC Booter", -1, "" },
+ { PLATFORM_PC_FX, "PC-FX", -1, "" },
+ { PLATFORM_PLAYSTATION, "PlayStation", -1, "" },
+ { PLATFORM_PLAYSTATION_2, "PlayStation 2", -1, "" },
+ { PLATFORM_PLAYSTATION_3, "PlayStation 3", -1, "" },
+ { PLATFORM_PSP, "PSP", -1, "" },
+ { PLATFORM_SEGA_32X, "SEGA 32X ", -1, "" },
+ { PLATFORM_SEGA_CD, "SEGA CD", -1, "" },
+ { PLATFORM_SEGA_MASTER_SYSTEM, "SEGA Master System", -1, "" },
+ { PLATFORM_SEGA_SATURN, "SEGA Saturn", -1, "" },
+ { PLATFORM_SNES, "SNES", -1, ".smc|.sfc|.fig|.gd3|.gd7|.dx2|.bsx|.swc" },
+ { PLATFORM_SPECTRAVIDEO, "Spectravideo", -1, "" },
+ { PLATFORM_TI_99_4A, "TI-99/4A", -1, "" },
+ { PLATFORM_TRS_80, "TRS-80", -1, "" },
+ { PLATFORM_TRS_80_COCO, "TRS-80 CoCo", -1, "" },
+ { PLATFORM_TURBOGRAFX_16, "TurboGrafx-16", -1, "" },
+ { PLATFORM_TURBOGRAFX_CD, "TurboGrafx CD", -1, "" },
+ { PLATFORM_VECTREX, "Vectrex", -1, "" },
+ { PLATFORM_VIC_20, "VIC-20", -1, "" },
+ { PLATFORM_VIRTUAL_BOY, "Virtual Boy", -1, "" },
+ { PLATFORM_V_SMILE, "V.Smile", -1, "" },
+ { PLATFORM_WII, "Wii", -1, "" },
+ { PLATFORM_WINDOWS, "Windows", -1, "" },
+ { PLATFORM_WINDOWS_3X, "Windows 3.x", -1, "" },
+ { PLATFORM_WONDERSWAN, "WonderSwan", -1, "" },
+ { PLATFORM_WONDERSWAN_COLOR, "WonderSwan Color", -1, "" },
+ { PLATFORM_XBOX, "Xbox", -1, "" },
+ { PLATFORM_XBOX_360, "Xbox 360", -1, "" },
+ { PLATFORM_ZEEBO, "Zeebo", -1, "" },
+ { PLATFORM_ZODIAC, "Zodiac", -1, "" },
+ { PLATFORM_ZX_SPECTR, "ZX Spectr", -1, "" },
+};
+
+/* static */
+CGameInfoTagLoader &CGameInfoTagLoader::Get()
+{
+ static CGameInfoTagLoader gameInfoTagLoaderInstance;
+ return gameInfoTagLoaderInstance;
+}
+
+bool CGameInfoTagLoader::Load(const CStdString &strPath, CGameInfoTag &tag)
+{
+ if (strPath.IsEmpty())
+ return false;
+
+ PlatformInfo platform = GetPlatformByExtension(URIUtils::GetExtension(strPath));
+ if (platform.id == PLATFORM_UNKNOWN || platform.id == PLATFORM_AMBIGUOUS)
+ return false;
+
+ tag.SetPlatform(platform.name);
+ tag.SetLoaded(true);
+
+ switch (platform.id)
+ {
+ case PLATFORM_GAMEBOY:
+ case PLATFORM_GAMEBOY_COLOR:
+ CGameboyTag::Load(strPath, tag);
+ break;
+ case PLATFORM_GAMEBOY_ADVANCE:
+ CGBATag::Load(strPath, tag);
+ break;
+ default:
+ break;
+ }
+ return true;
+}
+
+/* static */
+const PlatformInfo &CGameInfoTagLoader::GetPlatformByName(const CStdString &strPlatform)
+{
+ if (strPlatform.empty())
+ return platformInfo[0]; // Unknown
+
+ for (size_t i = 0; i < sizeof(platformInfo) / sizeof(platformInfo[0]); i++)
+ if (SanitizedEquals(strPlatform.c_str(), platformInfo[i].name))
+ return platformInfo[i];
+
+ return platformInfo[0];
+}
+
+/* static */
+const PlatformInfo &CGameInfoTagLoader::GetPlatformByExtension(const CStdString &strExtension)
+{
+ if (strExtension.empty())
+ return platformInfo[0];
+
+ CStdString strExt(strExtension);
+ strExt.ToLower();
+
+ for (size_t i = 0; i < sizeof(platformInfo) / sizeof(platformInfo[0]); i++)
+ {
+ if (platformInfo[i].extensions[0] == '\0')
+ continue; // No extensions
+
+ CStdStringArray vecExts;
+ StringUtils::SplitString(platformInfo[i].extensions, "|", vecExts);
+ for (unsigned int i = 0; i < vecExts.size(); i++)
+ if (vecExts[i].Equals(strExtension))
+ return platformInfo[i];
+ }
+ return platformInfo[0]; // Unknown
+}
+
+/* static */
+const PlatformInfo &CGameInfoTagLoader::GetPlatformByID(GamePlatform platform)
+{
+ for (size_t i = 0; i < sizeof(platformInfo) / sizeof(platformInfo[0]); i++)
+ if (platformInfo[i].id == platform)
+ return platformInfo[i];
+ return platformInfo[0]; // Unknown
+}
+
+#define IS_ALPHANUMERIC(c) (('a' <= (c) && (c) <= 'z') || ('A' <= (c) && (c) <= 'Z') || ('0' <= (c) && (c) <= '0'))
+#define LOWER(c) (('A' <= (c) && (c) <= 'Z') ? (c) - 'A' + 'a' : (c))
+
+/* static */
+bool CGameInfoTagLoader::SanitizedEquals(const char *str1, const char *str2)
+{
+ // Sanity check
+ if (!str1 || !str2)
+ return false;
+
+ // Break at the first null character
+ for (; *str1 && *str2; )
+ {
+ // Advance to the next alphanumeric character
+ while (*str1 && !IS_ALPHANUMERIC(*str1))
+ str1++;
+ while (*str2 && !IS_ALPHANUMERIC(*str2))
+ str2++;
+
+ // If they differ, we're done here, otherwise increment and continue
+ if (LOWER(*str1) != LOWER(*str2))
+ return false;
+
+ str1++;
+ str2++;
+ }
+
+ // Final test, return true if these are both null
+ return *str1 == *str2;
+}
View
165 xbmc/games/tags/GameInfoTagLoader.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2012 Garrett Brown
+ * Copyright (C) 2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * 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; either version 2, or (at your option)
+ * any later version.
+ *
+ * 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+#pragma once
+
+#include "GameInfoTag.h"
+#include "utils/StdString.h"
+
+namespace GAME_INFO
+{
+ // Platforms that XBMC is currently aware of
+ // Game ID used is MobyGames ID
+ enum GamePlatform
+ {
+ PLATFORM_UNKNOWN = -2,
+ PLATFORM_AMBIGUOUS = -1,
+ PLATFORM_3D0 = 35,
+ PLATFORM_AMIGA = 19,
+ PLATFORM_AMIGA_CD32 = 56,
+ PLATFORM_AMSTRAD_CPC = 60,
+ PLATFORM_APPLE_II = 31,
+ PLATFORM_ATARI_2600 = 28,
+ PLATFORM_ATARI_5200 = 33,
+ PLATFORM_ATARI_7800 = 34,
+ PLATFORM_ATARI_8_BIT = 39,
+ PLATFORM_ATARI_ST = 24,
+ PLATFORM_BBC_MICRO = 92,
+ PLATFORM_BREW = 63,
+ PLATFORM_CD_I = 73,
+ PLATFORM_CHANNEL_F = 76,
+ PLATFORM_COLECO_VISION = 29,
+ PLATFORM_COMMODORE_128 = 61,
+ PLATFORM_COMMODORE_64 = 27,
+ PLATFORM_COMMODORE_PET_CBM = 77,
+ PLATFORM_DOJA = 72,
+ PLATFORM_DOS = 2,
+ PLATFORM_DRAGON_32_64 = 79,
+ PLATFORM_DREAMCAST = 8,
+ PLATFORM_ELECTRON = 93,
+ PLATFORM_EXEN = 70,
+ PLATFORM_GAMEBOY = 10,
+ PLATFORM_GAMEBOY_ADVANCE = 12,
+ PLATFORM_GAMEBOY_COLOR = 11,
+ PLATFORM_GAMECUBE = 14,
+ PLATFORM_GAME_GEAR = 25,
+ PLATFORM_GENESIS = 16,
+ PLATFORM_GIZMONDO = 55,
+ PLATFORM_INTELLIVISION = 30,
+ PLATFORM_JAGUAR = 17,
+ PLATFORM_LINUX = 1,
+ PLATFORM_LYNX = 18,
+ PLATFORM_MACINTOSH = 74,
+ PLATFORM_MAME = 0, // No platform, per se
+ PLATFORM_MOPHUN = 71,
+ PLATFORM_MSX = 57,
+ PLATFORM_NEO_GEO = 36,
+ PLATFORM_NEO_GEO_CD = 54,
+ PLATFORM_NEO_GEO_POCKET = 52,
+ PLATFORM_NEO_GEO_POCKET_COLOR = 53,
+ PLATFORM_NES = 22,
+ PLATFORM_N_GAGE = 32,
+ PLATFORM_NINTENDO_64 = 9,
+ PLATFORM_NINTENDO_DS = 44,
+ PLATFORM_NINTENDO_DSI = 87,
+ PLATFORM_ODYSSEY = 75,
+ PLATFORM_ODYSSEY_2 = 78,
+ PLATFORM_PC_88 = 94,
+ PLATFORM_PC_98 = 95,
+ PLATFORM_PC_BOOTER = 4,
+ PLATFORM_PC_FX = 59,
+ PLATFORM_PLAYSTATION = 6,
+ PLATFORM_PLAYSTATION_2 = 7,
+ PLATFORM_PLAYSTATION_3 = 81,
+ PLATFORM_PSP = 46,
+ PLATFORM_SEGA_32X = 21,
+ PLATFORM_SEGA_CD = 20,
+ PLATFORM_SEGA_MASTER_SYSTEM = 26,
+ PLATFORM_SEGA_SATURN = 23,
+ PLATFORM_SNES = 15,
+ PLATFORM_SPECTRAVIDEO = 85,
+ PLATFORM_TI_99_4A = 47,
+ PLATFORM_TRS_80 = 58,
+ PLATFORM_TRS_80_COCO = 62,
+ PLATFORM_TURBOGRAFX_16 = 40,
+ PLATFORM_TURBOGRAFX_CD = 45,
+ PLATFORM_VECTREX = 37,
+ PLATFORM_VIC_20 = 43,
+ PLATFORM_VIRTUAL_BOY = 38,
+ PLATFORM_V_SMILE = 42,
+ PLATFORM_WII = 82,
+ PLATFORM_WINDOWS = 3,
+ PLATFORM_WINDOWS_3X = 5,
+ PLATFORM_WONDERSWAN = 48,
+ PLATFORM_WONDERSWAN_COLOR = 49,
+ PLATFORM_XBOX = 13,
+ PLATFORM_XBOX_360 = 69,
+ PLATFORM_ZEEBO = 88,
+ PLATFORM_ZODIAC = 68,
+ PLATFORM_ZX_SPECTR = 41,
+ };
+
+ typedef std::vector<GamePlatform> GamePlatformArray;
+
+ struct PlatformInfo
+ {
+ GamePlatform id;
+ const char *name;
+ int ports; // -1 for unknown
+ const char *extensions; // Must be unique to the platform (e.g. no zip)
+ CStdStringArray vecExtensions; // Cache of extensions plus advanced settings, first populated on Get()
+ };
+
+ class CGameInfoTagLoader
+ {
+ public:
+ static CGameInfoTagLoader &Get();
+
+ bool Load(const CStdString &strPath, CGameInfoTag &tag);
+
+ /**
+ * Get platform info by the platform's name. See struct platformInfo in
+ * GameInfoTagLoader.cpp. The comparison is performed case-, space- and
+ * punctuation-insensitive. If the name isn't recognized as a valid game
+ * platform, a PLATFORM_UNKNOWN struct is returned.
+ */
+ static const PlatformInfo &GetPlatformByName(const CStdString &strPlatform);
+
+ /**
+ * Resolve a known extension name into a PlatformInfo struct. If the
+ * extension isn't listed in struct platformInfo, PLATFORM_UNKOWN is
+ * returned. If the extension is valid for more than 1 platform (zip, bin),
+ * PLATFORM_UNKOWN is returned.
+ */
+ static const PlatformInfo &GetPlatformByExtension(const CStdString &strExtension);
+
+ /**
+ * Look up platform information by ID.
+ */
+ static const PlatformInfo &GetPlatformByID(GamePlatform id);
+
+ private:
+ /**
+ * Strip all non-alphanumeric characters and compare strings case-insensitive.
+ */
+ static bool SanitizedEquals(const char *str1, const char *str2);
+ };
+}
View
398 xbmc/games/tags/GameboyTag.cpp
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2012 Garrett Brown
+ * Copyright (C) 2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * 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; either version 2, or (at your option)
+ * any later version.
+ *
+ * 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "GameboyTag.h"
+#include "GameInfoTagLoader.h"
+#include "filesystem/File.h"
+#include "utils/log.h"
+
+using namespace GAME_INFO;
+using namespace XFILE;
+
+// Constants and file format data from VBA-M project
+// http://sourceforge.net/projects/vbam
+// This code references VBA-M at r1118, later commits may contain fixes
+
+/* static */
+void CGameboyTag::Load(const CStdString& strPath, CGameInfoTag &gameInfoTag)
+{
+ // Open the file and read in the data
+ CFile file;
+ if (!file.Open(strPath))
+ return;
+
+ char data[0x147 + 2];
+ if (file.Read(data, sizeof(data)) != sizeof(data))
+ return;
+
+ // Correct the platform if the extension was wrong
+ if (data[0x143] & 0x80)
+ gameInfoTag.SetPlatform(CGameInfoTagLoader::GetPlatformByID(PLATFORM_GAMEBOY_COLOR).name);
+ //else if (data[0x146] == 0x03)
+ // m_gameInfoTag.SetPlatform(CGameInfoTagLoader::GetPlatformByID(PLATFORM_SUPER_GAMEBOY).name);
+ else
+ gameInfoTag.SetPlatform(CGameInfoTagLoader::GetPlatformByID(PLATFORM_GAMEBOY).name);
+
+ // Title: $134, 15 bytes
+ for (unsigned int i = 0x134; i < 0x134 + 15; i++)
+ {
+ if ((0 < data[i] && data[i] < 32) || 126 < data[i]) // zero is ok
+ {
+ CLog::Log(LOGINFO, "CGameboyTag: Non-ASCII data encountered, assuming it's not a game image");
+ return;
+ }
+ }
+ gameInfoTag.SetTitle(CStdString(std::string(data + 0x134, 15)).Trim());
+
+ // Publisher: $144, 2 bytes
+ gameInfoTag.SetPublisher(CGameboyTag::TranslatePublisher(data + 0x144));
+
+ // Cartridge Type: $147, 1 byte
+ CStdString type;
+ switch ((unsigned char)data[0x147])
+ {
+ case 0x00:
+ type = "ROM";
+ break;
+ case 0x01:
+ type = "ROM+MBC1";
+ break;
+ case 0x02:
+ type = "ROM+MBC1+RAM";
+ break;
+ case 0x03:
+ type = "ROM+MBC1+RAM+BATT";
+ break;
+ case 0x05:
+ type = "ROM+MBC2";
+ break;
+ case 0x06:
+ type = "ROM+MBC2+BATT";
+ break;
+ case 0x0b:
+ type = "ROM+MMM01";
+ break;
+ case 0x0c:
+ type = "ROM+MMM01+RAM";
+ break;
+ case 0x0d:
+ type = "ROM+MMM01+RAM+BATT";
+ break;
+ case 0x0f:
+ type = "ROM+MBC3+TIMER+BATT";
+ break;
+ case 0x10:
+ type = "ROM+MBC3+TIMER+RAM+BATT";
+ break;
+ case 0x11:
+ type = "ROM+MBC3";
+ break;
+ case 0x12:
+ type = "ROM+MBC3+RAM";
+ break;
+ case 0x13:
+ type = "ROM+MBC3+RAM+BATT";
+ break;
+ case 0x19:
+ type = "ROM+MBC5";
+ break;
+ case 0x1a:
+ type = "ROM+MBC5+RAM";
+ break;
+ case 0x1b:
+ type = "ROM+MBC5+RAM+BATT";
+ break;
+ case 0x1c:
+ type = "ROM+MBC5+RUMBLE";
+ break;
+ case 0x1d:
+ type = "ROM+MBC5+RUMBLE+RAM";
+ break;
+ case 0x1e:
+ type = "ROM+MBC5+RUMBLE+RAM+BATT";
+ break;
+ case 0x22:
+ type = "ROM+MBC7+BATT";
+ break;
+ case 0x55:
+ type = "GameGenie";
+ break;
+ case 0x56:
+ type = "GameShark V3.0";
+ break;
+ case 0xfc:
+ type = "ROM+POCKET CAMERA";
+ break;
+ case 0xfd:
+ type = "ROM+BANDAI TAMA5";
+ break;
+ case 0xfe:
+ type = "ROM+HuC-3";
+ break;
+ case 0xff:
+ type = "ROM+HuC-1";
+ break;
+ }
+ gameInfoTag.SetCartridgeType(type);
+}
+
+const char *CGameboyTag::TranslatePublisher(const char *code)
+{
+ if (!code) return "";
+
+ static struct
+ {
+ const char *code;
+ const char *name;
+ }
+ companies[] =
+ {
+ { "01", "Nintendo" },
+ { "02", "Rocket Games" },
+ { "08", "Capcom" },
+ { "09", "Hot B Co." },
+ { "0A", "Jaleco" },
+ { "0B", "Coconuts Japan" },
+ { "0C", "Coconuts Japan/G.X.Media" },
+ { "0H", "Starfish" },
+ { "0L", "Warashi Inc." },
+ { "0N", "Nowpro" },
+ { "0P", "Game Village" },
+ { "13", "Electronic Arts Japan" },
+ { "18", "Hudson Soft Japan" },
+ { "19", "S.C.P." },
+ { "1A", "Yonoman" },
+ { "1G", "SMDE" },
+ { "1P", "Creatures Inc." },
+ { "1Q", "TDK Deep Impresion" },
+ { "20", "Destination Software" },
+ { "22", "VR 1 Japan" },
+ { "25", "San-X" },
+ { "28", "Kemco Japan" },
+ { "29", "Seta" },
+ { "2H", "Ubisoft Japan" },
+ { "2K", "NEC InterChannel" },
+ { "2L", "Tam" },
+ { "2M", "Jordan" },
+ { "2N", "Smilesoft" },
+ { "2Q", "Mediakite" },
+ { "36", "Codemasters" },
+ { "37", "GAGA Communications" },
+ { "38", "Laguna" },
+ { "39", "Telstar Fun and Games" },
+ { "41", "Ubi Soft Entertainment" },
+ { "42", "Sunsoft" },
+ { "47", "Spectrum Holobyte" },
+ { "49", "IREM" },
+ { "4D", "Malibu Games" },
+ { "4F", "Eidos/U.S. Gold" },
+ { "4J", "Fox Interactive" },
+ { "4K", "Time Warner Interactive" },
+ { "4Q", "Disney" },
+ { "4S", "Black Pearl" },
+ { "4X", "GT Interactive" },
+ { "4Y", "RARE" },
+ { "4Z", "Crave Entertainment" },
+ { "50", "Absolute Entertainment" },
+ { "51", "Acclaim" },
+ { "52", "Activision" },
+ { "53", "American Sammy Corp." },
+ { "54", "Take 2 Interactive" },
+ { "55", "Hi Tech" },
+ { "56", "LJN LTD." },
+ { "58", "Mattel" },
+ { "5A", "Mindscape/Red Orb Ent." },
+ { "5C", "Taxan" },
+ { "5D", "Midway" },
+ { "5F", "American Softworks" },
+ { "5G", "Majesco Sales Inc" },
+ { "5H", "3DO" },
+ { "5K", "Hasbro" },
+ { "5L", "NewKidCo" },
+ { "5M", "Telegames" },
+ { "5N", "Metro3D" },
+ { "5P", "Vatical Entertainment" },
+ { "5Q", "LEGO Media" },
+ { "5S", "Xicat Interactive" },
+ { "5T", "Cryo Interactive" },
+ { "5W", "Red Storm Ent./BKN Ent." },
+ { "5X", "Microids" },
+ { "5Z", "Conspiracy Entertainment Corp." },
+ { "60", "Titus Interactive Studios" },
+ { "61", "Virgin Interactive" },
+ { "62", "Maxis" },
+ { "64", "LucasArts Entertainment" },
+ { "67", "Ocean" },
+ { "69", "Electronic Arts" },
+ { "6E", "Elite Systems Ltd." },
+ { "6F", "Electro Brain" },
+ { "6G", "The Learning Company" },
+ { "6H", "BBC" },
+ { "6J", "Software 2000" },
+ { "6L", "BAM! Entertainment" },
+ { "6M", "Studio 3" },
+ { "6Q", "Classified Games" },
+ { "6S", "TDK Mediactive" },
+ { "6U", "DreamCatcher" },
+ { "6V", "JoWood Productions" },
+ { "6W", "SEGA" },
+ { "6X", "Wannado Edition" },
+ { "6Y", "LSP" },
+ { "6Z", "ITE Media" },
+ { "70", "Infogrames" },
+ { "71", "Interplay" },
+ { "72", "JVC Musical Industries Inc" },
+ { "73", "Parker Brothers" },
+ { "75", "SCI" },
+ { "78", "THQ" },
+ { "79", "Accolade" },
+ { "7A", "Triffix Ent. Inc." },
+ { "7C", "Microprose Software" },
+ { "7D", "Universal Interactive Studios" },
+ { "7F", "Kemco" },
+ { "7G", "Rage Software" },
+ { "7H", "Encore" },
+ { "7J", "Zoo" },
+ { "7K", "BVM" },
+ { "7L", "Simon & Schuster Interactive" },
+ { "7M", "Asmik Ace Entertainment Inc./AIA" },
+ { "7N", "Empire Interactive" },
+ { "7Q", "Jester Interactive" },
+ { "7T", "Scholastic" },
+ { "7U", "Ignition Entertainment" },
+ { "7W", "Stadlbauer" },
+ { "80", "Misawa" },
+ { "83", "LOZC" },
+ { "8B", "Bulletproof Software" },
+ { "8C", "Vic Tokai Inc." },
+ { "8J", "General Entertainment" },
+ { "8N", "Success" },
+ { "8P", "SEGA Japan" },
+ { "91", "Chun Soft" },
+ { "92", "Video System" },
+ { "93", "BEC" },
+ { "96", "Yonezawa/S'pal" },
+ { "97", "Kaneko" },
+ { "99", "Victor Interactive Software" },
+ { "9A", "Nichibutsu/Nihon Bussan" },
+ { "9B", "Tecmo" },
+ { "9C", "Imagineer" },
+ { "9F", "Nova" },
+ { "9H", "Bottom Up" },
+ { "9L", "Hasbro Japan" },
+ { "9N", "Marvelous Entertainment" },
+ { "9P", "Keynet Inc." },
+ { "9Q", "Hands-On Entertainment" },
+ { "A0", "Telenet" },
+ { "A1", "Hori" },
+ { "A4", "Konami" },
+ { "A6", "Kawada" },
+ { "A7", "Takara" },
+ { "A9", "Technos Japan Corp." },
+ { "AA", "JVC" },
+ { "AC", "Toei Animation" },
+ { "AD", "Toho" },
+ { "AF", "Namco" },
+ { "AG", "Media Rings Corporation" },
+ { "AH", "J-Wing" },
+ { "AK", "KID" },
+ { "AL", "MediaFactory" },
+ { "AP", "Infogrames Hudson" },
+ { "AQ", "Kiratto. Ludic Inc" },
+ { "B0", "Acclaim Japan" },
+ { "B1", "ASCII" },
+ { "B2", "Bandai" },
+ { "B4", "Enix" },
+ { "B6", "HAL Laboratory" },
+ { "B7", "SNK" },
+ { "B9", "Pony Canyon Hanbai" },
+ { "BA", "Culture Brain" },
+ { "BB", "Sunsoft" },
+ { "BD", "Sony Imagesoft" },
+ { "BF", "Sammy" },
+ { "BG", "Magical" },
+ { "BJ", "Compile" },
+ { "BL", "MTO Inc." },
+ { "BN", "Sunrise Interactive" },
+ { "BP", "Global A Entertainment" },
+ { "BQ", "Fuuki" },
+ { "C0", "Taito" },
+ { "C2", "Kemco" },
+ { "C3", "Square Soft" },
+ { "C5", "Data East" },
+ { "C6", "Tonkin House" },
+ { "C8", "Koei" },
+ { "CA", "Konami/Palcom/Ultra" },
+ { "CB", "Vapinc/NTVIC" },
+ { "CC", "Use Co.,Ltd." },
+ { "CD", "Meldac" },
+ { "CE", "FCI/Pony Canyon" },
+ { "CF", "Angel" },
+ { "CM", "Konami Computer Entertainment Osaka" },
+ { "CP", "Enterbrain" },
+ { "D1", "Sofel" },
+ { "D2", "Quest" },
+ { "D3", "Sigma Enterprises" },
+ { "D4", "Ask Kodansa" },
+ { "D6", "Naxat" },
+ { "D7", "Copya System" },
+ { "D9", "Banpresto" },
+ { "DA", "TOMY" },
+ { "DB", "LJN Japan" },
+ { "DD", "NCS" },
+ { "DF", "Altron Corporation" },
+ { "DH", "Gaps Inc." },
+ { "DN", "ELF" },
+ { "E2", "Yutaka" },
+ { "E3", "Varie" },
+ { "E5", "Epoch" },
+ { "E7", "Athena" },
+ { "E8", "Asmik Ace Entertainment Inc." },
+ { "E9", "Natsume" },
+ { "EA", "King Records" },
+ { "EB", "Atlus" },
+ { "EC", "Epic/Sony Records" },
+ { "EE", "IGS" },
+ { "EL", "Spike" },
+ { "EM", "Konami Computer Entertainment Tokyo" },
+ { "EN", "Alphadream Corporation" },
+ { "F0", "A Wave" },
+ { "G1", "PCCW" },
+ { "G4", "KiKi Co Ltd" },
+ { "G5", "Open Sesame Inc." },
+ { "G6", "Sims" },
+ { "G7", "Broccoli" },
+ { "G8", "Avex" },
+ { "G9", "D3 Publisher" },
+ { "GB", "Konami Computer Entertainment Japan" },
+ { "GD", "Square-Enix" },
+ { "HY", "Sachen" },
+ { NULL, NULL }
+ };
+
+ for (int i = 0; companies[i].code; i++)
+ {
+ if (companies[i].code[0] == code[0] && companies[i].code[1] == code[1])
+ return companies[i].name;
+ }
+ return "";
+}
View
37 xbmc/games/tags/GameboyTag.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2012 Garrett Brown
+ * Copyright (C) 2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * 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; either version 2, or (at your option)
+ * any later version.
+ *
+ * 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+#pragma once
+
+#include "GameInfoTag.h"
+
+namespace GAME_INFO
+{
+ class CGameboyTag
+ {
+ public:
+ static void Load(const CStdString& strPath, CGameInfoTag &gameInfoTag);
+
+ private:
+ friend class CGBATag;
+ static const char *TranslatePublisher(const char *code);
+ };
+}
View
9 xbmc/games/tags/Makefile.in
@@ -0,0 +1,9 @@
+SRCS=GameboyTag.cpp \
+ GameInfoTag.cpp \
+ GameInfoTagLoader.cpp \
+ GBATag.cpp
+
+LIB=gameinfotags.a
+
+include @abs_top_srcdir@/Makefile.include
+-include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS)))
Please sign in to comment.
Something went wrong with that request. Please try again.