aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client/Minimap.cpp
blob: 65c6d5f2cce620e990e44441791d8df35cc82a96 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
#include "stdafx.h"
#include "Minecraft.h"
#include "Minimap.h"
#include "Font.h"
#include "Options.h"
#include "Textures.h"
#include "Tesselator.h"
#include "..\Minecraft.World\net.minecraft.world.level.saveddata.h"
#include "..\Minecraft.World\net.minecraft.world.level.material.h"

#ifdef __ORBIS__
short Minimap::LUT[256];	// 4J added
#else
int Minimap::LUT[256];	// 4J added
#endif
bool Minimap::genLUT = true;		// 4J added

Minimap::Minimap(Font *font, Options *options, Textures *textures, bool optimised)
{
#ifdef __PS3__
	// we're using the RSX now to upload textures to vram, so we need the main ram textures allocated from io space
	this->pixels = intArray((int*)RenderManager.allocIOMem(w*h*sizeof(int)), 16*16);

#elif defined __ORBIS__
	this->pixels = shortArray(w*h);
#else
	this->pixels = intArray(w*h);
#endif
    this->options = options;
    this->font = font;
	BufferedImage *img = new BufferedImage(w, h, BufferedImage::TYPE_INT_ARGB);
#ifdef __ORBIS__
	mapTexture = textures->getTexture(img, C4JRender::TEXTURE_FORMAT_RxGyBzAw5551, false );	// 4J - make sure we aren't mipmapping as we never set the data for mipmaps
#else
    mapTexture = textures->getTexture(img, C4JRender::TEXTURE_FORMAT_RxGyBzAw, false );	// 4J - make sure we aren't mipmapping as we never set the data for mipmaps
#endif
	delete img;
    for (int i = 0; i < w * h; i++)
	{
        pixels[i] = 0x00000000;
	}

	// 4J added - generate the colour mapping that we'll be needing as a LUT to minimise processing we actually need to do during normal rendering
	if( genLUT )
	{
		reloadColours();
	}
	renderCount = 0;	// 4J added
	m_optimised = optimised;
}

void Minimap::reloadColours()
{
	ColourTable *colourTable = Minecraft::GetInstance()->getColourTable();
	// 4J note that this code has been extracted pretty much as it was in Minimap::render, although with some byte order changes
	for( int i = 0; i < (14 * 4); i++ )	// 14 material colours currently, 4 brightnesses of each
	{
		if (i / 4 == 0)
		{
			// 4J - changed byte order to save having to reorder later
#ifdef __ORBIS__
			LUT[i] = 0;
#else
			LUT[i] = (((i + i / w) & 1) * 8 + 16);
#endif
			//pixels[i] = (((i + i / w) & 1) * 8 + 16) << 24;
		}
		else
		{
			int color = colourTable->getColor( MaterialColor::colors[i / 4]->col );
			int brightness = i & 3;

			int br = 220;
			if (brightness == 2) br = 255;
			if (brightness == 0) br = 180;

			int r = ((color >> 16) & 0xff) * br / 255;
			int g = ((color >> 8) & 0xff) * br / 255;
			int b = ((color) & 0xff) * br / 255;

			// 4J - changed byte order to save having to reorder later
#if ( defined _DURANGO || defined _WIN64 || __PSVITA__ )
			LUT[i] =  255 << 24 | b << 16 | g << 8 | r;
#elif defined _XBOX
			LUT[i] =  255 << 24 | r << 16 | g << 8 | b;
#elif defined __ORBIS__
			r >>= 3; g >>= 3; b >>= 3;
			LUT[i] = 1 << 15 | ( r << 10 ) | ( g << 5 ) | b;
#else
			LUT[i] =  r << 24 | g << 16 | b << 8 | 255;
#endif

			//pixels[i] = (255) << 24 | r << 16 | g << 8 | b;
		}

	}
	genLUT = false;
}

// 4J added entityId
void Minimap::render(shared_ptr<Player> player, Textures *textures, shared_ptr<MapItemSavedData> data, int entityId)
{
	// 4J - only update every 8 renders, as an optimisation
	// We don't want to use this for ItemFrame renders of maps, as then we can't have different maps together
	if( !m_optimised || ( renderCount & 7 ) == 0 )
	{
		for (int i = 0; i < w * h; i++)
		{
			int val = data->colors[i];
			// 4J - moved the code that used to run here into a LUT that is generated once in the ctor above
			pixels[i] = LUT[val];
		}
	}
	renderCount++;

	// 4J - changed - have changed texture generation here to put the bytes in the right order already, so we don't have to do any copying round etc. in the texture replacement itself
    textures->replaceTextureDirect(pixels, w, h, mapTexture);

    int x = 0;
    int y = 0;
    Tesselator *t = Tesselator::getInstance();

    float vo = 0;

    glBindTexture(GL_TEXTURE_2D, mapTexture);
    glEnable(GL_BLEND);
	glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    glDisable(GL_ALPHA_TEST);
    t->begin();
	// 4J - moved to -0.02 to stop z fighting ( was -0.01)
	// AP - Vita still has issues so push it a bit more
	float Offset = -0.02f;
#ifdef __PSVITA__
	Offset = -0.03f;
#endif
    t->vertexUV((float)(x + 0 + vo), (float)( y + h - vo), (float)( Offset), (float)( 0), (float)( 1));
    t->vertexUV((float)(x + w - vo), (float)( y + h - vo), (float)( Offset), (float)( 1), (float)( 1));
    t->vertexUV((float)(x + w - vo), (float)( y + 0 + vo), (float)( Offset), (float)( 1), (float)( 0));
    t->vertexUV((float)(x + 0 + vo), (float)( y + 0 + vo), (float)( Offset), (float)( 0), (float)( 0));
    t->end();
    glEnable(GL_ALPHA_TEST);
    glDisable(GL_BLEND);


    textures->bind(textures->loadTexture(TN_MISC_MAPICONS));//L"/misc/mapicons.png"));

#ifdef _LARGE_WORLDS
	vector<MapItemSavedData::MapDecoration *> m_edgeIcons;
#endif

	// 4J-PB - stack the map icons
	float fIconZ=-0.04f;// 4J - moved to -0.04 (was -0.02) to stop z fighting
	for( MapItemSavedData::MapDecoration *dec : data->decorations )
	{
		if(!dec->visible) continue;

		char imgIndex = dec->img;

#ifdef _LARGE_WORLDS
		// For edge icons, use a different texture
		if(imgIndex >= 16)
		{
			m_edgeIcons.push_back(dec);
			continue;
		}
#endif

		// 4J Stu - For item frame renders, the player is NULL. We do not want to show player icons on the frames.
		if(player == NULL && (imgIndex != 12)) continue;
		else if (player != NULL && imgIndex == 12) continue;
		else if( imgIndex == 12 && dec->entityId != entityId) continue;

        glPushMatrix();
        glTranslatef(x + dec->x / 2.0f + w / 2, y + dec->y / 2.0f + h / 2, fIconZ);
        glRotatef(dec->rot * 360 / 16.0f, 0, 0, 1);
        glScalef(4, 4, 3);
        glTranslatef(-1.0f / 8.0f, +1.0f / 8.0f, 0);

        float u0 = (imgIndex % 4 + 0) / 4.0f;
        float v0 = (imgIndex / 4 + 0) / 4.0f;
        float u1 = (imgIndex % 4 + 1) / 4.0f;
        float v1 = (imgIndex / 4 + 1) / 4.0f;

        t->begin();
        t->vertexUV((float)(-1), (float)( +1), (float)( 0), (float)( u0), (float)( v0));
        t->vertexUV((float)(+1), (float)( +1), (float)( 0), (float)( u1), (float)( v0));
        t->vertexUV((float)(+1), (float)( -1), (float)( 0), (float)( u1), (float)( v1));
        t->vertexUV((float)(-1), (float)( -1), (float)( 0), (float)( u0), (float)( v1));
        t->end();
        glPopMatrix();
		fIconZ-=0.01f;
    }

#ifdef _LARGE_WORLDS
	// For players on the edge of the world
	textures->bind(textures->loadTexture(TN_MISC_ADDITIONALMAPICONS));

	fIconZ=-0.04f;// 4J - moved to -0.04 (was -0.02) to stop z fighting
	for( MapItemSavedData::MapDecoration *dec : m_edgeIcons )
	{
		char imgIndex = dec->img;
		imgIndex -= 16;

		// 4J Stu - For item frame renders, the player is NULL. We do not want to show player icons on the frames.
		if(player == NULL && (imgIndex != 12)) continue;
		else if (player != NULL && imgIndex == 12) continue;
		else if( imgIndex == 12 && dec->entityId != entityId) continue;

        glPushMatrix();
        glTranslatef(x + dec->x / 2.0f + w / 2, y + dec->y / 2.0f + h / 2, fIconZ);
        glRotatef(dec->rot * 360 / 16.0f, 0, 0, 1);
        glScalef(4, 4, 3);
        glTranslatef(-1.0f / 8.0f, +1.0f / 8.0f, 0);

        float u0 = (imgIndex % 4 + 0) / 4.0f;
        float v0 = (imgIndex / 4 + 0) / 4.0f;
        float u1 = (imgIndex % 4 + 1) / 4.0f;
        float v1 = (imgIndex / 4 + 1) / 4.0f;

        t->begin();
        t->vertexUV((float)(-1), (float)( +1), (float)( 0), (float)( u0), (float)( v0));
        t->vertexUV((float)(+1), (float)( +1), (float)( 0), (float)( u1), (float)( v0));
        t->vertexUV((float)(+1), (float)( -1), (float)( 0), (float)( u1), (float)( v1));
        t->vertexUV((float)(-1), (float)( -1), (float)( 0), (float)( u0), (float)( v1));
        t->end();
        glPopMatrix();
		fIconZ-=0.01f;
    }
#endif

    glPushMatrix();
//        glRotatef(0, 1, 0, 0);
    glTranslatef(0, 0, -0.06f);
    glScalef(1, 1, 1);
// 4J Stu - Don't render the text name, except in debug
//#if 1
//#ifdef _DEBUG
//    font->draw(data->id, x, y, 0xff000000);
//#else
	// 4J Stu - TU-1 hotfix
	// DCR: Render the players current position here instead
	if(player != NULL)
	{
		wchar_t playerPosText[32];
		ZeroMemory(&playerPosText, sizeof(wchar_t) * 32);
		int posx = floor(player->x);
		int posy = floor(player->y);
		int posz = floor(player->z);
		swprintf(playerPosText, 32, L"X: %d, Y: %d, Z: %d", posx, posy, posz);

		font->draw(playerPosText, x, y, Minecraft::GetInstance()->getColourTable()->getColour(eMinecraftColour_Map_Text));
	}
//#endif
    glPopMatrix();

}