1 /* $Id$ */
2 /***************************************************************************
3  *                      (C) Copyright 2003 - Marauroa                      *
4  ***************************************************************************
5  ***************************************************************************
6  *                                                                         *
7  *   This program is free software; you can redistribute it and/or modify  *
8  *   it under the terms of the GNU General Public License as published by  *
9  *   the Free Software Foundation; either version 2 of the License, or     *
10  *   (at your option) any later version.                                   *
11  *                                                                         *
12  ***************************************************************************/
13 package games.stendhal.client;
14 
15 import java.awt.Graphics;
16 import java.io.IOException;
17 import java.io.InputStream;
18 
19 import org.apache.log4j.Logger;
20 
21 import games.stendhal.client.sprite.Sprite;
22 import games.stendhal.client.sprite.Tileset;
23 import games.stendhal.common.tiled.LayerDefinition;
24 
25 /**
26  * This is a helper class to render coherent tiles based on the tileset. This
27  * should be replaced by independent tiles as soon as possible .
28  */
29 class TileRenderer extends LayerRenderer {
30 	/** the logger instance. */
31 	private static final Logger logger = Logger.getLogger(TileRenderer.class);
32 	/** Tileset used for the map data */
33 	protected Tileset tileset;
34 	/** Raw map data. Indices of tiles in the tileset. */
35 	protected int[] map;
36 	/** The map data converted to tile references */
37 	protected Sprite[] spriteMap;
38 
TileRenderer()39 	public TileRenderer() {
40 		map = null;
41 		spriteMap = null;
42 	}
43 
44 	/**
45 	 * Sets the data that will be rendered.
46 	 * @param in the stream to read from
47 	 * @throws IOException
48 	 *
49 	 * @throws ClassNotFoundException
50 	 */
setMapData(final InputStream in)51 	public void setMapData(final InputStream in) throws IOException,
52 			ClassNotFoundException {
53 		final LayerDefinition layer = LayerDefinition.decode(in);
54 		width = layer.getWidth();
55 		height = layer.getHeight();
56 
57 		logger.debug("Layer(" + layer.getName() + "): " + width + "x" + height);
58 
59 		map = layer.expose();
60 	}
61 
62 	/**
63 	 * Set the tileset.
64 	 *
65 	 * @param tileset
66 	 *            The tileset.
67 	 */
68 	@Override
setTileset(final Tileset tileset)69 	public void setTileset(final Tileset tileset) {
70 		this.tileset = tileset;
71 	}
72 
73 	/**
74 	 * Initialize the sprite map from the tileset and the map data.
75 	 *
76 	 * @return true if the map is ready to be used, false otherwise.
77 	 */
initSpriteMap()78 	private boolean initSpriteMap() {
79 		if (spriteMap == null) {
80 			if (tileset != null) {
81 				/*
82 				 * Cache sprites
83 				 */
84 				spriteMap = new Sprite[map.length];
85 
86 				int i = spriteMap.length;
87 
88 				while (i-- != 0) {
89 					spriteMap[i] = tileset.getSprite(map[i]);
90 				}
91 			} else {
92 				return false;
93 			}
94 		}
95 		return true;
96 	}
97 
98 	@Override
draw(Graphics g, int x, int y, final int w, final int h)99 	public void draw(Graphics g, int x, int y, final int w, final int h) {
100 		if (!initSpriteMap()) {
101 			return;
102 		}
103 
104 		final int endX = Math.min(x + w, getWidth());
105 		final int endY= Math.min(y + h, getHeight());
106 
107 		int sy = y * IGameScreen.SIZE_UNIT_PIXELS;
108 		for (int j = y; j < endY; j++) {
109 			int mapidx = (j * width) + x;
110 			int sx = x * IGameScreen.SIZE_UNIT_PIXELS;
111 
112 			for (int i = x; i < endX; i++) {
113 				spriteMap[mapidx].draw(g, sx, sy);
114 				mapidx++;
115 				sx += IGameScreen.SIZE_UNIT_PIXELS;
116 			}
117 			sy += IGameScreen.SIZE_UNIT_PIXELS;
118 		}
119 	}
120 }
121