Skip to content

Commit

Permalink
UI|Home: Starting a game with package; show WAD title picture in dialog
Browse files Browse the repository at this point in the history
Any package can now be easily used in any profile via the package
info dialog. The “Play in…” button uses an ad-hoc game profile.

If a WAD contains a TITLE/TITLEPIC lump, and the appropriate game can
be identified, the title picture is shown in the package info dialog.
  • Loading branch information
skyjake committed Jan 15, 2017
1 parent 84393bb commit 9ea4679
Show file tree
Hide file tree
Showing 12 changed files with 184 additions and 90 deletions.
31 changes: 31 additions & 0 deletions doomsday/apps/client/include/resource/idtech1image.h
Expand Up @@ -20,6 +20,9 @@
#define DENG_CLIENT_RESOURCE_IDTECH1IMAGE_H

#include <de/Image>
#include <doomsday/LumpCatalog>

class Game;

/**
* Image that imports its content using Id Tech 1 graphics formats.
Expand Down Expand Up @@ -54,8 +57,36 @@ class IdTech1Image : public de::Image
*/
Size nominalSize() const;

public:
enum LogoFlag
{
UnmodifiedAppearance = 0,
ColorizedByFamily = 0x1,
Downscale50Percent = 0x2,
NullImageIfFails = 0x4, // by default returns a small fallback image

DefaultLogoFlags = ColorizedByFamily | Downscale50Percent,
};
Q_DECLARE_FLAGS(LogoFlags, LogoFlag)

/**
* Prepares a game logo image to be used in items. The image is based on the
* game's title screen image in its WAD file(s).
*
* @param game Game.
* @param catalog Catalog of selected lumps.
*
* @return Image.
*
* @todo This could be moved to a better location / other class. -jk
*/
static de::Image makeGameLogo(Game const &game, res::LumpCatalog const &catalog,
LogoFlags flags = DefaultLogoFlags);

private:
DENG2_PRIVATE(d)
};

Q_DECLARE_OPERATORS_FOR_FLAGS(IdTech1Image::LogoFlags)

#endif // DENG_CLIENT_RESOURCE_IDTECH1IMAGE_H
26 changes: 0 additions & 26 deletions doomsday/apps/client/include/ui/widgets/homeitemwidget.h
Expand Up @@ -75,31 +75,6 @@ class HomeItemWidget : public de::GuiWidget, public de::IAssetGroup

virtual void itemRightClicked();

public:
enum LogoFlag
{
UnmodifiedAppearance = 0,
ColorizedByFamily = 0x1,
Downscale50Percent = 0x2,

DefaultLogoFlags = ColorizedByFamily | Downscale50Percent,
};
Q_DECLARE_FLAGS(LogoFlags, LogoFlag)

/**
* Prepares a game logo image to be used in items. The image is based on the
* game's title screen image in its WAD file(s).
*
* @param game Game.
* @param catalog Catalog of selected lumps.
*
* @return Image.
*
* @todo This could be moved to a better location / other class. -jk
*/
static de::Image makeGameLogo(Game const &game, res::LumpCatalog const &catalog,
LogoFlags flags = DefaultLogoFlags);

signals:
void mouseActivity();
void doubleClicked();
Expand All @@ -112,6 +87,5 @@ class HomeItemWidget : public de::GuiWidget, public de::IAssetGroup
};

Q_DECLARE_OPERATORS_FOR_FLAGS(HomeItemWidget::Flags)
Q_DECLARE_OPERATORS_FOR_FLAGS(HomeItemWidget::LogoFlags)

#endif // DENG_CLIENT_UI_HOME_HOMEITEMWIDGET_H
51 changes: 51 additions & 0 deletions doomsday/apps/client/src/resource/idtech1image.cpp
Expand Up @@ -19,6 +19,9 @@
#include "resource/idtech1image.h"

#include <doomsday/resource/patch.h>
#include <doomsday/Game>

#include <de/Style>

using namespace de;
using namespace res;
Expand Down Expand Up @@ -72,3 +75,51 @@ Image::Size IdTech1Image::nominalSize() const
{
return d->nominalSize;
}

Image IdTech1Image::makeGameLogo(Game const &game,
res::LumpCatalog const &catalog,
LogoFlags flags)
{
try
{
if (game.isPlayable())
{
Block const playPal = catalog.read("PLAYPAL");
Block const title = catalog.read("TITLE");
Block const titlePic = catalog.read("TITLEPIC");

IdTech1Image img(title.isEmpty()? titlePic : title, playPal);

float const scaleFactor = flags.testFlag(Downscale50Percent)? .5f : 1.f;
Image::Size const finalSize(img.width() * scaleFactor,
img.height() * scaleFactor * 1.2f); // VGA aspect

Image logoImage(img.toQImage().scaled(finalSize.x, finalSize.y,
Qt::IgnoreAspectRatio,
Qt::SmoothTransformation));
if (flags & ColorizedByFamily)
{
String const colorId = "home.icon." +
(game.family().isEmpty()? "other" : game.family());
return logoImage.colorized(Style::get().colors().color(colorId));
}
return logoImage;
}
}
catch (Error const &er)
{
if (flags & NullImageIfFails) return Image();

LOG_RES_WARNING("Failed to load title picture for game \"%s\": %s")
<< game.title()
<< er.asText();
}
if (flags & NullImageIfFails)
{
return Image();
}
// Use a generic logo, some files are missing.
QImage img(64, 64, QImage::Format_ARGB32);
img.fill(Qt::black);
return img;
}
5 changes: 3 additions & 2 deletions doomsday/apps/client/src/ui/dialogs/packagesdialog.cpp
Expand Up @@ -21,6 +21,7 @@
#include "ui/widgets/homeitemwidget.h"
#include "ui/widgets/homemenuwidget.h"
#include "ui/widgets/packageinfodialog.h"
#include "resource/idtech1image.h"
#include "ui/clientwindow.h"
#include "clientapp.h"

Expand Down Expand Up @@ -277,8 +278,8 @@ DENG_GUI_PIMPL(PackagesDialog)
{
if (game && catalog.setPackages(requiredPackages + selectedPackages))
{
gameTitle->setImage(HomeItemWidget::makeGameLogo(*game, catalog,
HomeItemWidget::UnmodifiedAppearance));
gameTitle->setImage(IdTech1Image::makeGameLogo(*game, catalog,
IdTech1Image::UnmodifiedAppearance));
// List of the native required files.
StringList dataFiles;
for (String packageId : requiredPackages)
Expand Down
2 changes: 1 addition & 1 deletion doomsday/apps/client/src/ui/home/gamepanelbuttonwidget.cpp
Expand Up @@ -238,7 +238,7 @@ DENG_GUI_PIMPL(GamePanelButtonWidget)

void updateGameTitleImage()
{
self().icon().setImage(self().makeGameLogo(game(), catalog));
self().icon().setImage(IdTech1Image::makeGameLogo(game(), catalog));
}

void profileChanged(Profiles::AbstractProfile &)
Expand Down
Expand Up @@ -20,6 +20,7 @@
#include "ui/clientwindow.h"
#include "network/net_main.h"
#include "network/serverlink.h"
#include "resource/idtech1image.h"
#include "clientapp.h"
#include "dd_main.h"

Expand Down Expand Up @@ -218,7 +219,7 @@ void MultiplayerPanelButtonWidget::updateContent(shell::ServerInfo const &info)
/// @todo The server info should include the list of packages.
if (d->catalog.setPackages(game.requiredPackages()))
{
icon().setImage(makeGameLogo(game, d->catalog));
icon().setImage(IdTech1Image::makeGameLogo(game, d->catalog));
}
}
else
Expand Down
41 changes: 0 additions & 41 deletions doomsday/apps/client/src/ui/widgets/homeitemwidget.cpp
Expand Up @@ -389,47 +389,6 @@ void HomeItemWidget::focusLost()
void HomeItemWidget::itemRightClicked()
{}

Image HomeItemWidget::makeGameLogo(Game const &game, res::LumpCatalog const &catalog,
LogoFlags flags)
{
try
{
if (game.isPlayable())
{
Block const playPal = catalog.read("PLAYPAL");
Block const title = catalog.read("TITLE");
Block const titlePic = catalog.read("TITLEPIC");

IdTech1Image img(title.isEmpty()? titlePic : title, playPal);

float const scaleFactor = flags.testFlag(Downscale50Percent)? .5f : 1.f;
Image::Size const finalSize(img.width() * scaleFactor,
img.height() * scaleFactor * 1.2f); // VGA aspect

Image logoImage(img.toQImage().scaled(finalSize.x, finalSize.y,
Qt::IgnoreAspectRatio,
Qt::SmoothTransformation));
if (flags.testFlag(ColorizedByFamily))
{
String const colorId = "home.icon." +
(game.family().isEmpty()? "other" : game.family());
return logoImage.colorized(Style::get().colors().color(colorId));
}
return logoImage;
}
}
catch (Error const &er)
{
LOG_RES_WARNING("Failed to load title picture for game \"%s\": %s")
<< game.title()
<< er.asText();
}
// Use a generic logo, some files are missing.
QImage img(64, 64, QImage::Format_ARGB32);
img.fill(Qt::black);
return img;
}

void HomeItemWidget::addButton(GuiWidget *widget)
{
// Common styling.
Expand Down

0 comments on commit 9ea4679

Please sign in to comment.