Implement RGSS2 Tilemap class (TilemapVX)
This commit is contained in:
parent
3717609142
commit
7790bd6c2c
|
@ -61,6 +61,7 @@ void tilemapBindingInit();
|
||||||
|
|
||||||
#ifdef RGSS2
|
#ifdef RGSS2
|
||||||
void windowVXBindingInit();
|
void windowVXBindingInit();
|
||||||
|
void tilemapVXBindingInit();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void inputBindingInit();
|
void inputBindingInit();
|
||||||
|
@ -87,12 +88,13 @@ static void mriBindingInit()
|
||||||
spriteBindingInit();
|
spriteBindingInit();
|
||||||
viewportBindingInit();
|
viewportBindingInit();
|
||||||
planeBindingInit();
|
planeBindingInit();
|
||||||
tilemapBindingInit();
|
|
||||||
|
|
||||||
#ifdef RGSS2
|
#ifdef RGSS2
|
||||||
windowVXBindingInit();
|
windowVXBindingInit();
|
||||||
|
tilemapVXBindingInit();
|
||||||
#else
|
#else
|
||||||
windowBindingInit();
|
windowBindingInit();
|
||||||
|
tilemapBindingInit();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inputBindingInit();
|
inputBindingInit();
|
||||||
|
|
|
@ -126,9 +126,10 @@ setPrivateData(VALUE self, void *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline VALUE
|
inline VALUE
|
||||||
wrapObject(void *p, const rb_data_type_struct &type)
|
wrapObject(void *p, const rb_data_type_struct &type,
|
||||||
|
VALUE underKlass = rb_cObject)
|
||||||
{
|
{
|
||||||
VALUE klass = rb_const_get(rb_cObject, rb_intern(type.wrap_struct_name));
|
VALUE klass = rb_const_get(underKlass, rb_intern(type.wrap_struct_name));
|
||||||
VALUE obj = rb_obj_alloc(klass);
|
VALUE obj = rb_obj_alloc(klass);
|
||||||
|
|
||||||
setPrivateData(obj, p);
|
setPrivateData(obj, p);
|
||||||
|
@ -138,9 +139,10 @@ wrapObject(void *p, const rb_data_type_struct &type)
|
||||||
|
|
||||||
inline VALUE
|
inline VALUE
|
||||||
wrapProperty(VALUE self, void *prop, const char *iv,
|
wrapProperty(VALUE self, void *prop, const char *iv,
|
||||||
const rb_data_type_struct &type)
|
const rb_data_type_struct &type,
|
||||||
|
VALUE underKlass = rb_cObject)
|
||||||
{
|
{
|
||||||
VALUE propObj = wrapObject(prop, type);
|
VALUE propObj = wrapObject(prop, type, underKlass);
|
||||||
|
|
||||||
rb_iv_set(self, iv, propObj);
|
rb_iv_set(self, iv, propObj);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,158 @@
|
||||||
|
/*
|
||||||
|
** tilemapvx-binding.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 "viewport.h"
|
||||||
|
#include "bitmap.h"
|
||||||
|
#include "table.h"
|
||||||
|
|
||||||
|
#include "disposable-binding.h"
|
||||||
|
#include "binding-util.h"
|
||||||
|
#include "binding-types.h"
|
||||||
|
|
||||||
|
DEF_TYPE(TilemapVX);
|
||||||
|
rb_data_type_struct BitmapArrayType;
|
||||||
|
|
||||||
|
RB_METHOD(tilemapVXInitialize)
|
||||||
|
{
|
||||||
|
TilemapVX *t;
|
||||||
|
|
||||||
|
/* Get parameters */
|
||||||
|
VALUE viewportObj = Qnil;
|
||||||
|
Viewport *viewport = 0;
|
||||||
|
|
||||||
|
rb_get_args(argc, argv, "|o", &viewportObj RB_ARG_END);
|
||||||
|
|
||||||
|
if (!NIL_P(viewportObj))
|
||||||
|
viewport = getPrivateDataCheck<Viewport>(viewportObj, ViewportType);
|
||||||
|
|
||||||
|
/* Construct object */
|
||||||
|
t = new TilemapVX(viewport);
|
||||||
|
|
||||||
|
setPrivateData(self, t);
|
||||||
|
|
||||||
|
rb_iv_set(self, "viewport", viewportObj);
|
||||||
|
|
||||||
|
wrapProperty(self, &t->getBitmapArray(), "bitmap_array", BitmapArrayType,
|
||||||
|
rb_const_get(rb_cObject, rb_intern("Tilemap")));
|
||||||
|
|
||||||
|
VALUE autotilesObj = rb_iv_get(self, "bitmap_array");
|
||||||
|
|
||||||
|
VALUE ary = rb_ary_new2(7);
|
||||||
|
for (int i = 0; i < 7; ++i)
|
||||||
|
rb_ary_push(ary, Qnil);
|
||||||
|
|
||||||
|
rb_iv_set(autotilesObj, "array", ary);
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
RB_METHOD(tilemapVXGetBitmapArray)
|
||||||
|
{
|
||||||
|
RB_UNUSED_PARAM;
|
||||||
|
|
||||||
|
return rb_iv_get(self, "bitmap_array");
|
||||||
|
}
|
||||||
|
|
||||||
|
RB_METHOD(tilemapVXUpdate)
|
||||||
|
{
|
||||||
|
RB_UNUSED_PARAM;
|
||||||
|
|
||||||
|
TilemapVX *t = getPrivateData<TilemapVX>(self);
|
||||||
|
|
||||||
|
t->update();
|
||||||
|
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEF_PROP_OBJ_NIL(TilemapVX, Viewport, Viewport, "viewport")
|
||||||
|
|
||||||
|
DEF_PROP_OBJ(TilemapVX, Table, MapData, "map_data")
|
||||||
|
DEF_PROP_OBJ(TilemapVX, Table, FlashData, "flash_data")
|
||||||
|
DEF_PROP_OBJ(TilemapVX, Table, Flags, "flags")
|
||||||
|
|
||||||
|
DEF_PROP_B(TilemapVX, Visible)
|
||||||
|
|
||||||
|
DEF_PROP_I(TilemapVX, OX)
|
||||||
|
DEF_PROP_I(TilemapVX, OY)
|
||||||
|
|
||||||
|
RB_METHOD(tilemapVXBitmapsSet)
|
||||||
|
{
|
||||||
|
TilemapVX::BitmapArray *a = getPrivateData<TilemapVX::BitmapArray>(self);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
VALUE bitmapObj;
|
||||||
|
|
||||||
|
rb_get_args(argc, argv, "io", &i, &bitmapObj RB_ARG_END);
|
||||||
|
|
||||||
|
Bitmap *bitmap = getPrivateDataCheck<Bitmap>(bitmapObj, BitmapType);
|
||||||
|
|
||||||
|
a->set(i, bitmap);
|
||||||
|
|
||||||
|
VALUE ary = rb_iv_get(self, "array");
|
||||||
|
rb_ary_store(ary, i, bitmapObj);
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
RB_METHOD(tilemapVXBitmapsGet)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
rb_get_args (argc, argv, "i", &i RB_ARG_END);
|
||||||
|
|
||||||
|
if (i < 0 || i > 6)
|
||||||
|
return Qnil;
|
||||||
|
|
||||||
|
VALUE ary = rb_iv_get(self, "array");
|
||||||
|
|
||||||
|
return rb_ary_entry(ary, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tilemapVXBindingInit()
|
||||||
|
{
|
||||||
|
initType(TilemapVXType, "Tilemap", freeInstance<TilemapVX>);
|
||||||
|
|
||||||
|
VALUE klass = rb_define_class("Tilemap", rb_cObject);
|
||||||
|
rb_define_alloc_func(klass, classAllocate<&TilemapVXType>);
|
||||||
|
|
||||||
|
disposableBindingInit<TilemapVX>(klass);
|
||||||
|
|
||||||
|
_rb_define_method(klass, "initialize", tilemapVXInitialize);
|
||||||
|
_rb_define_method(klass, "bitmaps", tilemapVXGetBitmapArray);
|
||||||
|
_rb_define_method(klass, "update", tilemapVXUpdate);
|
||||||
|
|
||||||
|
INIT_PROP_BIND( TilemapVX, Viewport, "viewport" );
|
||||||
|
INIT_PROP_BIND( TilemapVX, MapData, "map_data" );
|
||||||
|
INIT_PROP_BIND( TilemapVX, FlashData, "flash_data" );
|
||||||
|
INIT_PROP_BIND( TilemapVX, Flags, "flags" );
|
||||||
|
INIT_PROP_BIND( TilemapVX, Visible, "visible" );
|
||||||
|
INIT_PROP_BIND( TilemapVX, OX, "ox" );
|
||||||
|
INIT_PROP_BIND( TilemapVX, OY, "oy" );
|
||||||
|
|
||||||
|
initType(BitmapArrayType, "BitmapArray", 0);
|
||||||
|
|
||||||
|
klass = rb_define_class_under(klass, "BitmapArray", rb_cObject);
|
||||||
|
rb_define_alloc_func(klass, classAllocate<&BitmapArrayType>);
|
||||||
|
|
||||||
|
_rb_define_method(klass, "[]=", tilemapVXBitmapsSet);
|
||||||
|
_rb_define_method(klass, "[]", tilemapVXBitmapsGet);
|
||||||
|
}
|
15
mkxp.pro
15
mkxp.pro
|
@ -197,17 +197,23 @@ EMBED = \
|
||||||
|
|
||||||
RGSS2 {
|
RGSS2 {
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
src/windowvx.h
|
src/windowvx.h \
|
||||||
|
src/tilemapvx.h \
|
||||||
|
src/tileatlasvx.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
src/vorbissource.cpp \
|
src/vorbissource.cpp \
|
||||||
src/windowvx.cpp
|
src/windowvx.cpp \
|
||||||
|
src/tilemapvx.cpp \
|
||||||
|
src/tileatlasvx.cpp \
|
||||||
|
src/autotilesvx.cpp
|
||||||
|
|
||||||
EMBED += \
|
EMBED += \
|
||||||
shader/blur.frag \
|
shader/blur.frag \
|
||||||
shader/blurH.vert \
|
shader/blurH.vert \
|
||||||
shader/blurV.vert \
|
shader/blurV.vert \
|
||||||
shader/simpleMatrix.vert
|
shader/simpleMatrix.vert \
|
||||||
|
shader/tilemapvx.vert
|
||||||
}
|
}
|
||||||
|
|
||||||
MIDI {
|
MIDI {
|
||||||
|
@ -318,7 +324,8 @@ BINDING_MRI {
|
||||||
|
|
||||||
RGSS2 {
|
RGSS2 {
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
binding-mri/windowvx-binding.cpp
|
binding-mri/windowvx-binding.cpp \
|
||||||
|
binding-mri/tilemapvx-binding.cpp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
|
||||||
|
uniform mat4 projMat;
|
||||||
|
|
||||||
|
uniform vec2 texSizeInv;
|
||||||
|
uniform vec2 translation;
|
||||||
|
|
||||||
|
uniform vec2 aniOffset;
|
||||||
|
|
||||||
|
attribute vec2 position;
|
||||||
|
attribute vec2 texCoord;
|
||||||
|
|
||||||
|
varying vec2 v_texCoord;
|
||||||
|
|
||||||
|
const vec2 atAreaA = vec2(9.0*32.0, 12.0*32.0);
|
||||||
|
const float atAreaCX = 12.0*32.0;
|
||||||
|
const float atAreaCW = 4.0*32.0;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec2 tex = texCoord;
|
||||||
|
|
||||||
|
/* Type A autotiles shift horizontally */
|
||||||
|
if (tex.x <= atAreaA.x && tex.y <= atAreaA.y)
|
||||||
|
tex.x += aniOffset.x;
|
||||||
|
|
||||||
|
/* Type C autotiles shift vertically */
|
||||||
|
if (tex.x >= atAreaCX && tex.x <= (atAreaCX+atAreaCW) && tex.y <= atAreaA.y)
|
||||||
|
tex.y += aniOffset.y;
|
||||||
|
|
||||||
|
gl_Position = projMat * vec4(position + translation, 0, 1);
|
||||||
|
|
||||||
|
v_texCoord = tex * texSizeInv;
|
||||||
|
}
|
|
@ -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 "../simpleMatrix.vert.xxd"
|
||||||
#include "../blurH.vert.xxd"
|
#include "../blurH.vert.xxd"
|
||||||
#include "../blurV.vert.xxd"
|
#include "../blurV.vert.xxd"
|
||||||
|
#include "../tilemapvx.vert.xxd"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -535,6 +536,21 @@ BlurShader::VPass::VPass()
|
||||||
ShaderBase::init();
|
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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
13
src/shader.h
13
src/shader.h
|
@ -243,6 +243,18 @@ struct BlurShader
|
||||||
HPass pass1;
|
HPass pass1;
|
||||||
VPass pass2;
|
VPass pass2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TilemapVXShader : public ShaderBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TilemapVXShader();
|
||||||
|
|
||||||
|
void setAniOffset(const Vec2 &value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
GLint u_aniOffset;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Bitmap blit */
|
/* Bitmap blit */
|
||||||
|
@ -280,6 +292,7 @@ struct ShaderSet
|
||||||
#ifdef RGSS2
|
#ifdef RGSS2
|
||||||
SimpleMatrixShader simpleMatrix;
|
SimpleMatrixShader simpleMatrix;
|
||||||
BlurShader blur;
|
BlurShader blur;
|
||||||
|
TilemapVXShader tilemapVX;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
|
@ -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…
Reference in New Issue