mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-22 11:19:17 +01:00
Searchengine changed: now find games, that hath the search string in it.
e.G. "SPOR" find "ea SPORts", "mario SPORts mix", "SPORe heros" and so on.
This commit is contained in:
parent
baff754740
commit
164889c917
@ -2,8 +2,8 @@
|
|||||||
<app version="1">
|
<app version="1">
|
||||||
<name> USB Loader GX</name>
|
<name> USB Loader GX</name>
|
||||||
<coder>USB Loader GX Team</coder>
|
<coder>USB Loader GX Team</coder>
|
||||||
<version>2.3 r1126</version>
|
<version>2.3 r1127</version>
|
||||||
<release_date>201111081925</release_date>
|
<release_date>201111111858</release_date>
|
||||||
<!-- // remove this line to enable arguments
|
<!-- // remove this line to enable arguments
|
||||||
<arguments>
|
<arguments>
|
||||||
<arg>--ios=250</arg>
|
<arg>--ios=250</arg>
|
||||||
|
@ -29,7 +29,7 @@ class cSearchButton
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GuiSearchBar::GuiSearchBar(const wchar_t *SearchChars) :
|
GuiSearchBar::GuiSearchBar(const std::set<wchar_t> &SearchChars) :
|
||||||
inSide(0), text((char *) NULL, 22, ( GXColor )
|
inSide(0), text((char *) NULL, 22, ( GXColor )
|
||||||
{ 0, 0, 0, 255}), buttons(0),
|
{ 0, 0, 0, 255}), buttons(0),
|
||||||
keyImageData(Resources::GetFile("keyboard_key.png"), Resources::GetFileSize("keyboard_key.png")),
|
keyImageData(Resources::GetFile("keyboard_key.png"), Resources::GetFileSize("keyboard_key.png")),
|
||||||
@ -39,24 +39,24 @@ GuiSearchBar::GuiSearchBar(const wchar_t *SearchChars) :
|
|||||||
trigB.SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B);
|
trigB.SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B);
|
||||||
SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
|
SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
|
||||||
|
|
||||||
cnt = wcslen(SearchChars);
|
cnt = SearchChars.size();
|
||||||
buttons = new cSearchButton*[cnt];
|
buttons = new cSearchButton*[cnt];
|
||||||
|
|
||||||
wchar_t charstr[2] = { 0, 0 };
|
wchar_t charstr[2] = { 0, 0 };
|
||||||
int lines = (cnt + 9) / 10;
|
int lines = (cnt + 9) / 10;
|
||||||
int buttonsPerLine = (cnt + lines - 1) / lines;
|
int buttonsPerLine = (cnt + lines - 1) / lines;
|
||||||
width = 10 + buttonsPerLine * 42 + 10;
|
width = 10 + buttonsPerLine * 42 + 10;
|
||||||
int x_start = 10, x = 0, y_start = 10 + 42, y = 0;
|
int i = 0, x_start = 10, x = 0, y_start = 10 + 42, y = 0;
|
||||||
if (width < 200)
|
if (width < 320)
|
||||||
{
|
{
|
||||||
x_start += (200 - width) >> 1;
|
x_start += (320 - width) >> 1;
|
||||||
width = 200;
|
width = 320;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < cnt; i++, x++)
|
for (std::set<wchar_t>::iterator it=SearchChars.begin() ; it != SearchChars.end(); it++, i++, x++)
|
||||||
{
|
{
|
||||||
if (x >= buttonsPerLine) x = 0;
|
if (x >= buttonsPerLine) x = 0;
|
||||||
if (x == 0) y++;
|
if (x == 0) y++;
|
||||||
charstr[0] = SearchChars[i];
|
charstr[0] = *it;
|
||||||
buttons[i] = new cSearchButton(charstr, &keyImageData, &keyOverImageData, x_start + x * 42, y_start - 42 + y
|
buttons[i] = new cSearchButton(charstr, &keyImageData, &keyOverImageData, x_start + x * 42, y_start - 42 + y
|
||||||
* 42, &trig, btnSoundOver, btnSoundClick);
|
* 42, &trig, btnSoundOver, btnSoundClick);
|
||||||
this->Append(&(buttons[i]->button));
|
this->Append(&(buttons[i]->button));
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
#ifndef GUI_SEARCHBAR_H_
|
#ifndef GUI_SEARCHBAR_H_
|
||||||
#define GUI_SEARCHBAR_H_
|
#define GUI_SEARCHBAR_H_
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
|
#include <set>
|
||||||
|
|
||||||
class cSearchButton;
|
class cSearchButton;
|
||||||
|
|
||||||
class GuiSearchBar: public GuiWindow
|
class GuiSearchBar: public GuiWindow
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GuiSearchBar(const wchar_t *SearchChars);
|
GuiSearchBar(const std::set<wchar_t> &SearchChars);
|
||||||
virtual ~GuiSearchBar();
|
virtual ~GuiSearchBar();
|
||||||
void Draw();
|
void Draw();
|
||||||
void Update(GuiTrigger * t);
|
void Update(GuiTrigger * t);
|
||||||
|
@ -908,13 +908,39 @@ int GameBrowseMenu::MainLoop()
|
|||||||
{
|
{
|
||||||
if (searchChar > 27) //! Character clicked
|
if (searchChar > 27) //! Character clicked
|
||||||
{
|
{
|
||||||
int len = gameList.GetCurrentFilter() ? wcslen(gameList.GetCurrentFilter()) : 0;
|
for(;;)
|
||||||
|
{
|
||||||
|
int len = wcslen(gameList.GetCurrentFilter());
|
||||||
wchar_t newFilter[len + 2];
|
wchar_t newFilter[len + 2];
|
||||||
if (gameList.GetCurrentFilter()) wcscpy(newFilter, gameList.GetCurrentFilter());
|
wcscpy(newFilter, gameList.GetCurrentFilter());
|
||||||
newFilter[len] = searchChar;
|
newFilter[len] = searchChar;
|
||||||
newFilter[len + 1] = 0;
|
newFilter[len + 1] = 0;
|
||||||
|
|
||||||
gameList.FilterList(newFilter);
|
gameList.FilterList(newFilter);
|
||||||
|
if(gameList.GetAvailableSearchChars().size() != 1)
|
||||||
|
break;
|
||||||
|
searchChar = *gameList.GetAvailableSearchChars().begin();
|
||||||
|
}
|
||||||
|
bool autoClose = false;
|
||||||
|
switch(Settings.gameDisplay)
|
||||||
|
{
|
||||||
|
case LIST_MODE:
|
||||||
|
autoClose = gameList.size()<=9;
|
||||||
|
break;
|
||||||
|
case CAROUSEL_MODE:
|
||||||
|
autoClose = gameList.size()<=5;
|
||||||
|
break;
|
||||||
|
case GRID_MODE:
|
||||||
|
autoClose = gameList.size()<=3;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(autoClose) // Close Searchwindow when less than 5 Games found
|
||||||
|
{
|
||||||
|
show_searchwindow = false;
|
||||||
|
searchBtn->StopEffect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (searchChar == 27) //! Close
|
else if (searchChar == 27) //! Close
|
||||||
{
|
{
|
||||||
@ -930,11 +956,16 @@ int GameBrowseMenu::MainLoop()
|
|||||||
{
|
{
|
||||||
int len = wcslen(gameList.GetCurrentFilter());
|
int len = wcslen(gameList.GetCurrentFilter());
|
||||||
wchar_t newFilter[len + 1];
|
wchar_t newFilter[len + 1];
|
||||||
if (gameList.GetCurrentFilter()) wcscpy(newFilter, gameList.GetCurrentFilter());
|
wcscpy(newFilter, gameList.GetCurrentFilter());
|
||||||
newFilter[len > 0 ? len - 1 : 0] = 0;
|
int old_game_count = gameList.size();
|
||||||
gameList.FilterList(newFilter);
|
for(; len > 0; len--)
|
||||||
|
{
|
||||||
|
newFilter[len - 1] = 0; // remove last char
|
||||||
if(len == 1)
|
if(len == 1)
|
||||||
Settings.gridRows = GridRowsPreSearch; //! restore old rows amount so we don't stay on one row
|
Settings.gridRows = GridRowsPreSearch; //! restore old rows amount so we don't stay on one row
|
||||||
|
if(gameList.FilterList(newFilter) != old_game_count)
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ReloadBrowser();
|
ReloadBrowser();
|
||||||
return MENU_NONE;
|
return MENU_NONE;
|
||||||
|
@ -181,14 +181,6 @@ int GameList::ReadGameList()
|
|||||||
return LoadUnfiltered();
|
return LoadUnfiltered();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool WCharSortCallback(const wchar_t char1, const wchar_t char2)
|
|
||||||
{
|
|
||||||
if (char2 == 0) return true;
|
|
||||||
if (char1 == 0) return false;
|
|
||||||
|
|
||||||
return char2 > char1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int GameList::FilterList(const wchar_t * gameFilter)
|
int GameList::FilterList(const wchar_t * gameFilter)
|
||||||
{
|
{
|
||||||
if (FullGameList.size() == 0) ReadGameList();
|
if (FullGameList.size() == 0) ReadGameList();
|
||||||
@ -251,22 +243,30 @@ int GameList::FilterList(const wchar_t * gameFilter)
|
|||||||
if(n == Settings.EnabledCategories.size()) continue;
|
if(n == Settings.EnabledCategories.size()) continue;
|
||||||
|
|
||||||
wchar_t *gameName = charToWideChar(GameTitles.GetTitle(header));
|
wchar_t *gameName = charToWideChar(GameTitles.GetTitle(header));
|
||||||
if (gameName && *GameFilter.c_str())
|
if (gameName)
|
||||||
{
|
{
|
||||||
if (wcsnicmp(gameName, GameFilter.c_str(), GameFilter.size()) != 0)
|
if ( GameFilter.size() ) // has Filter
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
wchar_t *s1 = gameName, *s2;
|
||||||
|
while( (s2 = wcscasestr(s1, GameFilter.c_str())) ) // search filter in gameName
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
wchar_t ch = towupper(s2[GameFilter.size()]);
|
||||||
|
if(ch) AvailableSearchChars.insert(ch);
|
||||||
|
s1++; // try search filter in gameName more times
|
||||||
|
}
|
||||||
|
if(!found)
|
||||||
{
|
{
|
||||||
delete [] gameName;
|
delete [] gameName;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else // no Filter -> makes all chars as aviable
|
||||||
if (gameName)
|
|
||||||
{
|
{
|
||||||
if (wcslen(gameName) > GameFilter.size() &&
|
for(wchar_t *ch = gameName; *ch; ch++)
|
||||||
AvailableSearchChars.find(towupper(gameName[GameFilter.size()])) == std::string::npos &&
|
if(*ch >= '@') // limit chars by empty filter
|
||||||
AvailableSearchChars.find(towlower(gameName[GameFilter.size()])) == std::string::npos)
|
AvailableSearchChars.insert(towupper(*ch));
|
||||||
{
|
|
||||||
AvailableSearchChars.push_back(gameName[GameFilter.size()]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete [] gameName;
|
delete [] gameName;
|
||||||
@ -277,7 +277,7 @@ int GameList::FilterList(const wchar_t * gameFilter)
|
|||||||
|
|
||||||
NewTitles::Instance()->Save();
|
NewTitles::Instance()->Save();
|
||||||
|
|
||||||
AvailableSearchChars.push_back(L'\0');
|
if (FilteredList.size() < 2)
|
||||||
|
|
||||||
if (FilteredList.size() < 2)
|
if (FilteredList.size() < 2)
|
||||||
AvailableSearchChars.clear();
|
AvailableSearchChars.clear();
|
||||||
@ -305,12 +305,9 @@ int GameList::LoadUnfiltered()
|
|||||||
wchar_t *gameName = charToWideChar(GameTitles.GetTitle(header));
|
wchar_t *gameName = charToWideChar(GameTitles.GetTitle(header));
|
||||||
if (gameName)
|
if (gameName)
|
||||||
{
|
{
|
||||||
if (wcslen(gameName) > GameFilter.size() &&
|
for(wchar_t *ch = gameName; *ch; ch++)
|
||||||
AvailableSearchChars.find(towupper(gameName[GameFilter.size()])) == std::string::npos &&
|
if(*ch >= '@') // limit chars by unfiltered list
|
||||||
AvailableSearchChars.find(towlower(gameName[GameFilter.size()])) == std::string::npos)
|
AvailableSearchChars.insert(towupper(*ch));
|
||||||
{
|
|
||||||
AvailableSearchChars.push_back(gameName[GameFilter.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete [] gameName;
|
delete [] gameName;
|
||||||
}
|
}
|
||||||
@ -320,8 +317,6 @@ int GameList::LoadUnfiltered()
|
|||||||
|
|
||||||
NewTitles::Instance()->Save();
|
NewTitles::Instance()->Save();
|
||||||
|
|
||||||
AvailableSearchChars.push_back(L'\0');
|
|
||||||
|
|
||||||
if (FilteredList.size() < 2)
|
if (FilteredList.size() < 2)
|
||||||
AvailableSearchChars.clear();
|
AvailableSearchChars.clear();
|
||||||
|
|
||||||
@ -350,10 +345,6 @@ void GameList::SortList()
|
|||||||
{
|
{
|
||||||
std::sort(FilteredList.begin(), FilteredList.end(), NameSortCallback);
|
std::sort(FilteredList.begin(), FilteredList.end(), NameSortCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AvailableSearchChars.size() > 1)
|
|
||||||
std::sort(AvailableSearchChars.begin(), AvailableSearchChars.end(), WCharSortCallback);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GameList::NameSortCallback(const struct discHdr *a, const struct discHdr *b)
|
bool GameList::NameSortCallback(const struct discHdr *a, const struct discHdr *b)
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define GAME_LIST_H_
|
#define GAME_LIST_H_
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <set>
|
||||||
#include "Controls/DeviceHandler.hpp"
|
#include "Controls/DeviceHandler.hpp"
|
||||||
#include "wstring.hpp"
|
#include "wstring.hpp"
|
||||||
#include "usbloader/disc.h"
|
#include "usbloader/disc.h"
|
||||||
@ -19,7 +20,7 @@ class GameList
|
|||||||
struct discHdr * operator[](int i) const { if (i < 0 || i >= (int) FilteredList.size()) return NULL; return FilteredList[i]; }
|
struct discHdr * operator[](int i) const { if (i < 0 || i >= (int) FilteredList.size()) return NULL; return FilteredList[i]; }
|
||||||
struct discHdr * GetDiscHeader(const char * gameID) const;
|
struct discHdr * GetDiscHeader(const char * gameID) const;
|
||||||
const wchar_t * GetCurrentFilter() const { return GameFilter.c_str(); }
|
const wchar_t * GetCurrentFilter() const { return GameFilter.c_str(); }
|
||||||
const wchar_t * GetAvailableSearchChars() const { return AvailableSearchChars.c_str(); }
|
const std::set<wchar_t> &GetAvailableSearchChars() const { return AvailableSearchChars; }
|
||||||
void SortList();
|
void SortList();
|
||||||
void clear();
|
void clear();
|
||||||
bool operator!() const { return (FullGameList.size() == 0); }
|
bool operator!() const { return (FullGameList.size() == 0); }
|
||||||
@ -41,7 +42,7 @@ class GameList
|
|||||||
static bool RankingSortCallback(const struct discHdr *a, const struct discHdr *b);
|
static bool RankingSortCallback(const struct discHdr *a, const struct discHdr *b);
|
||||||
static bool PlayersSortCallback(const struct discHdr *a, const struct discHdr *b);
|
static bool PlayersSortCallback(const struct discHdr *a, const struct discHdr *b);
|
||||||
|
|
||||||
wString AvailableSearchChars;
|
std::set<wchar_t> AvailableSearchChars;
|
||||||
wString GameFilter;
|
wString GameFilter;
|
||||||
int selectedGame;
|
int selectedGame;
|
||||||
std::vector<struct discHdr *> FilteredList;
|
std::vector<struct discHdr *> FilteredList;
|
||||||
|
@ -147,16 +147,15 @@ size_t utf8Len(const char *s)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wcsnicmp(const wchar_t *s1, const wchar_t *s2, int len)
|
wchar_t *wcscasestr(const wchar_t *s1, const wchar_t *s2)
|
||||||
{
|
{
|
||||||
if (len <= 0) return (0);
|
if(*s2==0) return (wchar_t *)s1;
|
||||||
|
int s1_len = wcslen(s1);
|
||||||
do
|
int s2_len = wcslen(s2);
|
||||||
{
|
if(s1_len < s2_len) return 0;
|
||||||
int r = towupper(*s1) - towupper(*s2++);
|
const wchar_t *end = &s1[s1_len-s2_len];
|
||||||
if (r) return r;
|
for(wchar_t *s=(wchar_t *)s1; s<=end; s++)
|
||||||
if (*s1++ == 0) break;
|
if(wcsncasecmp(s, s2, s2_len)==0)
|
||||||
} while (--len != 0);
|
return s;
|
||||||
|
return 0;
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ class wString: public std::basic_string<wchar_t, std::char_traits<wchar_t>, std:
|
|||||||
};
|
};
|
||||||
|
|
||||||
size_t utf8Len(const char *s);
|
size_t utf8Len(const char *s);
|
||||||
int wcsnicmp(const wchar_t *s1, const wchar_t *s2, int len);
|
|
||||||
|
wchar_t *wcscasestr(const wchar_t *s1, const wchar_t *s2);
|
||||||
|
|
||||||
#endif // !defined(__WSTRING_HPP)
|
#endif // !defined(__WSTRING_HPP)
|
||||||
|
Loading…
Reference in New Issue
Block a user