1 /*
2 * Copyright (C) 2004 Ivo Danihelka (ivo@danihelka.net)
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 */
9 #include "LayeredPicture.h"
10
11 #include "Path.h"
12 #include "ResImagePack.h"
13 #include "ResourceException.h"
14 #include "SurfaceLock.h"
15 #include "PixelTool.h"
16
17 //-----------------------------------------------------------------
18 /**
19 * Create picture with two layers and color mask to select
20 * active areas.
21 *
22 * @throws ResourceException when lowerLayer and colorMask have
23 * different proportions
24 */
LayeredPicture(const Path & bg_file,const V2 & loc,const Path & lowerLayer,const Path & colorMask)25 LayeredPicture::LayeredPicture(const Path &bg_file, const V2 &loc,
26 const Path &lowerLayer, const Path &colorMask)
27 : Picture(bg_file, loc)
28 {
29 m_lowerLayer = ResImagePack::loadImage(lowerLayer);
30 m_colorMask = ResImagePack::loadImage(colorMask);
31 if (m_lowerLayer->w != m_colorMask->w
32 || m_lowerLayer->h != m_colorMask->h) {
33 SDL_FreeSurface(m_lowerLayer);
34 SDL_FreeSurface(m_colorMask);
35 SDL_FreeSurface(m_surface);
36
37 throw ResourceException(ExInfo(
38 "lowerLayer and colorMask have different proportions")
39 .addInfo("lowerLayer", lowerLayer.getNative())
40 .addInfo("colorMask", colorMask.getNative()));
41 }
42
43 setNoActive();
44 }
45 //-----------------------------------------------------------------
~LayeredPicture()46 LayeredPicture::~LayeredPicture()
47 {
48 SDL_FreeSurface(m_lowerLayer);
49 SDL_FreeSurface(m_colorMask);
50 }
51 //-----------------------------------------------------------------
52 /**
53 * Return pixel at worldLoc.
54 * Translates world coordinates to local coordinates.
55 */
56 Uint32
getMaskAtWorld(const V2 & worldLoc)57 LayeredPicture::getMaskAtWorld(const V2 &worldLoc)
58 {
59 V2 localLoc = worldLoc.minus(m_loc);
60 return getMaskAt(localLoc);
61 }
62 //-----------------------------------------------------------------
63 /**
64 * Return pixel at position from left top image corner.
65 */
66 Uint32
getMaskAt(const V2 & loc)67 LayeredPicture::getMaskAt(const V2 &loc)
68 {
69 Uint32 result = MASK_NO;
70
71 if ((0 <= loc.getX() && loc.getX() < m_colorMask->w)
72 && (0 <= loc.getY() && loc.getY() < m_colorMask->h))
73 {
74 SurfaceLock lock1(m_colorMask);
75 result = PixelTool::getPixel(m_colorMask,
76 loc.getX(), loc.getY());
77 }
78 return result;
79 }
80 //-----------------------------------------------------------------
81 void
drawOn(SDL_Surface * screen)82 LayeredPicture::drawOn(SDL_Surface *screen)
83 {
84 Picture::drawOn(screen);
85 if (m_activeColor == MASK_NO) {
86 return;
87 }
88
89 SurfaceLock lock1(screen);
90 SurfaceLock lock2(m_lowerLayer);
91 SurfaceLock lock3(m_colorMask);
92
93 //TODO: support alpha channels
94 for (int py = 0; py < m_colorMask->h; ++py) {
95 int world_y = m_loc.getY() + py;
96 for (int px = 0; px < m_colorMask->w; ++px) {
97 Uint32 sample = PixelTool::getPixel(m_colorMask, px, py);
98
99 if (sample == m_activeColor) {
100 SDL_Color lower = PixelTool::getColor(m_lowerLayer, px, py);
101 if (lower.unused == 255) {
102 PixelTool::putColor(screen,
103 m_loc.getX() + px, world_y, lower);
104 }
105 }
106 }
107 }
108 }
109
110