Implement RGSS2 Tilemap class (TilemapVX)
This commit is contained in:
		
							parent
							
								
									3717609142
								
							
						
					
					
						commit
						7790bd6c2c
					
				
					 12 changed files with 1797 additions and 9 deletions
				
			
		
							
								
								
									
										269
									
								
								src/autotilesvx.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										269
									
								
								src/autotilesvx.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,269 @@
 | 
			
		|||
struct StaticRect { float x, y, w, h; };
 | 
			
		||||
 | 
			
		||||
extern const StaticRect autotileVXRectsA[] =
 | 
			
		||||
{
 | 
			
		||||
	{ 32.5, 64.5, 15, 15 },
 | 
			
		||||
	{ 16, 64.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 16, 48.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 0, 15, 15 },
 | 
			
		||||
	{ 16, 64.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 16, 48.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 64.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 0, 15, 15 },
 | 
			
		||||
	{ 32.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 16, 48.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 0, 15, 15 },
 | 
			
		||||
	{ 48.5, 0, 15, 15 },
 | 
			
		||||
	{ 32.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 16, 48.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 64.5, 15, 15 },
 | 
			
		||||
	{ 16, 64.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 16, 15, 15 },
 | 
			
		||||
	{ 32.5, 0, 15, 15 },
 | 
			
		||||
	{ 16, 64.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 16, 15, 15 },
 | 
			
		||||
	{ 32.5, 64.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 0, 15, 15 },
 | 
			
		||||
	{ 32.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 16, 15, 15 },
 | 
			
		||||
	{ 32.5, 0, 15, 15 },
 | 
			
		||||
	{ 48.5, 0, 15, 15 },
 | 
			
		||||
	{ 32.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 16, 15, 15 },
 | 
			
		||||
	{ 32.5, 64.5, 15, 15 },
 | 
			
		||||
	{ 16, 64.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 16, 15, 15 },
 | 
			
		||||
	{ 16, 48.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 0, 15, 15 },
 | 
			
		||||
	{ 16, 64.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 16, 15, 15 },
 | 
			
		||||
	{ 16, 48.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 64.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 0, 15, 15 },
 | 
			
		||||
	{ 32.5, 16, 15, 15 },
 | 
			
		||||
	{ 16, 48.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 0, 15, 15 },
 | 
			
		||||
	{ 48.5, 0, 15, 15 },
 | 
			
		||||
	{ 32.5, 16, 15, 15 },
 | 
			
		||||
	{ 16, 48.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 64.5, 15, 15 },
 | 
			
		||||
	{ 16, 64.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 16, 15, 15 },
 | 
			
		||||
	{ 48.5, 16, 15, 15 },
 | 
			
		||||
	{ 32.5, 0, 15, 15 },
 | 
			
		||||
	{ 16, 64.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 16, 15, 15 },
 | 
			
		||||
	{ 48.5, 16, 15, 15 },
 | 
			
		||||
	{ 32.5, 64.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 0, 15, 15 },
 | 
			
		||||
	{ 32.5, 16, 15, 15 },
 | 
			
		||||
	{ 48.5, 16, 15, 15 },
 | 
			
		||||
	{ 32.5, 0, 15, 15 },
 | 
			
		||||
	{ 48.5, 0, 15, 15 },
 | 
			
		||||
	{ 32.5, 16, 15, 15 },
 | 
			
		||||
	{ 48.5, 16, 15, 15 },
 | 
			
		||||
	{ 0, 64.5, 15, 15 },
 | 
			
		||||
	{ 16, 64.5, 15, 15 },
 | 
			
		||||
	{ 0, 48.5, 15, 15 },
 | 
			
		||||
	{ 16, 48.5, 15, 15 },
 | 
			
		||||
	{ 0, 64.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 0, 15, 15 },
 | 
			
		||||
	{ 0, 48.5, 15, 15 },
 | 
			
		||||
	{ 16, 48.5, 15, 15 },
 | 
			
		||||
	{ 0, 64.5, 15, 15 },
 | 
			
		||||
	{ 16, 64.5, 15, 15 },
 | 
			
		||||
	{ 0, 48.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 16, 15, 15 },
 | 
			
		||||
	{ 0, 64.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 0, 15, 15 },
 | 
			
		||||
	{ 0, 48.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 16, 15, 15 },
 | 
			
		||||
	{ 32.5, 32.5, 15, 15 },
 | 
			
		||||
	{ 16, 32.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 16, 48.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 32.5, 15, 15 },
 | 
			
		||||
	{ 16, 32.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 16, 15, 15 },
 | 
			
		||||
	{ 32.5, 32.5, 15, 15 },
 | 
			
		||||
	{ 16, 32.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 16, 15, 15 },
 | 
			
		||||
	{ 16, 48.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 32.5, 15, 15 },
 | 
			
		||||
	{ 16, 32.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 16, 15, 15 },
 | 
			
		||||
	{ 48.5, 16, 15, 15 },
 | 
			
		||||
	{ 32.5, 64.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 64.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 64.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 64.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 16, 15, 15 },
 | 
			
		||||
	{ 48.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 0, 15, 15 },
 | 
			
		||||
	{ 48.5, 64.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 0, 15, 15 },
 | 
			
		||||
	{ 48.5, 64.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 16, 15, 15 },
 | 
			
		||||
	{ 48.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 64.5, 15, 15 },
 | 
			
		||||
	{ 16, 64.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 80.5, 15, 15 },
 | 
			
		||||
	{ 16, 80.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 0, 15, 15 },
 | 
			
		||||
	{ 16, 64.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 80.5, 15, 15 },
 | 
			
		||||
	{ 16, 80.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 64.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 0, 15, 15 },
 | 
			
		||||
	{ 32.5, 80.5, 15, 15 },
 | 
			
		||||
	{ 16, 80.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 0, 15, 15 },
 | 
			
		||||
	{ 48.5, 0, 15, 15 },
 | 
			
		||||
	{ 32.5, 80.5, 15, 15 },
 | 
			
		||||
	{ 16, 80.5, 15, 15 },
 | 
			
		||||
	{ 0, 64.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 64.5, 15, 15 },
 | 
			
		||||
	{ 0, 48.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 32.5, 15, 15 },
 | 
			
		||||
	{ 16, 32.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 80.5, 15, 15 },
 | 
			
		||||
	{ 16, 80.5, 15, 15 },
 | 
			
		||||
	{ 0, 32.5, 15, 15 },
 | 
			
		||||
	{ 16, 32.5, 15, 15 },
 | 
			
		||||
	{ 0, 48.5, 15, 15 },
 | 
			
		||||
	{ 16, 48.5, 15, 15 },
 | 
			
		||||
	{ 0, 32.5, 15, 15 },
 | 
			
		||||
	{ 16, 32.5, 15, 15 },
 | 
			
		||||
	{ 0, 48.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 16, 15, 15 },
 | 
			
		||||
	{ 32.5, 32.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 32.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 32.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 32.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 16, 15, 15 },
 | 
			
		||||
	{ 48.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 64.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 64.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 80.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 80.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 0, 15, 15 },
 | 
			
		||||
	{ 48.5, 64.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 80.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 80.5, 15, 15 },
 | 
			
		||||
	{ 0, 64.5, 15, 15 },
 | 
			
		||||
	{ 16, 64.5, 15, 15 },
 | 
			
		||||
	{ 0, 80.5, 15, 15 },
 | 
			
		||||
	{ 16, 80.5, 15, 15 },
 | 
			
		||||
	{ 0, 64.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 0, 15, 15 },
 | 
			
		||||
	{ 0, 80.5, 15, 15 },
 | 
			
		||||
	{ 16, 80.5, 15, 15 },
 | 
			
		||||
	{ 0, 32.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 32.5, 15, 15 },
 | 
			
		||||
	{ 0, 48.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 0, 32.5, 15, 15 },
 | 
			
		||||
	{ 16, 32.5, 15, 15 },
 | 
			
		||||
	{ 0, 80.5, 15, 15 },
 | 
			
		||||
	{ 16, 80.5, 15, 15 },
 | 
			
		||||
	{ 0, 64.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 64.5, 15, 15 },
 | 
			
		||||
	{ 0, 80.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 80.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 32.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 32.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 80.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 80.5, 15, 15 },
 | 
			
		||||
	{ 0, 32.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 32.5, 15, 15 },
 | 
			
		||||
	{ 0, 80.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 80.5, 15, 15 },
 | 
			
		||||
	{ 0, 0, 15, 15 },
 | 
			
		||||
	{ 16, 0, 15, 15 },
 | 
			
		||||
	{ 0, 16, 15, 15 },
 | 
			
		||||
	{ 16, 16, 15, 15 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const int autotileVXRectsAN = sizeof(autotileVXRectsA) / sizeof(autotileVXRectsA[0]);
 | 
			
		||||
 | 
			
		||||
extern const StaticRect autotileVXRectsB[] =
 | 
			
		||||
{
 | 
			
		||||
	{ 32.5, 32.5, 15, 15 },
 | 
			
		||||
	{ 16, 32.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 16, 15, 15 },
 | 
			
		||||
	{ 16, 16, 15, 15 },
 | 
			
		||||
	{ 0, 32.5, 15, 15 },
 | 
			
		||||
	{ 16, 32.5, 15, 15 },
 | 
			
		||||
	{ 0, 16, 15, 15 },
 | 
			
		||||
	{ 16, 16, 15, 15 },
 | 
			
		||||
	{ 32.5, 0, 15, 15 },
 | 
			
		||||
	{ 16, 0, 15, 15 },
 | 
			
		||||
	{ 32.5, 16, 15, 15 },
 | 
			
		||||
	{ 16, 16, 15, 15 },
 | 
			
		||||
	{ 0, 0, 15, 15 },
 | 
			
		||||
	{ 16, 0, 15, 15 },
 | 
			
		||||
	{ 0, 16, 15, 15 },
 | 
			
		||||
	{ 16, 16, 15, 15 },
 | 
			
		||||
	{ 32.5, 32.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 32.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 16, 15, 15 },
 | 
			
		||||
	{ 48.5, 16, 15, 15 },
 | 
			
		||||
	{ 0, 32.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 32.5, 15, 15 },
 | 
			
		||||
	{ 0, 16, 15, 15 },
 | 
			
		||||
	{ 48.5, 16, 15, 15 },
 | 
			
		||||
	{ 32.5, 0, 15, 15 },
 | 
			
		||||
	{ 48.5, 0, 15, 15 },
 | 
			
		||||
	{ 32.5, 16, 15, 15 },
 | 
			
		||||
	{ 48.5, 16, 15, 15 },
 | 
			
		||||
	{ 0, 0, 15, 15 },
 | 
			
		||||
	{ 48.5, 0, 15, 15 },
 | 
			
		||||
	{ 0, 16, 15, 15 },
 | 
			
		||||
	{ 48.5, 16, 15, 15 },
 | 
			
		||||
	{ 32.5, 32.5, 15, 15 },
 | 
			
		||||
	{ 16, 32.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 16, 48.5, 15, 15 },
 | 
			
		||||
	{ 0, 32.5, 15, 15 },
 | 
			
		||||
	{ 16, 32.5, 15, 15 },
 | 
			
		||||
	{ 0, 48.5, 15, 15 },
 | 
			
		||||
	{ 16, 48.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 0, 15, 15 },
 | 
			
		||||
	{ 16, 0, 15, 15 },
 | 
			
		||||
	{ 32.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 16, 48.5, 15, 15 },
 | 
			
		||||
	{ 0, 0, 15, 15 },
 | 
			
		||||
	{ 16, 0, 15, 15 },
 | 
			
		||||
	{ 0, 48.5, 15, 15 },
 | 
			
		||||
	{ 16, 48.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 32.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 32.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 0, 32.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 32.5, 15, 15 },
 | 
			
		||||
	{ 0, 48.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 32.5, 0, 15, 15 },
 | 
			
		||||
	{ 48.5, 0, 15, 15 },
 | 
			
		||||
	{ 32.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 48.5, 15, 15 },
 | 
			
		||||
	{ 0, 0, 15, 15 },
 | 
			
		||||
	{ 48.5, 0, 15, 15 },
 | 
			
		||||
	{ 0, 48.5, 15, 15 },
 | 
			
		||||
	{ 48.5, 48.5, 15, 15 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern const int autotileVXRectsBN = sizeof(autotileVXRectsB) / sizeof(autotileVXRectsB[0]);
 | 
			
		||||
| 
						 | 
				
			
			@ -48,6 +48,7 @@
 | 
			
		|||
#include "../simpleMatrix.vert.xxd"
 | 
			
		||||
#include "../blurH.vert.xxd"
 | 
			
		||||
#include "../blurV.vert.xxd"
 | 
			
		||||
#include "../tilemapvx.vert.xxd"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -535,6 +536,21 @@ BlurShader::VPass::VPass()
 | 
			
		|||
	ShaderBase::init();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
TilemapVXShader::TilemapVXShader()
 | 
			
		||||
{
 | 
			
		||||
	INIT_SHADER(tilemapvx, simple, TilemapVXShader);
 | 
			
		||||
 | 
			
		||||
	ShaderBase::init();
 | 
			
		||||
 | 
			
		||||
	GET_U(aniOffset);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TilemapVXShader::setAniOffset(const Vec2 &value)
 | 
			
		||||
{
 | 
			
		||||
	gl.Uniform2f(u_aniOffset, value.x, value.y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										13
									
								
								src/shader.h
									
										
									
									
									
								
							
							
						
						
									
										13
									
								
								src/shader.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -243,6 +243,18 @@ struct BlurShader
 | 
			
		|||
	HPass pass1;
 | 
			
		||||
	VPass pass2;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class TilemapVXShader : public ShaderBase
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	TilemapVXShader();
 | 
			
		||||
 | 
			
		||||
	void setAniOffset(const Vec2 &value);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	GLint u_aniOffset;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Bitmap blit */
 | 
			
		||||
| 
						 | 
				
			
			@ -280,6 +292,7 @@ struct ShaderSet
 | 
			
		|||
#ifdef RGSS2
 | 
			
		||||
	SimpleMatrixShader simpleMatrix;
 | 
			
		||||
	BlurShader blur;
 | 
			
		||||
	TilemapVXShader tilemapVX;
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										635
									
								
								src/tileatlasvx.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										635
									
								
								src/tileatlasvx.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,635 @@
 | 
			
		|||
/*
 | 
			
		||||
** tileatlasvx.cpp
 | 
			
		||||
**
 | 
			
		||||
** This file is part of mkxp.
 | 
			
		||||
**
 | 
			
		||||
** Copyright (C) 2014 Jonas Kulla <Nyocurio@gmail.com>
 | 
			
		||||
**
 | 
			
		||||
** mkxp is free software: you can redistribute it and/or modify
 | 
			
		||||
** it under the terms of the GNU General Public License as published by
 | 
			
		||||
** the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
** (at your option) any later version.
 | 
			
		||||
**
 | 
			
		||||
** mkxp is distributed in the hope that it will be useful,
 | 
			
		||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
** GNU General Public License for more details.
 | 
			
		||||
**
 | 
			
		||||
** You should have received a copy of the GNU General Public License
 | 
			
		||||
** along with mkxp.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "tileatlasvx.h"
 | 
			
		||||
 | 
			
		||||
#include "bitmap.h"
 | 
			
		||||
#include "table.h"
 | 
			
		||||
#include "etc-internal.h"
 | 
			
		||||
#include "gl-util.h"
 | 
			
		||||
#include "gl-meta.h"
 | 
			
		||||
#include "sharedstate.h"
 | 
			
		||||
#include "glstate.h"
 | 
			
		||||
#include "texpool.h"
 | 
			
		||||
#include "util.h"
 | 
			
		||||
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
/* Regular autotile patterns */
 | 
			
		||||
extern const StaticRect autotileVXRectsA[];
 | 
			
		||||
extern const int autotileVXRectsAN;
 | 
			
		||||
 | 
			
		||||
/* Wall autotile patterns */
 | 
			
		||||
extern const StaticRect autotileVXRectsB[];
 | 
			
		||||
extern const int autotileVXRectsBN;
 | 
			
		||||
 | 
			
		||||
static const StaticRect autotileVXRectsC[] =
 | 
			
		||||
{
 | 
			
		||||
	{ 32.5, 0.5, 15, 31 },
 | 
			
		||||
	{ 16.5, 0.5, 15, 31 },
 | 
			
		||||
	{  0.0, 0.5, 15, 31 },
 | 
			
		||||
	{ 16.5, 0.5, 15, 31 },
 | 
			
		||||
	{ 32.5, 0.5, 15, 31 },
 | 
			
		||||
	{ 48.5, 0.5, 15, 31 },
 | 
			
		||||
	{  0.0, 0.5, 15, 31 },
 | 
			
		||||
	{ 48.5, 0.5, 15, 31 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static elementsN(autotileVXRectsC);
 | 
			
		||||
 | 
			
		||||
namespace TileAtlasVX
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
wrap(int value, int range)
 | 
			
		||||
{
 | 
			
		||||
	int res = value % range;
 | 
			
		||||
	return res < 0 ? res + range : res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int16_t
 | 
			
		||||
tableGetWrapped(const Table &t, int x, int y, int z = 0)
 | 
			
		||||
{
 | 
			
		||||
	return t.at(wrap(x, t.xSize()),
 | 
			
		||||
	            wrap(y, t.ySize()),
 | 
			
		||||
	            z);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int16_t
 | 
			
		||||
tableGetSafe(const Table *t, int x)
 | 
			
		||||
{
 | 
			
		||||
	if (!t)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	if (x < 0 || x >= t->xSize())
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	return t->at(x);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* All below constants are in tiles (= 32 pixels) */
 | 
			
		||||
 | 
			
		||||
struct Size
 | 
			
		||||
{
 | 
			
		||||
	int w, h;
 | 
			
		||||
 | 
			
		||||
	Size(int w, int h)
 | 
			
		||||
	    : w(w), h(h)
 | 
			
		||||
	{}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const Size bmSizes[BM_COUNT] =
 | 
			
		||||
{
 | 
			
		||||
	Size(16, 12), /* A1 */
 | 
			
		||||
	Size(16, 12), /* A2 */
 | 
			
		||||
	Size(16,  8), /* A3 */
 | 
			
		||||
	Size(16, 15), /* A4 */
 | 
			
		||||
	Size( 8, 16), /* A5 */
 | 
			
		||||
	Size(16, 16), /* B */
 | 
			
		||||
	Size(16, 16), /* C */
 | 
			
		||||
	Size(16, 16), /* D */
 | 
			
		||||
	Size(16, 16), /* E */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const Size atArea(16, 13);
 | 
			
		||||
 | 
			
		||||
static const Vec2i freeArea(8, 48);
 | 
			
		||||
 | 
			
		||||
static const Vec2i CDEArea(16, 0);
 | 
			
		||||
 | 
			
		||||
struct Blit
 | 
			
		||||
{
 | 
			
		||||
	IntRect src;
 | 
			
		||||
	Vec2i dst;
 | 
			
		||||
 | 
			
		||||
	Blit(int srcX, int srcY, int w, int h, int dstX, int dstY)
 | 
			
		||||
	    : src(srcX, srcY, w, h),
 | 
			
		||||
	      dst(dstX, dstY)
 | 
			
		||||
	{}
 | 
			
		||||
 | 
			
		||||
	Blit(int srcX, int srcY, const Size &size, int dstX, int dstY)
 | 
			
		||||
	    : src(srcX, srcY, size.w, size.h),
 | 
			
		||||
	      dst(dstX, dstY)
 | 
			
		||||
	{}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const Blit blitsA1[] =
 | 
			
		||||
{
 | 
			
		||||
	/* Animated A autotiles */
 | 
			
		||||
	Blit(0, 0, 6, 12, 0, 0),
 | 
			
		||||
	Blit(8, 0, 6, 12, 6, 0),
 | 
			
		||||
	/* Unanimated A autotiles */
 | 
			
		||||
	Blit(6, 0, 2, 6, freeArea.x, freeArea.y),
 | 
			
		||||
	/* C autotiles */
 | 
			
		||||
	Blit(14, 0, 2, 6, 12, 0),
 | 
			
		||||
	Blit(6, 6, 2, 6, 14, 0),
 | 
			
		||||
	Blit(14, 6, 2, 6, 12, 6)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const Blit blitsA2[] =
 | 
			
		||||
{
 | 
			
		||||
	Blit(0, 0, bmSizes[BM_A2], 0, atArea.h)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const Blit blitsA3[] =
 | 
			
		||||
{
 | 
			
		||||
	Blit(0, 0, bmSizes[BM_A3], 0, blitsA2[0].dst.y+blitsA2[0].src.h)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const Blit blitsA4[] =
 | 
			
		||||
{
 | 
			
		||||
	Blit(0, 0, bmSizes[BM_A4], 0, blitsA3[0].dst.y+blitsA3[0].src.h)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const Blit blitsA5[] =
 | 
			
		||||
{
 | 
			
		||||
	Blit(0, 0, bmSizes[BM_A5], 0, blitsA4[0].dst.y+blitsA4[0].src.h)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const Blit blitsB[] =
 | 
			
		||||
{
 | 
			
		||||
	Blit(0, 0, bmSizes[BM_B], atArea.w, 0)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const Blit blitsC[] =
 | 
			
		||||
{
 | 
			
		||||
	Blit(0, 0, bmSizes[BM_C], blitsA2[0].src.w, blitsB[0].dst.y+blitsB[0].src.h)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const Blit blitsD[] =
 | 
			
		||||
{
 | 
			
		||||
	Blit(0, 0, bmSizes[BM_D], blitsC[0].dst.x, blitsC[0].dst.y+blitsC[0].src.h)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const Blit blitsE[] =
 | 
			
		||||
{
 | 
			
		||||
	Blit(0, 0, bmSizes[BM_E], blitsD[0].dst.x, blitsD[0].dst.y+blitsD[0].src.h)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static elementsN(blitsA1);
 | 
			
		||||
static elementsN(blitsA2);
 | 
			
		||||
static elementsN(blitsA3);
 | 
			
		||||
static elementsN(blitsA4);
 | 
			
		||||
static elementsN(blitsA5);
 | 
			
		||||
static elementsN(blitsB);
 | 
			
		||||
static elementsN(blitsC);
 | 
			
		||||
static elementsN(blitsD);
 | 
			
		||||
static elementsN(blitsE);
 | 
			
		||||
 | 
			
		||||
/* 'Waterfall' autotiles atlas origin */
 | 
			
		||||
static const Vec2i AEPartsDst[] =
 | 
			
		||||
{
 | 
			
		||||
	Vec2i(12, 0),
 | 
			
		||||
	Vec2i(12, 3),
 | 
			
		||||
	Vec2i(14, 0),
 | 
			
		||||
	Vec2i(14, 3),
 | 
			
		||||
	Vec2i(12, 6),
 | 
			
		||||
	Vec2i(12, 9)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const Vec2i shadowArea(freeArea.x+2, freeArea.y);
 | 
			
		||||
 | 
			
		||||
static SDL_Surface*
 | 
			
		||||
createShadowSet()
 | 
			
		||||
{
 | 
			
		||||
	int bpp;
 | 
			
		||||
	Uint32 rm, gm, bm, am;
 | 
			
		||||
 | 
			
		||||
	SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_ABGR8888, &bpp, &rm, &gm, &bm, &am);
 | 
			
		||||
	SDL_Surface *surf = SDL_CreateRGBSurface(0, 1*32, 16*32, bpp, rm, gm, bm, am);
 | 
			
		||||
 | 
			
		||||
	std::vector<SDL_Rect> rects;
 | 
			
		||||
	SDL_Rect rect = { 0, 0, 16, 16 };
 | 
			
		||||
 | 
			
		||||
	for (int val = 0; val < 16; ++val)
 | 
			
		||||
	{
 | 
			
		||||
		int origY = val*32;
 | 
			
		||||
 | 
			
		||||
		/* Top left */
 | 
			
		||||
		if (val & (1 << 0))
 | 
			
		||||
		{
 | 
			
		||||
			rect.x = 0;
 | 
			
		||||
			rect.y = origY;
 | 
			
		||||
			rects.push_back(rect);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Top Right */
 | 
			
		||||
		if (val & (1 << 1))
 | 
			
		||||
		{
 | 
			
		||||
			rect.x = 16;
 | 
			
		||||
			rect.y = origY;
 | 
			
		||||
			rects.push_back(rect);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Bottom left */
 | 
			
		||||
		if (val & (1 << 2))
 | 
			
		||||
		{
 | 
			
		||||
			rect.x = 0;
 | 
			
		||||
			rect.y = origY+16;
 | 
			
		||||
			rects.push_back(rect);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Bottom right */
 | 
			
		||||
		if (val & (1 << 3))
 | 
			
		||||
		{
 | 
			
		||||
			rect.x = 16;
 | 
			
		||||
			rect.y = origY+16;
 | 
			
		||||
			rects.push_back(rect);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Fill rects with half opacity black */
 | 
			
		||||
	uint32_t color = (0x80808080 & am);
 | 
			
		||||
	SDL_FillRects(surf, &rects[0], rects.size(), color);
 | 
			
		||||
 | 
			
		||||
	return surf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void build(TEXFBO &tf, Bitmap *bitmaps[BM_COUNT])
 | 
			
		||||
{
 | 
			
		||||
	assert(tf.width == ATLASVX_W && tf.height == ATLASVX_H);
 | 
			
		||||
 | 
			
		||||
	GLMeta::blitBegin(tf);
 | 
			
		||||
 | 
			
		||||
	glState.clearColor.pushSet(Vec4());
 | 
			
		||||
	FBO::clear();
 | 
			
		||||
	glState.clearColor.pop();
 | 
			
		||||
 | 
			
		||||
	SDL_Surface *shadow = createShadowSet();
 | 
			
		||||
	TEX::bind(tf.tex);
 | 
			
		||||
	TEX::uploadSubImage(shadowArea.x*32, shadowArea.y*32,
 | 
			
		||||
	                    shadow->w, shadow->h, shadow->pixels, GL_RGBA);
 | 
			
		||||
	SDL_FreeSurface(shadow);
 | 
			
		||||
 | 
			
		||||
	Bitmap *bm;
 | 
			
		||||
#define EXEC_BLITS(part) \
 | 
			
		||||
	if ((bm = bitmaps[BM_##part])) \
 | 
			
		||||
	{ \
 | 
			
		||||
		GLMeta::blitSource(bm->getGLTypes()); \
 | 
			
		||||
		for (size_t i = 0; i < blits##part##N; ++i) \
 | 
			
		||||
		{\
 | 
			
		||||
			IntRect src = blits##part[i].src; \
 | 
			
		||||
			src = IntRect(src.x*32, src.y*32, src.w*32, src.h*32); \
 | 
			
		||||
			Vec2i dst = blits##part[i].dst; \
 | 
			
		||||
			dst = Vec2i(dst.x*32, dst.y*32); \
 | 
			
		||||
			GLMeta::blitRectangle(src, dst); \
 | 
			
		||||
		} \
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	EXEC_BLITS(A1);
 | 
			
		||||
	EXEC_BLITS(A2);
 | 
			
		||||
	EXEC_BLITS(A3);
 | 
			
		||||
	EXEC_BLITS(A4);
 | 
			
		||||
	EXEC_BLITS(A5);
 | 
			
		||||
	EXEC_BLITS(B);
 | 
			
		||||
	EXEC_BLITS(C);
 | 
			
		||||
	EXEC_BLITS(D);
 | 
			
		||||
	EXEC_BLITS(E);
 | 
			
		||||
 | 
			
		||||
#undef EXEC_BLITS
 | 
			
		||||
 | 
			
		||||
	GLMeta::blitEnd();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define OVER_PLAYER_FLAG (1 << 4)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
atSelectSubPos(FloatRect &pos, int i)
 | 
			
		||||
{
 | 
			
		||||
	switch (i)
 | 
			
		||||
	{
 | 
			
		||||
	case 0:
 | 
			
		||||
		return;
 | 
			
		||||
	case 1:
 | 
			
		||||
		pos.x += 16;
 | 
			
		||||
		return;
 | 
			
		||||
	case 2:
 | 
			
		||||
		pos.y += 16;
 | 
			
		||||
		return;
 | 
			
		||||
	case 3:
 | 
			
		||||
		pos.x += 16;
 | 
			
		||||
		pos.y += 16;
 | 
			
		||||
		return;
 | 
			
		||||
	default:
 | 
			
		||||
		assert(!"Unreachable");
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Reference: http://www.tktkgame.com/tkool/memo/vx/tile_id.html */
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
readAutotile(Reader &reader, int patternID,
 | 
			
		||||
             const Vec2i &orig, int x, int y,
 | 
			
		||||
             const StaticRect rectSource[], int rectSourceN)
 | 
			
		||||
{
 | 
			
		||||
	FloatRect tex[4], pos[4];
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < 4; ++i)
 | 
			
		||||
	{
 | 
			
		||||
		assert((patternID*4 + i) < rectSourceN);
 | 
			
		||||
 | 
			
		||||
		tex[i] = FloatRect(rectSource[patternID*4 + i]);
 | 
			
		||||
		tex[i].x += orig.x*32;
 | 
			
		||||
		tex[i].y += orig.y*32;
 | 
			
		||||
 | 
			
		||||
		pos[i] = FloatRect(x*32, y*32, 16, 16);
 | 
			
		||||
		atSelectSubPos(pos[i], i);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	reader.onQuads4(tex, pos);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
readAutotileA(Reader &reader, int patternID,
 | 
			
		||||
              const Vec2i &orig, int x, int y)
 | 
			
		||||
{
 | 
			
		||||
	readAutotile(reader, patternID, orig, x, y,
 | 
			
		||||
	             autotileVXRectsA, autotileVXRectsAN);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
readAutotileB(Reader &reader, int patternID,
 | 
			
		||||
              const Vec2i &orig, int x, int y)
 | 
			
		||||
{
 | 
			
		||||
	if (patternID >= 0x10)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	readAutotile(reader, patternID, orig, x, y,
 | 
			
		||||
	             autotileVXRectsB, autotileVXRectsBN);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
readAutotileC(Reader &reader, int patternID,
 | 
			
		||||
              const Vec2i &orig, int x, int y)
 | 
			
		||||
{
 | 
			
		||||
	if (patternID > 0x3)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	FloatRect tex[2], pos[2];
 | 
			
		||||
 | 
			
		||||
	for (size_t i = 0; i < 2; ++i)
 | 
			
		||||
	{
 | 
			
		||||
		tex[i] = autotileVXRectsC[patternID*2+i];
 | 
			
		||||
		tex[i].x += orig.x*32;
 | 
			
		||||
		tex[i].y += orig.y*32;
 | 
			
		||||
 | 
			
		||||
		pos[i] = FloatRect(x*32, y*32, 16, 32);
 | 
			
		||||
		pos[i].x += i*16;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	reader.onQuads2(tex, pos);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
onTileA1(Reader &reader, int16_t tileID,
 | 
			
		||||
         const int x, const int y)
 | 
			
		||||
{
 | 
			
		||||
	tileID -= 0x0800;
 | 
			
		||||
 | 
			
		||||
	int patternID  = tileID % 0x30;
 | 
			
		||||
	int autotileID = tileID / 0x30;
 | 
			
		||||
 | 
			
		||||
	const Vec2i autotileC(-1, -1);
 | 
			
		||||
	const Vec2i atOrig[] =
 | 
			
		||||
	{
 | 
			
		||||
		Vec2i(0, 0),
 | 
			
		||||
		Vec2i(0, 3),
 | 
			
		||||
		Vec2i(freeArea),
 | 
			
		||||
		Vec2i(freeArea.x, freeArea.y+3),
 | 
			
		||||
		Vec2i(6, 0),
 | 
			
		||||
		autotileC,
 | 
			
		||||
		Vec2i(6, 3),
 | 
			
		||||
		autotileC,
 | 
			
		||||
 | 
			
		||||
		Vec2i(0, 6),
 | 
			
		||||
		autotileC,
 | 
			
		||||
		Vec2i(0, 9),
 | 
			
		||||
		autotileC,
 | 
			
		||||
		Vec2i(6, 6),
 | 
			
		||||
		autotileC,
 | 
			
		||||
		Vec2i(6, 9),
 | 
			
		||||
		autotileC
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	const Vec2i orig = atOrig[autotileID];
 | 
			
		||||
 | 
			
		||||
	if (orig.x == -1)
 | 
			
		||||
	{
 | 
			
		||||
		int cID = (autotileID - 5) / 2;
 | 
			
		||||
		const Vec2i orig = AEPartsDst[cID];
 | 
			
		||||
 | 
			
		||||
		readAutotileC(reader, patternID, orig, x, y);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	readAutotileA(reader, patternID, orig, x, y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
onTileA2(Reader &reader, int16_t tileID,
 | 
			
		||||
         int x, int y)
 | 
			
		||||
{
 | 
			
		||||
	Vec2i orig = blitsA2[0].dst;
 | 
			
		||||
	tileID -= 0x0B00;
 | 
			
		||||
 | 
			
		||||
	int patternID  = tileID % 0x30;
 | 
			
		||||
	int autotileID = tileID / 0x30;
 | 
			
		||||
 | 
			
		||||
	orig.x += (autotileID % 8) * 2;
 | 
			
		||||
	orig.y += (autotileID / 8) * 3;
 | 
			
		||||
 | 
			
		||||
	readAutotileA(reader, patternID, orig, x, y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
onTileA3(Reader &reader, int16_t tileID,
 | 
			
		||||
         int x, int y)
 | 
			
		||||
{
 | 
			
		||||
	Vec2i orig = blitsA3[0].dst;
 | 
			
		||||
	tileID -= 0x1100;
 | 
			
		||||
 | 
			
		||||
	int patternID  = tileID % 0x30;
 | 
			
		||||
	int autotileID = tileID / 0x30;
 | 
			
		||||
 | 
			
		||||
	orig.x += (autotileID % 8) * 2;
 | 
			
		||||
	orig.y += (autotileID / 8) * 2;
 | 
			
		||||
 | 
			
		||||
	readAutotileB(reader, patternID, orig, x, y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
onTileA4(Reader &reader, int16_t tileID,
 | 
			
		||||
         int x, int y)
 | 
			
		||||
{
 | 
			
		||||
	Vec2i orig = blitsA4[0].dst;
 | 
			
		||||
	tileID -= 0x1700;
 | 
			
		||||
 | 
			
		||||
	const int offY[] = { 0, 3, 5, 8, 10, 13 };
 | 
			
		||||
 | 
			
		||||
	int patternID  = tileID % 0x30;
 | 
			
		||||
	int autotileID = tileID / 0x30;
 | 
			
		||||
 | 
			
		||||
	int offYI = autotileID / 8;
 | 
			
		||||
	orig.x += (autotileID % 8) * 2;
 | 
			
		||||
	orig.y += offY[offYI];
 | 
			
		||||
 | 
			
		||||
	if ((offYI % 2) == 0)
 | 
			
		||||
		readAutotileA(reader, patternID, orig, x, y);
 | 
			
		||||
	else
 | 
			
		||||
		readAutotileB(reader, patternID, orig, x, y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
onTileA5(Reader &reader, int16_t tileID,
 | 
			
		||||
         int x, int y, bool overPlayer)
 | 
			
		||||
{
 | 
			
		||||
	const Vec2i orig = blitsA5[0].dst;
 | 
			
		||||
	tileID -= 0x0600;
 | 
			
		||||
 | 
			
		||||
	int ox = tileID % 0x8;
 | 
			
		||||
	int oy = tileID / 0x8;
 | 
			
		||||
 | 
			
		||||
	FloatRect tex((orig.x+ox)*32+0.5, (orig.y+oy)*32+0.5, 31, 31);
 | 
			
		||||
	FloatRect pos(x*32, y*32, 32, 32);
 | 
			
		||||
 | 
			
		||||
	reader.onQuads1(tex, pos, overPlayer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
onTileBCDE(Reader &reader, int16_t tileID,
 | 
			
		||||
           int x, int y, bool overPlayer)
 | 
			
		||||
{
 | 
			
		||||
	int ox = tileID % 0x8;
 | 
			
		||||
	int oy = (tileID / 0x8) % 0x10;
 | 
			
		||||
	int ob = tileID / (0x8*0x10);
 | 
			
		||||
 | 
			
		||||
	ox += (ob % 2) * 0x8;
 | 
			
		||||
	oy += (ob / 2) * 0x10;
 | 
			
		||||
 | 
			
		||||
	FloatRect tex((CDEArea.x+ox)*32+0.5, (CDEArea.y+oy)*32+0.5, 31, 31);
 | 
			
		||||
	FloatRect pos(x*32, y*32, 32, 32);
 | 
			
		||||
 | 
			
		||||
	reader.onQuads1(tex, pos, overPlayer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
onTile(Reader &reader, int16_t tileID,
 | 
			
		||||
       int x, int y, bool overPlayer)
 | 
			
		||||
{
 | 
			
		||||
	/* B ~ E */
 | 
			
		||||
	if (tileID < 0x0400)
 | 
			
		||||
	{
 | 
			
		||||
		onTileBCDE(reader, tileID, x, y, overPlayer);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* A5 */
 | 
			
		||||
	if (tileID >= 0x0600 && tileID < 0x0680)
 | 
			
		||||
	{
 | 
			
		||||
		onTileA5(reader, tileID, x, y, overPlayer);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (tileID >= 0x0800 && tileID < 0x0B00)
 | 
			
		||||
	{
 | 
			
		||||
		onTileA1(reader, tileID, x, y);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* A2 */
 | 
			
		||||
	if (tileID >= 0x0B00 && tileID < 0x1100)
 | 
			
		||||
	{
 | 
			
		||||
		onTileA2(reader, tileID, x, y);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* A3 */
 | 
			
		||||
	if (tileID < 0x1700)
 | 
			
		||||
	{
 | 
			
		||||
		onTileA3(reader, tileID, x, y);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* A4 */
 | 
			
		||||
	if (tileID < 0x2000)
 | 
			
		||||
	{
 | 
			
		||||
		onTileA4(reader, tileID, x, y);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
readLayer(Reader &reader, const Table &data,
 | 
			
		||||
          const Table *flags, int ox, int oy, int w, int h, int z)
 | 
			
		||||
{
 | 
			
		||||
	for (int y = 0; y < h; ++y)
 | 
			
		||||
		for (int x = 0; x < w; ++x)
 | 
			
		||||
		{
 | 
			
		||||
			int16_t tileID = tableGetWrapped(data, x+ox, y+oy, z);
 | 
			
		||||
			bool overPlayer = tableGetSafe(flags, tileID) & OVER_PLAYER_FLAG;
 | 
			
		||||
 | 
			
		||||
			if (tileID <= 0)
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			onTile(reader, tileID, x, y, overPlayer);
 | 
			
		||||
		}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
onShadowTile(Reader &reader, int8_t value,
 | 
			
		||||
             int x, int y)
 | 
			
		||||
{
 | 
			
		||||
	if (value == 0)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	int oy = value;
 | 
			
		||||
 | 
			
		||||
	FloatRect tex((shadowArea.x)*32+0.5, (shadowArea.y+oy)*32+0.5, 31, 31);
 | 
			
		||||
	FloatRect pos(x*32, y*32, 32, 32);
 | 
			
		||||
 | 
			
		||||
	reader.onQuads1(tex, pos, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
readShadowLayer(Reader &reader, const Table &data,
 | 
			
		||||
                int ox, int oy, int w, int h)
 | 
			
		||||
{
 | 
			
		||||
	for (int y = 0; y < h; ++y)
 | 
			
		||||
		for (int x = 0; x < w; ++x)
 | 
			
		||||
		{
 | 
			
		||||
			int16_t value = tableGetWrapped(data, x+ox, y+oy, 3);
 | 
			
		||||
			onShadowTile(reader, value & 0xF, x, y);
 | 
			
		||||
		}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void readTiles(Reader &reader, const Table &data,
 | 
			
		||||
               const Table *flags, int ox, int oy, int w, int h)
 | 
			
		||||
{
 | 
			
		||||
	for (int i = 0; i < 2; ++i)
 | 
			
		||||
		readLayer(reader, data, flags, ox, oy, w, h, i);
 | 
			
		||||
 | 
			
		||||
	readShadowLayer(reader, data, ox, oy, w, h);
 | 
			
		||||
 | 
			
		||||
	readLayer(reader, data, flags, ox, oy, w, h, 2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										67
									
								
								src/tileatlasvx.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								src/tileatlasvx.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,67 @@
 | 
			
		|||
/*
 | 
			
		||||
** tileatlasvx.h
 | 
			
		||||
**
 | 
			
		||||
** This file is part of mkxp.
 | 
			
		||||
**
 | 
			
		||||
** Copyright (C) 2014 Jonas Kulla <Nyocurio@gmail.com>
 | 
			
		||||
**
 | 
			
		||||
** mkxp is free software: you can redistribute it and/or modify
 | 
			
		||||
** it under the terms of the GNU General Public License as published by
 | 
			
		||||
** the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
** (at your option) any later version.
 | 
			
		||||
**
 | 
			
		||||
** mkxp is distributed in the hope that it will be useful,
 | 
			
		||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
** GNU General Public License for more details.
 | 
			
		||||
**
 | 
			
		||||
** You should have received a copy of the GNU General Public License
 | 
			
		||||
** along with mkxp.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef TILEATLASVX_H
 | 
			
		||||
#define TILEATLASVX_H
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
struct FloatRect;
 | 
			
		||||
struct TEXFBO;
 | 
			
		||||
class Bitmap;
 | 
			
		||||
class Table;
 | 
			
		||||
 | 
			
		||||
#define ATLASVX_W 1024
 | 
			
		||||
#define ATLASVX_H 2048
 | 
			
		||||
 | 
			
		||||
/* Bitmap indices */
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
	BM_A1 = 0,
 | 
			
		||||
	BM_A2 = 1,
 | 
			
		||||
	BM_A3 = 2,
 | 
			
		||||
	BM_A4 = 3,
 | 
			
		||||
	BM_A5 = 4,
 | 
			
		||||
	BM_B  = 5,
 | 
			
		||||
	BM_C  = 6,
 | 
			
		||||
	BM_D  = 7,
 | 
			
		||||
	BM_E  = 8,
 | 
			
		||||
 | 
			
		||||
	BM_COUNT
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
namespace TileAtlasVX
 | 
			
		||||
{
 | 
			
		||||
struct Reader
 | 
			
		||||
{
 | 
			
		||||
	virtual void onQuads1(const FloatRect &t, const FloatRect &p,
 | 
			
		||||
	                      bool overPlayer) = 0;
 | 
			
		||||
	virtual void onQuads2(const FloatRect t[2], const FloatRect p[2]) = 0;
 | 
			
		||||
	virtual void onQuads4(const FloatRect t[4], const FloatRect p[4]) = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void build(TEXFBO &tf, Bitmap *bitmaps[BM_COUNT]);
 | 
			
		||||
 | 
			
		||||
void readTiles(Reader &reader, const Table &data,
 | 
			
		||||
               const Table *flags, int ox, int oy, int w, int h);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // TILEATLASVX_H
 | 
			
		||||
							
								
								
									
										515
									
								
								src/tilemapvx.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										515
									
								
								src/tilemapvx.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,515 @@
 | 
			
		|||
/*
 | 
			
		||||
** tilemapvx.cpp
 | 
			
		||||
**
 | 
			
		||||
** This file is part of mkxp.
 | 
			
		||||
**
 | 
			
		||||
** Copyright (C) 2014 Jonas Kulla <Nyocurio@gmail.com>
 | 
			
		||||
**
 | 
			
		||||
** mkxp is free software: you can redistribute it and/or modify
 | 
			
		||||
** it under the terms of the GNU General Public License as published by
 | 
			
		||||
** the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
** (at your option) any later version.
 | 
			
		||||
**
 | 
			
		||||
** mkxp is distributed in the hope that it will be useful,
 | 
			
		||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
** GNU General Public License for more details.
 | 
			
		||||
**
 | 
			
		||||
** You should have received a copy of the GNU General Public License
 | 
			
		||||
** along with mkxp.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "tilemapvx.h"
 | 
			
		||||
 | 
			
		||||
#include "tileatlasvx.h"
 | 
			
		||||
#include "etc-internal.h"
 | 
			
		||||
#include "bitmap.h"
 | 
			
		||||
#include "table.h"
 | 
			
		||||
#include "viewport.h"
 | 
			
		||||
#include "gl-util.h"
 | 
			
		||||
#include "sharedstate.h"
 | 
			
		||||
#include "glstate.h"
 | 
			
		||||
#include "vertex.h"
 | 
			
		||||
#include "quad.h"
 | 
			
		||||
#include "quadarray.h"
 | 
			
		||||
#include "shader.h"
 | 
			
		||||
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <sigc++/connection.h>
 | 
			
		||||
#include <sigc++/bind.h>
 | 
			
		||||
 | 
			
		||||
/* Map viewport size */
 | 
			
		||||
// FIXME: This will be wrong if resolution is changed
 | 
			
		||||
static const int viewpW = 18;
 | 
			
		||||
static const int viewpH = 14;
 | 
			
		||||
 | 
			
		||||
/* How many tiles are max visible on screen at once */
 | 
			
		||||
static const Vec2i screenTiles(18, 14);
 | 
			
		||||
 | 
			
		||||
// FIXME: Implement flash
 | 
			
		||||
 | 
			
		||||
struct TilemapVXPrivate : public ViewportElement, TileAtlasVX::Reader
 | 
			
		||||
{
 | 
			
		||||
	TilemapVX::BitmapArray bitmapsProxy;
 | 
			
		||||
	Bitmap *bitmaps[BM_COUNT];
 | 
			
		||||
 | 
			
		||||
	Table *mapData;
 | 
			
		||||
	Table *flashData;
 | 
			
		||||
	Table *flags;
 | 
			
		||||
	Vec2i offset;
 | 
			
		||||
 | 
			
		||||
	Vec2i dispPos;
 | 
			
		||||
	/* Map viewport position */
 | 
			
		||||
	Vec2i viewpPos;
 | 
			
		||||
	Vec2i sceneOffset;
 | 
			
		||||
	Scene::Geometry sceneGeo;
 | 
			
		||||
 | 
			
		||||
	std::vector<SVertex> groundVert;
 | 
			
		||||
	std::vector<SVertex> aboveVert;
 | 
			
		||||
 | 
			
		||||
	TEXFBO atlas;
 | 
			
		||||
	VBO::ID vbo;
 | 
			
		||||
	GLMeta::VAO vao;
 | 
			
		||||
 | 
			
		||||
	size_t allocQuads;
 | 
			
		||||
 | 
			
		||||
	size_t groundQuads;
 | 
			
		||||
	size_t aboveQuads;
 | 
			
		||||
 | 
			
		||||
	uint16_t frameIdx;
 | 
			
		||||
	uint8_t aniIdxA;
 | 
			
		||||
	uint8_t aniIdxC;
 | 
			
		||||
	Vec2 aniOffset;
 | 
			
		||||
 | 
			
		||||
	bool atlasDirty;
 | 
			
		||||
	bool buffersDirty;
 | 
			
		||||
	bool mapViewportDirty;
 | 
			
		||||
 | 
			
		||||
	sigc::connection mapDataCon;
 | 
			
		||||
	sigc::connection flagsCon;
 | 
			
		||||
 | 
			
		||||
	sigc::connection prepareCon;
 | 
			
		||||
	sigc::connection bmChangedCons[BM_COUNT];
 | 
			
		||||
	sigc::connection bmDisposedCons[BM_COUNT];
 | 
			
		||||
 | 
			
		||||
	struct AboveLayer : public ViewportElement
 | 
			
		||||
	{
 | 
			
		||||
		TilemapVXPrivate *p;
 | 
			
		||||
 | 
			
		||||
		AboveLayer(TilemapVXPrivate *p, Viewport *viewport)
 | 
			
		||||
		    : ViewportElement(viewport, 200),
 | 
			
		||||
		      p(p)
 | 
			
		||||
		{}
 | 
			
		||||
 | 
			
		||||
		void draw()
 | 
			
		||||
		{
 | 
			
		||||
			p->drawAbove();
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	AboveLayer above;
 | 
			
		||||
 | 
			
		||||
	TilemapVXPrivate(Viewport *viewport)
 | 
			
		||||
	    : ViewportElement(viewport),
 | 
			
		||||
	      mapData(0),
 | 
			
		||||
	      flashData(0),
 | 
			
		||||
	      flags(0),
 | 
			
		||||
	      allocQuads(0),
 | 
			
		||||
	      groundQuads(0),
 | 
			
		||||
	      aboveQuads(0),
 | 
			
		||||
	      frameIdx(0),
 | 
			
		||||
	      aniIdxA(0),
 | 
			
		||||
	      aniIdxC(0),
 | 
			
		||||
	      atlasDirty(true),
 | 
			
		||||
	      buffersDirty(false),
 | 
			
		||||
	      mapViewportDirty(false),
 | 
			
		||||
	      above(this, viewport)
 | 
			
		||||
	{
 | 
			
		||||
		memset(bitmaps, 0, sizeof(bitmaps));
 | 
			
		||||
 | 
			
		||||
		shState->requestAtlasTex(ATLASVX_W, ATLASVX_H, atlas);
 | 
			
		||||
 | 
			
		||||
		vbo = VBO::gen();
 | 
			
		||||
 | 
			
		||||
		GLMeta::vaoFillInVertexData<SVertex>(vao);
 | 
			
		||||
		vao.vbo = vbo;
 | 
			
		||||
		vao.ibo = shState->globalIBO().ibo;
 | 
			
		||||
		GLMeta::vaoInit(vao);
 | 
			
		||||
 | 
			
		||||
		prepareCon = shState->prepareDraw.connect
 | 
			
		||||
			(sigc::mem_fun(this, &TilemapVXPrivate::prepare));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	virtual ~TilemapVXPrivate()
 | 
			
		||||
	{
 | 
			
		||||
		GLMeta::vaoFini(vao);
 | 
			
		||||
		VBO::del(vbo);
 | 
			
		||||
 | 
			
		||||
		shState->releaseAtlasTex(atlas);
 | 
			
		||||
 | 
			
		||||
		prepareCon.disconnect();
 | 
			
		||||
 | 
			
		||||
		mapDataCon.disconnect();
 | 
			
		||||
		flagsCon.disconnect();
 | 
			
		||||
 | 
			
		||||
		for (size_t i = 0; i < BM_COUNT; ++i)
 | 
			
		||||
		{
 | 
			
		||||
			bmChangedCons[i].disconnect();
 | 
			
		||||
			bmDisposedCons[i].disconnect();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void invalidateAtlas()
 | 
			
		||||
	{
 | 
			
		||||
		atlasDirty = true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void onBitmapDisposed(int i)
 | 
			
		||||
	{
 | 
			
		||||
		bitmaps[i] = 0;
 | 
			
		||||
		bmChangedCons[i].disconnect();
 | 
			
		||||
		bmDisposedCons[i].disconnect();
 | 
			
		||||
 | 
			
		||||
		atlasDirty = true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void invalidateBuffers()
 | 
			
		||||
	{
 | 
			
		||||
		buffersDirty = true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void rebuildAtlas()
 | 
			
		||||
	{
 | 
			
		||||
		TileAtlasVX::build(atlas, bitmaps);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void updatePosition()
 | 
			
		||||
	{
 | 
			
		||||
		dispPos.x = -(offset.x - viewpPos.x * 32) + sceneOffset.x;
 | 
			
		||||
		dispPos.y = -(offset.y - viewpPos.y * 32) + sceneOffset.y;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void onGeometryChange(const Scene::Geometry &geo)
 | 
			
		||||
	{
 | 
			
		||||
		sceneOffset.x = geo.rect.x - geo.xOrigin;
 | 
			
		||||
		sceneOffset.y = geo.rect.y - geo.yOrigin;
 | 
			
		||||
		sceneGeo = geo;
 | 
			
		||||
 | 
			
		||||
		updatePosition();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void updateMapViewport()
 | 
			
		||||
	{
 | 
			
		||||
		int tileOX, tileOY;
 | 
			
		||||
 | 
			
		||||
		if (offset.x >= 0)
 | 
			
		||||
			tileOX = offset.x / 32;
 | 
			
		||||
		else
 | 
			
		||||
			tileOX = -(-(offset.x-31) / 32);
 | 
			
		||||
 | 
			
		||||
		if (offset.y >= 0)
 | 
			
		||||
			tileOY = offset.y / 32;
 | 
			
		||||
		else
 | 
			
		||||
			tileOY = -(-(offset.y-31) / 32);
 | 
			
		||||
 | 
			
		||||
		bool dirty = false;
 | 
			
		||||
 | 
			
		||||
		if (tileOX < viewpPos.x || tileOX + screenTiles.x > viewpPos.x + viewpW)
 | 
			
		||||
		{
 | 
			
		||||
			viewpPos.x = tileOX;
 | 
			
		||||
			dirty = true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (tileOY < viewpPos.y || tileOY + screenTiles.y > viewpPos.y + viewpH)
 | 
			
		||||
		{
 | 
			
		||||
			viewpPos.y = tileOY;
 | 
			
		||||
			dirty = true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (dirty)
 | 
			
		||||
		{
 | 
			
		||||
			buffersDirty = true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		updatePosition();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static size_t quadBytes(size_t quads)
 | 
			
		||||
	{
 | 
			
		||||
		return quads * 4 * sizeof(SVertex);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void rebuildBuffers()
 | 
			
		||||
	{
 | 
			
		||||
		if (!mapData)
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		groundVert.clear();
 | 
			
		||||
		aboveVert.clear();
 | 
			
		||||
 | 
			
		||||
		TileAtlasVX::readTiles(*this, *mapData, flags,
 | 
			
		||||
		                       viewpPos.x, viewpPos.y, viewpW, viewpH);
 | 
			
		||||
 | 
			
		||||
		groundQuads = groundVert.size() / 4;
 | 
			
		||||
		aboveQuads = aboveVert.size() / 4;
 | 
			
		||||
		size_t totalQuads = groundQuads + aboveQuads;
 | 
			
		||||
 | 
			
		||||
		VBO::bind(vbo);
 | 
			
		||||
 | 
			
		||||
		if (totalQuads > allocQuads)
 | 
			
		||||
		{
 | 
			
		||||
			VBO::allocEmpty(quadBytes(totalQuads), GL_DYNAMIC_DRAW);
 | 
			
		||||
			allocQuads = totalQuads;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		VBO::uploadSubData(0, quadBytes(groundQuads), &groundVert[0]);
 | 
			
		||||
		VBO::uploadSubData(quadBytes(groundQuads), quadBytes(aboveQuads), &aboveVert[0]);
 | 
			
		||||
 | 
			
		||||
		VBO::unbind();
 | 
			
		||||
 | 
			
		||||
		shState->ensureQuadIBO(totalQuads);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void prepare()
 | 
			
		||||
	{
 | 
			
		||||
		if (!mapData)
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		if (atlasDirty)
 | 
			
		||||
		{
 | 
			
		||||
			rebuildAtlas();
 | 
			
		||||
			atlasDirty = false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (mapViewportDirty)
 | 
			
		||||
		{
 | 
			
		||||
			updateMapViewport();
 | 
			
		||||
			mapViewportDirty = false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (buffersDirty)
 | 
			
		||||
		{
 | 
			
		||||
			rebuildBuffers();
 | 
			
		||||
			buffersDirty = false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	SVertex *allocVert(std::vector<SVertex> &vec, size_t count)
 | 
			
		||||
	{
 | 
			
		||||
		size_t size = vec.size();
 | 
			
		||||
		vec.resize(size + count);
 | 
			
		||||
 | 
			
		||||
		return &vec[size];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* SceneElement */
 | 
			
		||||
	void draw()
 | 
			
		||||
	{
 | 
			
		||||
		TilemapVXShader &shader = shState->shaders().tilemapVX;
 | 
			
		||||
		shader.bind();
 | 
			
		||||
		shader.setTexSize(Vec2i(atlas.width, atlas.height));
 | 
			
		||||
		shader.applyViewportProj();
 | 
			
		||||
		shader.setTranslation(dispPos);
 | 
			
		||||
		shader.setAniOffset(aniOffset);
 | 
			
		||||
 | 
			
		||||
		TEX::bind(atlas.tex);
 | 
			
		||||
		GLMeta::vaoBind(vao);
 | 
			
		||||
 | 
			
		||||
		gl.DrawElements(GL_TRIANGLES, groundQuads*6, _GL_INDEX_TYPE, 0);
 | 
			
		||||
 | 
			
		||||
		GLMeta::vaoUnbind(vao);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void drawAbove()
 | 
			
		||||
	{
 | 
			
		||||
		if (aboveQuads == 0)
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		SimpleShader &shader = shState->shaders().simple;
 | 
			
		||||
		shader.bind();
 | 
			
		||||
		shader.setTexSize(Vec2i(atlas.width, atlas.height));
 | 
			
		||||
		shader.applyViewportProj();
 | 
			
		||||
		shader.setTranslation(dispPos);
 | 
			
		||||
 | 
			
		||||
		TEX::bind(atlas.tex);
 | 
			
		||||
		GLMeta::vaoBind(vao);
 | 
			
		||||
 | 
			
		||||
		gl.DrawElements(GL_TRIANGLES, aboveQuads*6, _GL_INDEX_TYPE,
 | 
			
		||||
		                (GLvoid*) (groundQuads*6*sizeof(index_t)));
 | 
			
		||||
 | 
			
		||||
		GLMeta::vaoUnbind(vao);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* TileAtlasVX::Reader */
 | 
			
		||||
	void onQuads1(const FloatRect &t1, const FloatRect &p1,
 | 
			
		||||
	              bool overPlayer)
 | 
			
		||||
	{
 | 
			
		||||
		SVertex *vert;
 | 
			
		||||
 | 
			
		||||
		if (overPlayer)
 | 
			
		||||
			vert = allocVert(aboveVert, 4);
 | 
			
		||||
		else
 | 
			
		||||
			vert = allocVert(groundVert, 4);
 | 
			
		||||
 | 
			
		||||
		Quad::setTexPosRect(vert, t1, p1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void onQuads2(const FloatRect t[2], const FloatRect p[2])
 | 
			
		||||
	{
 | 
			
		||||
		SVertex *vert = allocVert(groundVert, 8);
 | 
			
		||||
 | 
			
		||||
		Quad::setTexPosRect(&vert[0], t[0], p[0]);
 | 
			
		||||
		Quad::setTexPosRect(&vert[4], t[1], p[1]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void onQuads4(const FloatRect t[4], const FloatRect p[4])
 | 
			
		||||
	{
 | 
			
		||||
		SVertex *vert = allocVert(groundVert, 16);
 | 
			
		||||
 | 
			
		||||
		Quad::setTexPosRect(&vert[ 0], t[0], p[0]);
 | 
			
		||||
		Quad::setTexPosRect(&vert[ 4], t[1], p[1]);
 | 
			
		||||
		Quad::setTexPosRect(&vert[ 8], t[2], p[2]);
 | 
			
		||||
		Quad::setTexPosRect(&vert[12], t[3], p[3]);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void TilemapVX::BitmapArray::set(int i, Bitmap *bitmap)
 | 
			
		||||
{
 | 
			
		||||
	if (i < 0 || i >= BM_COUNT)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (p->bitmaps[i] == bitmap)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	p->bitmaps[i] = bitmap;
 | 
			
		||||
	p->atlasDirty = true;
 | 
			
		||||
 | 
			
		||||
	p->bmChangedCons[i].disconnect();
 | 
			
		||||
	p->bmChangedCons[i] = bitmap->modified.connect
 | 
			
		||||
		(sigc::mem_fun(p, &TilemapVXPrivate::invalidateAtlas));
 | 
			
		||||
 | 
			
		||||
	p->bmDisposedCons[i].disconnect();
 | 
			
		||||
	p->bmDisposedCons[i] = bitmap->wasDisposed.connect
 | 
			
		||||
		(sigc::bind(sigc::mem_fun(p, &TilemapVXPrivate::onBitmapDisposed), i));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Bitmap *TilemapVX::BitmapArray::get(int i) const
 | 
			
		||||
{
 | 
			
		||||
	if (i < 0 || i >= BM_COUNT)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	return p->bitmaps[i];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TilemapVX::TilemapVX(Viewport *viewport)
 | 
			
		||||
{
 | 
			
		||||
	(void) viewport;
 | 
			
		||||
	p = new TilemapVXPrivate(viewport);
 | 
			
		||||
	p->bitmapsProxy.p = p;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TilemapVX::~TilemapVX()
 | 
			
		||||
{
 | 
			
		||||
	delete p;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TilemapVX::update()
 | 
			
		||||
{
 | 
			
		||||
	if (++p->frameIdx >= 30*3*4)
 | 
			
		||||
		p->frameIdx = 0;
 | 
			
		||||
 | 
			
		||||
	const uint8_t aniIndicesA[3*4] =
 | 
			
		||||
		{ 0, 1, 2, 1, 0, 1, 2, 1, 0, 1, 2, 1 };
 | 
			
		||||
	const uint8_t aniIndicesC[3*4] =
 | 
			
		||||
		{ 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2 };
 | 
			
		||||
 | 
			
		||||
	p->aniIdxA = aniIndicesA[p->frameIdx / 30];
 | 
			
		||||
	p->aniIdxC = aniIndicesC[p->frameIdx / 30];
 | 
			
		||||
 | 
			
		||||
	p->aniOffset = Vec2(p->aniIdxA * 2 * 32, p->aniIdxC * 32);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TilemapVX::BitmapArray &TilemapVX::getBitmapArray() const
 | 
			
		||||
{
 | 
			
		||||
	return p->bitmapsProxy;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DEF_ATTR_RD_SIMPLE(TilemapVX, MapData, Table*, p->mapData)
 | 
			
		||||
DEF_ATTR_RD_SIMPLE(TilemapVX, FlashData, Table*, p->flashData)
 | 
			
		||||
DEF_ATTR_RD_SIMPLE(TilemapVX, Flags, Table*, p->flags)
 | 
			
		||||
DEF_ATTR_RD_SIMPLE(TilemapVX, OX, int, p->offset.x)
 | 
			
		||||
DEF_ATTR_RD_SIMPLE(TilemapVX, OY, int, p->offset.y)
 | 
			
		||||
 | 
			
		||||
Viewport *TilemapVX::getViewport() const
 | 
			
		||||
{
 | 
			
		||||
	return p->getViewport();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool TilemapVX::getVisible() const
 | 
			
		||||
{
 | 
			
		||||
	return p->getVisible();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TilemapVX::setViewport(Viewport *value)
 | 
			
		||||
{
 | 
			
		||||
	p->setViewport(value);
 | 
			
		||||
	p->above.setViewport(value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TilemapVX::setMapData(Table *value)
 | 
			
		||||
{
 | 
			
		||||
	if (p->mapData == value)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	p->mapData = value;
 | 
			
		||||
	p->buffersDirty = true;
 | 
			
		||||
 | 
			
		||||
	p->mapDataCon.disconnect();
 | 
			
		||||
	p->mapDataCon = value->modified.connect
 | 
			
		||||
		(sigc::mem_fun(p, &TilemapVXPrivate::invalidateBuffers));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TilemapVX::setFlashData(Table *value)
 | 
			
		||||
{
 | 
			
		||||
	if (p->flashData == value)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	p->flashData = value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TilemapVX::setFlags(Table *value)
 | 
			
		||||
{
 | 
			
		||||
	if (p->flags == value)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	p->flags = value;
 | 
			
		||||
	p->buffersDirty = true;
 | 
			
		||||
 | 
			
		||||
	p->flagsCon.disconnect();
 | 
			
		||||
	p->flagsCon = value->modified.connect
 | 
			
		||||
		(sigc::mem_fun(p, &TilemapVXPrivate::invalidateBuffers));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TilemapVX::setVisible(bool value)
 | 
			
		||||
{
 | 
			
		||||
	p->setVisible(value);
 | 
			
		||||
	p->above.setVisible(value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TilemapVX::setOX(int value)
 | 
			
		||||
{
 | 
			
		||||
	if (p->offset.x == value)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	p->offset.x = value;
 | 
			
		||||
	p->mapViewportDirty = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TilemapVX::setOY(int value)
 | 
			
		||||
{
 | 
			
		||||
	if (p->offset.y == value)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	p->offset.y = value;
 | 
			
		||||
	p->mapViewportDirty = true;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										71
									
								
								src/tilemapvx.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								src/tilemapvx.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,71 @@
 | 
			
		|||
/*
 | 
			
		||||
** tilemapvx.h
 | 
			
		||||
**
 | 
			
		||||
** This file is part of mkxp.
 | 
			
		||||
**
 | 
			
		||||
** Copyright (C) 2014 Jonas Kulla <Nyocurio@gmail.com>
 | 
			
		||||
**
 | 
			
		||||
** mkxp is free software: you can redistribute it and/or modify
 | 
			
		||||
** it under the terms of the GNU General Public License as published by
 | 
			
		||||
** the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
** (at your option) any later version.
 | 
			
		||||
**
 | 
			
		||||
** mkxp is distributed in the hope that it will be useful,
 | 
			
		||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
** GNU General Public License for more details.
 | 
			
		||||
**
 | 
			
		||||
** You should have received a copy of the GNU General Public License
 | 
			
		||||
** along with mkxp.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef TILEMAPVX_H
 | 
			
		||||
#define TILEMAPVX_H
 | 
			
		||||
 | 
			
		||||
#include "disposable.h"
 | 
			
		||||
#include "util.h"
 | 
			
		||||
 | 
			
		||||
class Viewport;
 | 
			
		||||
class Bitmap;
 | 
			
		||||
class Table;
 | 
			
		||||
 | 
			
		||||
struct TilemapVXPrivate;
 | 
			
		||||
 | 
			
		||||
class TilemapVX : public Disposable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	class BitmapArray
 | 
			
		||||
	{
 | 
			
		||||
	public:
 | 
			
		||||
		void set(int i, Bitmap *bitmap);
 | 
			
		||||
		Bitmap *get(int i) const;
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		BitmapArray() {}
 | 
			
		||||
		~BitmapArray() {}
 | 
			
		||||
 | 
			
		||||
		TilemapVXPrivate *p;
 | 
			
		||||
		friend class TilemapVX;
 | 
			
		||||
		friend struct TilemapVXPrivate;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	TilemapVX(Viewport *viewport = 0);
 | 
			
		||||
	~TilemapVX();
 | 
			
		||||
 | 
			
		||||
	void update();
 | 
			
		||||
 | 
			
		||||
	BitmapArray &getBitmapArray() const;
 | 
			
		||||
 | 
			
		||||
	DECL_ATTR( Viewport,   Viewport* )
 | 
			
		||||
	DECL_ATTR( MapData,    Table*    )
 | 
			
		||||
	DECL_ATTR( FlashData,  Table*    )
 | 
			
		||||
	DECL_ATTR( Flags,      Table*    )
 | 
			
		||||
	DECL_ATTR( Visible,    bool      )
 | 
			
		||||
	DECL_ATTR( OX,         int       )
 | 
			
		||||
	DECL_ATTR( OY,         int       )
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	TilemapVXPrivate *p;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // TILEMAPVX_H
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue