Merge branch 'dev'
This commit is contained in:
		
						commit
						58d86039d5
					
				
					 46 changed files with 1121 additions and 632 deletions
				
			
		| 
						 | 
					@ -44,7 +44,7 @@ This binding only exists for testing purposes and does nothing (the engine quits
 | 
				
			||||||
* pixman
 | 
					* pixman
 | 
				
			||||||
* zlib (only ruby bindings)
 | 
					* zlib (only ruby bindings)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mkxp employs Qt's qmake build system, so you'll need to install that beforehand.
 | 
					mkxp employs Qt's qmake build system, so you'll need to install that beforehand. Alternatively, you can build with cmake (FIXME: add cmake instructions).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
qmake will use pkg-config to locate the respective include/library paths. If you installed any dependencies into non-standard prefixes, make sure to adjust your `PKG_CONFIG_PATH` variable accordingly.
 | 
					qmake will use pkg-config to locate the respective include/library paths. If you installed any dependencies into non-standard prefixes, make sure to adjust your `PKG_CONFIG_PATH` variable accordingly.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -89,5 +89,5 @@ If a requested font is not found, no error is generated. Instead, a built-in fon
 | 
				
			||||||
To alleviate possible porting of heavily Win32API reliant scripts, I have added certain functionality that you won't find in the RGSS spec. Currently this amounts to the following:
 | 
					To alleviate possible porting of heavily Win32API reliant scripts, I have added certain functionality that you won't find in the RGSS spec. Currently this amounts to the following:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* The `Input.press?` family of functions accepts three additional button constants: `::MOUSELEFT`, `::MOUSEMIDDLE` and `::MOUSERIGHT` for the respective mouse buttons.
 | 
					* The `Input.press?` family of functions accepts three additional button constants: `::MOUSELEFT`, `::MOUSEMIDDLE` and `::MOUSERIGHT` for the respective mouse buttons.
 | 
				
			||||||
* The `Input` module has two additional functions, `#mouse_x` and `#mouse_y` to query the mouse pointer position relative to the game window.
 | 
					* The `Input` module has two additional functions, `#mouse_x` and `#mouse_y` to query the mouse pointer position relative to the game screen.
 | 
				
			||||||
* The `Graphics` module has two additional properties: `fullscreen` represents the current fullscreen mode (`true` = fullscreen, `false` = windowed), `show_cursor` hides the system cursor inside the game window when `false`.
 | 
					* The `Graphics` module has two additional properties: `fullscreen` represents the current fullscreen mode (`true` = fullscreen, `false` = windowed), `show_cursor` hides the system cursor inside the game window when `false`.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -88,8 +88,13 @@ static void mriBindingInit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fileIntBindingInit();
 | 
						fileIntBindingInit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef RGSS3
 | 
				
			||||||
 | 
						_rb_define_module_function(rb_mKernel, "msgbox",   mriPrint);
 | 
				
			||||||
 | 
						_rb_define_module_function(rb_mKernel, "msgbox_p", mriP);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
	_rb_define_module_function(rb_mKernel, "print", mriPrint);
 | 
						_rb_define_module_function(rb_mKernel, "print", mriPrint);
 | 
				
			||||||
	_rb_define_module_function(rb_mKernel, "p",     mriP);
 | 
						_rb_define_module_function(rb_mKernel, "p",     mriP);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rb_eval_string(module_rpg);
 | 
						rb_eval_string(module_rpg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -237,6 +237,24 @@ rb_get_args(int argc, VALUE *argv, const char *format, ...)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case 'n' :
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (argI >= argc)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ID *sym = va_arg(ap, ID*);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								VALUE symVal = *arg++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (!SYMBOL_P(symVal))
 | 
				
			||||||
 | 
									rb_raise(rb_eTypeError, "Argument %d: Expected symbol", argI);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								*sym = SYM2ID(symVal);
 | 
				
			||||||
 | 
								++argI;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case '|' :
 | 
							case '|' :
 | 
				
			||||||
			opt = true;
 | 
								opt = true;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -131,7 +131,7 @@ wrapNilProperty(VALUE self, const char *iv)
 | 
				
			||||||
	rb_iv_set(self, iv, Qnil);
 | 
						rb_iv_set(self, iv, Qnil);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Implemented: oSszfib| */
 | 
					/* Implemented: oSszfibn| */
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
rb_get_args(int argc, VALUE *argv, const char *format, ...);
 | 
					rb_get_args(int argc, VALUE *argv, const char *format, ...);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,12 +52,14 @@ RB_METHOD(bitmapInitialize)
 | 
				
			||||||
	setPrivateData(self, b);
 | 
						setPrivateData(self, b);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Wrap properties */
 | 
						/* Wrap properties */
 | 
				
			||||||
	Font *font = new Font();
 | 
						VALUE fontKlass = rb_const_get(rb_cObject, rb_intern("Font"));
 | 
				
			||||||
	b->setFont(font);
 | 
						VALUE fontObj = rb_obj_alloc(fontKlass);
 | 
				
			||||||
	font->setColor(new Color(*font->getColor()));
 | 
						rb_obj_call_init(fontObj, 0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	VALUE fontProp = wrapProperty(self, font, "font", FontType);
 | 
						Font *font = getPrivateData<Font>(fontObj);
 | 
				
			||||||
	wrapProperty(fontProp, font->getColor(), "color", ColorType);
 | 
						b->setFont(font);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rb_iv_set(self, "font", fontObj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return self;
 | 
						return self;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -202,7 +204,7 @@ RB_METHOD(bitmapGetPixel)
 | 
				
			||||||
	            return Qnil;
 | 
						            return Qnil;
 | 
				
			||||||
	         )
 | 
						         )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Vec4 value;
 | 
						Color value;
 | 
				
			||||||
	GUARD_EXC( value = b->getPixel(x, y); );
 | 
						GUARD_EXC( value = b->getPixel(x, y); );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Color *color = new Color(value);
 | 
						Color *color = new Color(value);
 | 
				
			||||||
| 
						 | 
					@ -223,7 +225,7 @@ RB_METHOD(bitmapSetPixel)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	color = getPrivateDataCheck<Color>(colorObj, ColorType);
 | 
						color = getPrivateDataCheck<Color>(colorObj, ColorType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GUARD_EXC( b->setPixel(x, y, color->norm); );
 | 
						GUARD_EXC( b->setPixel(x, y, *color); );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return self;
 | 
						return self;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,9 @@
 | 
				
			||||||
#include "binding-util.h"
 | 
					#include "binding-util.h"
 | 
				
			||||||
#include "binding-types.h"
 | 
					#include "binding-types.h"
 | 
				
			||||||
#include "exception.h"
 | 
					#include "exception.h"
 | 
				
			||||||
 | 
					#include "sharedstate.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEF_TYPE(Font);
 | 
					DEF_TYPE(Font);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,14 +39,16 @@ RB_METHOD(fontDoesExist)
 | 
				
			||||||
	return rb_bool_new(Font::doesExist(name));
 | 
						return rb_bool_new(Font::doesExist(name));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RB_METHOD(FontSetName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RB_METHOD(fontInitialize)
 | 
					RB_METHOD(fontInitialize)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char *name = 0;
 | 
						VALUE name = Qnil;
 | 
				
			||||||
	int size = 0;
 | 
						int size = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rb_get_args(argc, argv, "|zi", &name, &size RB_ARG_END);
 | 
						rb_get_args(argc, argv, "|oi", &name, &size RB_ARG_END);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Font *f = new Font(name, size);
 | 
						Font *f = new Font(0, size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	setPrivateData(self, f);
 | 
						setPrivateData(self, f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,6 +56,13 @@ RB_METHOD(fontInitialize)
 | 
				
			||||||
	f->setColor(new Color(*f->getColor()));
 | 
						f->setColor(new Color(*f->getColor()));
 | 
				
			||||||
	wrapProperty(self, f->getColor(), "color", ColorType);
 | 
						wrapProperty(self, f->getColor(), "color", ColorType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (NIL_P(name))
 | 
				
			||||||
 | 
							name = rb_iv_get(rb_obj_class(self), "default_name");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Going over the 'name=' function automatically causes
 | 
				
			||||||
 | 
						 * a possbile name array to be re-verified for existing fonts */
 | 
				
			||||||
 | 
						FontSetName(1, &name, self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return self;
 | 
						return self;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -77,21 +89,63 @@ RB_METHOD(FontGetName)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	RB_UNUSED_PARAM;
 | 
						RB_UNUSED_PARAM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Font *f = getPrivateData<Font>(self);
 | 
						return rb_iv_get(self, "name");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return rb_str_new_cstr(f->getName());
 | 
					static void
 | 
				
			||||||
 | 
					fontSetNameHelper(VALUE self, int argc, VALUE *argv,
 | 
				
			||||||
 | 
					                  const char *nameIv, char *outBuf, size_t outLen)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						rb_check_argc(argc, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						VALUE arg = argv[0];
 | 
				
			||||||
 | 
						int type = rb_type(arg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Fixme: in RGSS3, specifying "" (and only that) as font name results in
 | 
				
			||||||
 | 
						// no text being drawn (everything else is substituted with Arial I think)
 | 
				
			||||||
 | 
						strncpy(outBuf, "", outLen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (type == RUBY_T_STRING)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							strncpy(outBuf, RSTRING_PTR(arg), outLen);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if (type == RUBY_T_ARRAY)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							for (long i = 0; i < RARRAY_LEN(arg); ++i)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								VALUE str = rb_ary_entry(arg, i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								/* Non-string objects are tolerated (ignored) */
 | 
				
			||||||
 | 
								if (rb_type(str) != RUBY_T_STRING)
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								const char *family = RSTRING_PTR(str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								/* We only set the core Font object's name attribute
 | 
				
			||||||
 | 
								 * to the actually existing font name */
 | 
				
			||||||
 | 
								if (!shState->fontState().fontPresent(family))
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								strncpy(outBuf, family, outLen);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* RMXP doesn't even care if the argument type is
 | 
				
			||||||
 | 
						 * something other than string/array. Whatever... */
 | 
				
			||||||
 | 
						rb_iv_set(self, nameIv, arg);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RB_METHOD(FontSetName)
 | 
					RB_METHOD(FontSetName)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	Font *f = getPrivateData<Font>(self);
 | 
						Font *f = getPrivateData<Font>(self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	VALUE name;
 | 
						char result[256];
 | 
				
			||||||
	rb_get_args(argc, argv, "S", &name RB_ARG_END);
 | 
						fontSetNameHelper(self, argc, argv, "default_name",
 | 
				
			||||||
 | 
						                  result, sizeof(result));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	f->setName(RSTRING_PTR(name));
 | 
						f->setName(result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return name;
 | 
						return argv[0];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#undef DEF_PROP_CHK_DISP
 | 
					#undef DEF_PROP_CHK_DISP
 | 
				
			||||||
| 
						 | 
					@ -124,18 +178,19 @@ DEF_KLASS_PROP(Font, bool, DefaultItalic, "b", rb_bool_new)
 | 
				
			||||||
RB_METHOD(FontGetDefaultName)
 | 
					RB_METHOD(FontGetDefaultName)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	RB_UNUSED_PARAM;
 | 
						RB_UNUSED_PARAM;
 | 
				
			||||||
	return rb_str_new_cstr(Font::getDefaultName());
 | 
					
 | 
				
			||||||
 | 
						return rb_iv_get(self, "default_name");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RB_METHOD(FontSetDefaultName)
 | 
					RB_METHOD(FontSetDefaultName)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	RB_UNUSED_PARAM;
 | 
						char result[256];
 | 
				
			||||||
	VALUE nameObj;
 | 
						fontSetNameHelper(self, argc, argv, "default_name",
 | 
				
			||||||
	rb_get_args(argc, argv, "S", &nameObj RB_ARG_END);
 | 
						                  result, sizeof(result));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Font::setDefaultName(RSTRING_PTR(nameObj));
 | 
						Font::setDefaultName(result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nameObj;
 | 
						return argv[0];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RB_METHOD(FontGetDefaultColor)
 | 
					RB_METHOD(FontGetDefaultColor)
 | 
				
			||||||
| 
						 | 
					@ -174,6 +229,7 @@ fontBindingInit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Font::setDefaultColor(new Color(*Font::getDefaultColor()));
 | 
						Font::setDefaultColor(new Color(*Font::getDefaultColor()));
 | 
				
			||||||
	wrapProperty(klass, Font::getDefaultColor(), "default_color", ColorType);
 | 
						wrapProperty(klass, Font::getDefaultColor(), "default_color", ColorType);
 | 
				
			||||||
 | 
						rb_iv_set(klass, "default_name", rb_str_new_cstr(Font::getDefaultName()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	INIT_KLASS_PROP_BIND(Font, DefaultName, "default_name");
 | 
						INIT_KLASS_PROP_BIND(Font, DefaultName, "default_name");
 | 
				
			||||||
	INIT_KLASS_PROP_BIND(Font, DefaultSize, "default_size");
 | 
						INIT_KLASS_PROP_BIND(Font, DefaultSize, "default_size");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -99,6 +99,24 @@ RB_METHOD(graphicsFrameReset)
 | 
				
			||||||
DEF_GRA_PROP_I(FrameRate)
 | 
					DEF_GRA_PROP_I(FrameRate)
 | 
				
			||||||
DEF_GRA_PROP_I(FrameCount)
 | 
					DEF_GRA_PROP_I(FrameCount)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef RGSS2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RB_METHOD(graphicsWidth)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						RB_UNUSED_PARAM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return rb_fix_new(shState->graphics().width());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RB_METHOD(graphicsHeight)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						RB_UNUSED_PARAM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return rb_fix_new(shState->graphics().height());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEF_GRA_PROP_B(Fullscreen)
 | 
					DEF_GRA_PROP_B(Fullscreen)
 | 
				
			||||||
DEF_GRA_PROP_B(ShowCursor)
 | 
					DEF_GRA_PROP_B(ShowCursor)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -120,6 +138,11 @@ void graphicsBindingInit()
 | 
				
			||||||
	INIT_GRA_PROP_BIND( FrameRate,  "frame_rate"  );
 | 
						INIT_GRA_PROP_BIND( FrameRate,  "frame_rate"  );
 | 
				
			||||||
	INIT_GRA_PROP_BIND( FrameCount, "frame_count" );
 | 
						INIT_GRA_PROP_BIND( FrameCount, "frame_count" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef RGSS2
 | 
				
			||||||
 | 
						_rb_define_module_function(module, "width",  graphicsWidth);
 | 
				
			||||||
 | 
						_rb_define_module_function(module, "height", graphicsHeight);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	INIT_GRA_PROP_BIND( Fullscreen, "fullscreen"  );
 | 
						INIT_GRA_PROP_BIND( Fullscreen, "fullscreen"  );
 | 
				
			||||||
	INIT_GRA_PROP_BIND( ShowCursor, "show_cursor" );
 | 
						INIT_GRA_PROP_BIND( ShowCursor, "show_cursor" );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,40 +33,45 @@ RB_METHOD(inputUpdate)
 | 
				
			||||||
	return Qnil;
 | 
						return Qnil;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int getButtonArg(VALUE self, int argc, VALUE *argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int num;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef RGSS3
 | 
				
			||||||
 | 
						ID sym;
 | 
				
			||||||
 | 
						rb_get_args(argc, argv, "n", &sym RB_ARG_END);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (rb_const_defined(self, sym))
 | 
				
			||||||
 | 
							num = FIX2INT(rb_const_get(self, sym));
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							num = 0;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						(void) self;
 | 
				
			||||||
 | 
						rb_get_args(argc, argv, "i", &num RB_ARG_END);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return num;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RB_METHOD(inputPress)
 | 
					RB_METHOD(inputPress)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	RB_UNUSED_PARAM;
 | 
						int num = getButtonArg(self, argc, argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int num;
 | 
						return rb_bool_new(shState->input().isPressed(num));
 | 
				
			||||||
	rb_get_args(argc, argv, "i", &num RB_ARG_END);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Input::ButtonCode bc = (Input::ButtonCode) num;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return rb_bool_new(shState->input().isPressed(bc));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RB_METHOD(inputTrigger)
 | 
					RB_METHOD(inputTrigger)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	RB_UNUSED_PARAM;
 | 
						int num = getButtonArg(self, argc, argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int num;
 | 
						return rb_bool_new(shState->input().isTriggered(num));
 | 
				
			||||||
	rb_get_args(argc, argv, "i", &num RB_ARG_END);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Input::ButtonCode bc = (Input::ButtonCode) num;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return rb_bool_new(shState->input().isTriggered(bc));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RB_METHOD(inputRepeat)
 | 
					RB_METHOD(inputRepeat)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	RB_UNUSED_PARAM;
 | 
						int num = getButtonArg(self, argc, argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int num;
 | 
						return rb_bool_new(shState->input().isRepeated(num));
 | 
				
			||||||
	rb_get_args(argc, argv, "i", &num RB_ARG_END);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Input::ButtonCode bc = (Input::ButtonCode) num;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return rb_bool_new(shState->input().isRepeated(bc));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RB_METHOD(inputDir4)
 | 
					RB_METHOD(inputDir4)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -69,6 +69,39 @@ DEF_PROP_F(Sprite, Angle)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEF_PROP_B(Sprite, Mirror)
 | 
					DEF_PROP_B(Sprite, Mirror)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef RGSS2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RB_METHOD(spriteWidth)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						RB_UNUSED_PARAM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Sprite *s = getPrivateData<Sprite>(self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int value;
 | 
				
			||||||
 | 
						GUARD_EXC( value = s->getWidth(); )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return rb_fix_new(value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RB_METHOD(spriteHeight)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						RB_UNUSED_PARAM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Sprite *s = getPrivateData<Sprite>(self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int value;
 | 
				
			||||||
 | 
						GUARD_EXC( value = s->getHeight(); )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return rb_fix_new(value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEF_PROP_I(Sprite, WaveAmp)
 | 
				
			||||||
 | 
					DEF_PROP_I(Sprite, WaveLength)
 | 
				
			||||||
 | 
					DEF_PROP_I(Sprite, WaveSpeed)
 | 
				
			||||||
 | 
					DEF_PROP_F(Sprite, WavePhase)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
spriteBindingInit()
 | 
					spriteBindingInit()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -98,4 +131,14 @@ spriteBindingInit()
 | 
				
			||||||
	INIT_PROP_BIND( Sprite, BlendType, "blend_type" );
 | 
						INIT_PROP_BIND( Sprite, BlendType, "blend_type" );
 | 
				
			||||||
	INIT_PROP_BIND( Sprite, Color,     "color"      );
 | 
						INIT_PROP_BIND( Sprite, Color,     "color"      );
 | 
				
			||||||
	INIT_PROP_BIND( Sprite, Tone,      "tone"       );
 | 
						INIT_PROP_BIND( Sprite, Tone,      "tone"       );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef RGSS2
 | 
				
			||||||
 | 
						_rb_define_method(klass, "width", spriteWidth);
 | 
				
			||||||
 | 
						_rb_define_method(klass, "height", spriteHeight);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						INIT_PROP_BIND( Sprite, WaveAmp,    "wave_amp"    );
 | 
				
			||||||
 | 
						INIT_PROP_BIND( Sprite, WaveLength, "wave_length" );
 | 
				
			||||||
 | 
						INIT_PROP_BIND( Sprite, WaveSpeed,  "wave_speed"  );
 | 
				
			||||||
 | 
						INIT_PROP_BIND( Sprite, WavePhase,  "wave_phase"  );
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -194,7 +194,7 @@ MRB_METHOD(bitmapGetPixel)
 | 
				
			||||||
	            return mrb_nil_value();
 | 
						            return mrb_nil_value();
 | 
				
			||||||
	         )
 | 
						         )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Vec4 value;
 | 
						Color value;
 | 
				
			||||||
	GUARD_EXC( value = b->getPixel(x, y); )
 | 
						GUARD_EXC( value = b->getPixel(x, y); )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Color *color = new Color(value);
 | 
						Color *color = new Color(value);
 | 
				
			||||||
| 
						 | 
					@ -215,7 +215,7 @@ MRB_METHOD(bitmapSetPixel)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	color = getPrivateDataCheck<Color>(mrb, colorObj, ColorType);
 | 
						color = getPrivateDataCheck<Color>(mrb, colorObj, ColorType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GUARD_EXC( b->setPixel(x, y, color->norm); )
 | 
						GUARD_EXC( b->setPixel(x, y, *color); )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return mrb_nil_value();
 | 
						return mrb_nil_value();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,22 +24,22 @@
 | 
				
			||||||
#include "binding-types.h"
 | 
					#include "binding-types.h"
 | 
				
			||||||
#include "serializable-binding.h"
 | 
					#include "serializable-binding.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ATTR_RW(Type, attr, arg_type, mrb_val, arg_t_s) \
 | 
					#define ATTR_RW(Type, Attr, arg_type, mrb_val, arg_t_s) \
 | 
				
			||||||
	MRB_METHOD(Type##Get_##attr) \
 | 
						MRB_METHOD(Type##Get##Attr) \
 | 
				
			||||||
	{ \
 | 
						{ \
 | 
				
			||||||
		Type *p = getPrivateData<Type>(mrb, self); \
 | 
							Type *p = getPrivateData<Type>(mrb, self); \
 | 
				
			||||||
	 \
 | 
						 \
 | 
				
			||||||
		return mrb_##mrb_val##_value(p->attr); \
 | 
							return mrb_##mrb_val##_value(p->get##Attr()); \
 | 
				
			||||||
	} \
 | 
						} \
 | 
				
			||||||
\
 | 
					\
 | 
				
			||||||
	MRB_METHOD(Type##Set_##attr) \
 | 
						MRB_METHOD(Type##Set##Attr) \
 | 
				
			||||||
	{ \
 | 
						{ \
 | 
				
			||||||
		Type *p = getPrivateData<Type>(mrb, self); \
 | 
							Type *p = getPrivateData<Type>(mrb, self); \
 | 
				
			||||||
	 \
 | 
						 \
 | 
				
			||||||
		arg_type arg; \
 | 
							arg_type arg; \
 | 
				
			||||||
		mrb_get_args(mrb, arg_t_s, &arg); \
 | 
							mrb_get_args(mrb, arg_t_s, &arg); \
 | 
				
			||||||
	 \
 | 
						 \
 | 
				
			||||||
		p->attr = arg; \
 | 
							p->set##Attr(arg); \
 | 
				
			||||||
		UPDATE_F \
 | 
							UPDATE_F \
 | 
				
			||||||
	 \
 | 
						 \
 | 
				
			||||||
		return mrb_##mrb_val##_value(arg); \
 | 
							return mrb_##mrb_val##_value(arg); \
 | 
				
			||||||
| 
						 | 
					@ -64,22 +64,22 @@
 | 
				
			||||||
#define ATTR_INT_RW(Type, attr)   ATTR_RW(Type, attr, mrb_int, fixnum, "i")
 | 
					#define ATTR_INT_RW(Type, attr)   ATTR_RW(Type, attr, mrb_int, fixnum, "i")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define UPDATE_F p->updateInternal();
 | 
					#define UPDATE_F p->updateInternal();
 | 
				
			||||||
ATTR_FLOAT_RW(Color, red)
 | 
					ATTR_FLOAT_RW(Color, Red)
 | 
				
			||||||
ATTR_FLOAT_RW(Color, green)
 | 
					ATTR_FLOAT_RW(Color, Green)
 | 
				
			||||||
ATTR_FLOAT_RW(Color, blue)
 | 
					ATTR_FLOAT_RW(Color, Blue)
 | 
				
			||||||
ATTR_FLOAT_RW(Color, alpha)
 | 
					ATTR_FLOAT_RW(Color, Alpha)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ATTR_FLOAT_RW(Tone, red)
 | 
					ATTR_FLOAT_RW(Tone, Red)
 | 
				
			||||||
ATTR_FLOAT_RW(Tone, green)
 | 
					ATTR_FLOAT_RW(Tone, Green)
 | 
				
			||||||
ATTR_FLOAT_RW(Tone, blue)
 | 
					ATTR_FLOAT_RW(Tone, Blue)
 | 
				
			||||||
ATTR_FLOAT_RW(Tone, gray)
 | 
					ATTR_FLOAT_RW(Tone, Gray)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#undef UPDATE_F
 | 
					#undef UPDATE_F
 | 
				
			||||||
#define UPDATE_F
 | 
					#define UPDATE_F
 | 
				
			||||||
ATTR_INT_RW(Rect, x)
 | 
					ATTR_INT_RW(Rect, X)
 | 
				
			||||||
ATTR_INT_RW(Rect, y)
 | 
					ATTR_INT_RW(Rect, Y)
 | 
				
			||||||
ATTR_INT_RW(Rect, width)
 | 
					ATTR_INT_RW(Rect, Width)
 | 
				
			||||||
ATTR_INT_RW(Rect, height)
 | 
					ATTR_INT_RW(Rect, Height)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EQUAL_FUN(Color)
 | 
					EQUAL_FUN(Color)
 | 
				
			||||||
EQUAL_FUN(Tone)
 | 
					EQUAL_FUN(Tone)
 | 
				
			||||||
| 
						 | 
					@ -163,15 +163,9 @@ CLONE_FUN(Tone)
 | 
				
			||||||
CLONE_FUN(Color)
 | 
					CLONE_FUN(Color)
 | 
				
			||||||
CLONE_FUN(Rect)
 | 
					CLONE_FUN(Rect)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MRB_ATTR_R(Class, attr) mrb_define_method(mrb, klass, #attr, Class##Get_##attr, MRB_ARGS_NONE())
 | 
					#define MRB_ATTR_R(Class, Attr, sym) mrb_define_method(mrb, klass, sym, Class##Get##Attr, MRB_ARGS_NONE())
 | 
				
			||||||
#define MRB_ATTR_W(Class, attr) mrb_define_method(mrb, klass, #attr "=", Class##Set_##attr, MRB_ARGS_REQ(1))
 | 
					#define MRB_ATTR_W(Class, Attr, sym) mrb_define_method(mrb, klass, sym "=", Class##Set##Attr, MRB_ARGS_REQ(1))
 | 
				
			||||||
#define MRB_ATTR_RW(Class, attr) { MRB_ATTR_R(Class, attr); MRB_ATTR_W(Class, attr); }
 | 
					#define MRB_ATTR_RW(Class, Attr, sym) { MRB_ATTR_R(Class, Attr, sym); MRB_ATTR_W(Class, Attr, sym); }
 | 
				
			||||||
 | 
					 | 
				
			||||||
#define MRB_ATTR_RW_A(Class, attr, alias) \
 | 
					 | 
				
			||||||
{ \
 | 
					 | 
				
			||||||
	mrb_define_method(mrb, klass, #alias, Class##Get_##attr, MRB_ARGS_NONE()); \
 | 
					 | 
				
			||||||
	mrb_define_method(mrb, klass, #alias "=", Class##Set_##attr, MRB_ARGS_REQ(1)); \
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define INIT_BIND(Klass) \
 | 
					#define INIT_BIND(Klass) \
 | 
				
			||||||
{ \
 | 
					{ \
 | 
				
			||||||
| 
						 | 
					@ -191,21 +185,21 @@ void etcBindingInit(mrb_state *mrb)
 | 
				
			||||||
	RClass *klass;
 | 
						RClass *klass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	INIT_BIND(Color);
 | 
						INIT_BIND(Color);
 | 
				
			||||||
	MRB_ATTR_RW(Color, red);
 | 
						MRB_ATTR_RW(Color, Red,   "red"  );
 | 
				
			||||||
	MRB_ATTR_RW(Color, green);
 | 
						MRB_ATTR_RW(Color, Green, "green");
 | 
				
			||||||
	MRB_ATTR_RW(Color, blue);
 | 
						MRB_ATTR_RW(Color, Blue,  "blue" );
 | 
				
			||||||
	MRB_ATTR_RW(Color, alpha);
 | 
						MRB_ATTR_RW(Color, Alpha, "alpha");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	INIT_BIND(Tone);
 | 
						INIT_BIND(Tone);
 | 
				
			||||||
	MRB_ATTR_RW(Tone, red);
 | 
						MRB_ATTR_RW(Tone, Red,   "red"  );
 | 
				
			||||||
	MRB_ATTR_RW(Tone, green);
 | 
						MRB_ATTR_RW(Tone, Green, "green");
 | 
				
			||||||
	MRB_ATTR_RW(Tone, blue);
 | 
						MRB_ATTR_RW(Tone, Blue,  "blue" );
 | 
				
			||||||
	MRB_ATTR_RW(Tone, gray);
 | 
						MRB_ATTR_RW(Tone, Gray,  "gray" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	INIT_BIND(Rect);
 | 
						INIT_BIND(Rect);
 | 
				
			||||||
	MRB_ATTR_RW(Rect, x);
 | 
						MRB_ATTR_RW(Rect, X,      "x"     );
 | 
				
			||||||
	MRB_ATTR_RW(Rect, y);
 | 
						MRB_ATTR_RW(Rect, Y,      "y"     );
 | 
				
			||||||
	MRB_ATTR_RW(Rect, width);
 | 
						MRB_ATTR_RW(Rect, Width,  "width" );
 | 
				
			||||||
	MRB_ATTR_RW(Rect, height);
 | 
						MRB_ATTR_RW(Rect, Height, "height");
 | 
				
			||||||
	mrb_define_method(mrb, klass, "empty", RectEmpty, MRB_ARGS_NONE());
 | 
						mrb_define_method(mrb, klass, "empty", RectEmpty, MRB_ARGS_NONE());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,34 +33,44 @@ MRB_FUNCTION(inputUpdate)
 | 
				
			||||||
	return mrb_nil_value();
 | 
						return mrb_nil_value();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MRB_FUNCTION(inputPress)
 | 
					static mrb_int getButtonArg(mrb_state *mrb, mrb_value self)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	mrb_int num;
 | 
						mrb_int num;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef RGSS3
 | 
				
			||||||
 | 
						mrb_sym sym;
 | 
				
			||||||
 | 
						mrb_get_args(mrb, "n", &sym);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (mrb_const_defined(mrb, self, sym))
 | 
				
			||||||
 | 
							num = mrb_fixnum(mrb_const_get(mrb, self, sym));
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							num = 0;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
	mrb_get_args(mrb, "i", &num);
 | 
						mrb_get_args(mrb, "i", &num);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Input::ButtonCode bc = (Input::ButtonCode) num;
 | 
						return num;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return mrb_bool_value(shState->input().isPressed(bc));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MRB_FUNCTION(inputTrigger)
 | 
					MRB_METHOD(inputPress)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	mrb_int num;
 | 
						mrb_int num = getButtonArg(mrb, self);
 | 
				
			||||||
	mrb_get_args(mrb, "i", &num);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Input::ButtonCode bc = (Input::ButtonCode) num;
 | 
						return mrb_bool_value(shState->input().isPressed(num));
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return mrb_bool_value(shState->input().isTriggered(bc));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MRB_FUNCTION(inputRepeat)
 | 
					MRB_METHOD(inputTrigger)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	mrb_int num;
 | 
						mrb_int num = getButtonArg(mrb, self);
 | 
				
			||||||
	mrb_get_args(mrb, "i", &num);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Input::ButtonCode bc = (Input::ButtonCode) num;
 | 
						return mrb_bool_value(shState->input().isTriggered(num));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return mrb_bool_value(shState->input().isRepeated(bc));
 | 
					MRB_METHOD(inputRepeat)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						mrb_int num = getButtonArg(mrb, self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return mrb_bool_value(shState->input().isRepeated(num));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MRB_FUNCTION(inputDir4)
 | 
					MRB_FUNCTION(inputDir4)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,6 +68,35 @@ DEF_PROP_F(Sprite, Angle)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEF_PROP_B(Sprite, Mirror)
 | 
					DEF_PROP_B(Sprite, Mirror)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef RGSS2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MRB_METHOD(spriteWidth)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Sprite *s = getPrivateData<Sprite>(mrb, self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int value;
 | 
				
			||||||
 | 
						GUARD_EXC( value = s->getWidth(); )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return mrb_fixnum_value(value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MRB_METHOD(spriteHeight)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Sprite *s = getPrivateData<Sprite>(mrb, self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int value;
 | 
				
			||||||
 | 
						GUARD_EXC( value = s->getHeight(); )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return mrb_fixnum_value(value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEF_PROP_I(Sprite, WaveAmp)
 | 
				
			||||||
 | 
					DEF_PROP_I(Sprite, WaveLength)
 | 
				
			||||||
 | 
					DEF_PROP_I(Sprite, WaveSpeed)
 | 
				
			||||||
 | 
					DEF_PROP_F(Sprite, WavePhase)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
spriteBindingInit(mrb_state *mrb)
 | 
					spriteBindingInit(mrb_state *mrb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -95,5 +124,15 @@ spriteBindingInit(mrb_state *mrb)
 | 
				
			||||||
	INIT_PROP_BIND( Sprite, Color,     "color"      );
 | 
						INIT_PROP_BIND( Sprite, Color,     "color"      );
 | 
				
			||||||
	INIT_PROP_BIND( Sprite, Tone,      "tone"       );
 | 
						INIT_PROP_BIND( Sprite, Tone,      "tone"       );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef RGSS2
 | 
				
			||||||
 | 
						mrb_define_method(mrb, klass, "width",  spriteWidth,  MRB_ARGS_NONE());
 | 
				
			||||||
 | 
						mrb_define_method(mrb, klass, "height", spriteHeight, MRB_ARGS_NONE());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						INIT_PROP_BIND( Sprite, WaveAmp,    "wave_amp"    );
 | 
				
			||||||
 | 
						INIT_PROP_BIND( Sprite, WaveLength, "wave_length" );
 | 
				
			||||||
 | 
						INIT_PROP_BIND( Sprite, WaveSpeed,  "wave_speed"  );
 | 
				
			||||||
 | 
						INIT_PROP_BIND( Sprite, WavePhase,  "wave_phase"  );
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mrb_define_method(mrb, klass, "inspect", inspectObject, MRB_ARGS_NONE());
 | 
						mrb_define_method(mrb, klass, "inspect", inspectObject, MRB_ARGS_NONE());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -119,3 +119,18 @@
 | 
				
			||||||
# (default: disabled)
 | 
					# (default: disabled)
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# useScriptNames=false
 | 
					# useScriptNames=false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Font substitutions allow drop-in replacements of fonts
 | 
				
			||||||
 | 
					# to be used without changing the RGSS scripts,
 | 
				
			||||||
 | 
					# eg. providing 'Open Sans' when the game thinkgs it's
 | 
				
			||||||
 | 
					# using 'Arial'. Font family to be substituted and
 | 
				
			||||||
 | 
					# replacement family are separated by one sole '>'.
 | 
				
			||||||
 | 
					# Be careful not to include any spaces.
 | 
				
			||||||
 | 
					# This is not connected to the built-in font, which is
 | 
				
			||||||
 | 
					# always used when a non-existing font family is
 | 
				
			||||||
 | 
					# requested by RGSS.
 | 
				
			||||||
 | 
					# (default: none)
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# fontSub=Arial>Open Sans
 | 
				
			||||||
 | 
					# fontSub=Times New Roman>Liberation Serif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										5
									
								
								mkxp.pro
									
										
									
									
									
								
							
							
						
						
									
										5
									
								
								mkxp.pro
									
										
									
									
									
								
							| 
						 | 
					@ -44,6 +44,11 @@ RGSS2 {
 | 
				
			||||||
	DEFINES += RGSS2
 | 
						DEFINES += RGSS2
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Requires RGSS2
 | 
				
			||||||
 | 
					RGSS3 {
 | 
				
			||||||
 | 
						DEFINES += RGSS3
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unix {
 | 
					unix {
 | 
				
			||||||
	CONFIG += link_pkgconfig
 | 
						CONFIG += link_pkgconfig
 | 
				
			||||||
	PKGCONFIG += sigc++-2.0 glew pixman-1 zlib physfs \
 | 
						PKGCONFIG += sigc++-2.0 glew pixman-1 zlib physfs \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,18 +20,14 @@ void main()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	vec4 resFrag;
 | 
						vec4 resFrag;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	float ab = opacity;
 | 
						float co1 = srcFrag.a * opacity;
 | 
				
			||||||
	float as = srcFrag.a;
 | 
						float co2 = dstFrag.a * (1.0 - co1);
 | 
				
			||||||
	float ad = dstFrag.a;
 | 
						resFrag.a = co1 + co2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	float at = ab*as;
 | 
						if (resFrag.a == 0.0)
 | 
				
			||||||
	resFrag.a = at + ad - ad*at;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Sigh...
 | 
					 | 
				
			||||||
	if (ad == 0.0)
 | 
					 | 
				
			||||||
		resFrag.rgb = srcFrag.rgb;
 | 
							resFrag.rgb = srcFrag.rgb;
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		resFrag.rgb = as*srcFrag.rgb + (1.0-at) * ad * dstFrag.rgb;
 | 
							resFrag.rgb = (co1*srcFrag.rgb + co2*dstFrag.rgb) / resFrag.a;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gl_FragColor = resFrag;
 | 
						gl_FragColor = resFrag;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,7 @@
 | 
				
			||||||
#define ALUTIL_H
 | 
					#define ALUTIL_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <al.h>
 | 
					#include <al.h>
 | 
				
			||||||
 | 
					#include <alc.h>
 | 
				
			||||||
#include <alext.h>
 | 
					#include <alext.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace AL
 | 
					namespace AL
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -366,6 +366,7 @@ struct SDLSoundSource : ALDataSource
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	~SDLSoundSource()
 | 
						~SDLSoundSource()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							/* This also closes 'srcOps' */
 | 
				
			||||||
		Sound_FreeSample(sample);
 | 
							Sound_FreeSample(sample);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,10 +55,6 @@ struct BitmapPrivate
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	TEXFBO gl;
 | 
						TEXFBO gl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* 'setPixel()' calls are cached and executed
 | 
					 | 
				
			||||||
	 * in batches on 'flush()' */
 | 
					 | 
				
			||||||
	PointArray pointArray;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Font *font;
 | 
						Font *font;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* "Mega surfaces" are a hack to allow Tilesets to be used
 | 
						/* "Mega surfaces" are a hack to allow Tilesets to be used
 | 
				
			||||||
| 
						 | 
					@ -154,32 +150,9 @@ struct BitmapPrivate
 | 
				
			||||||
		glState.blendMode.pop();
 | 
							glState.blendMode.pop();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void flushPoints()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (pointArray.count() == 0)
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		SimpleColorShader &shader = shState->shaders().simpleColor;
 | 
					 | 
				
			||||||
		shader.bind();
 | 
					 | 
				
			||||||
		shader.setTranslation(Vec2i());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		bindFBO();
 | 
					 | 
				
			||||||
		pushSetViewport(shader);
 | 
					 | 
				
			||||||
		glState.blendMode.pushSet(BlendNone);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		pointArray.commit();
 | 
					 | 
				
			||||||
		pointArray.draw();
 | 
					 | 
				
			||||||
		pointArray.reset();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		glState.blendMode.pop();
 | 
					 | 
				
			||||||
		popViewport();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void fillRect(const IntRect &rect,
 | 
						void fillRect(const IntRect &rect,
 | 
				
			||||||
	              const Vec4 &color)
 | 
						              const Vec4 &color)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		flushPoints();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		bindFBO();
 | 
							bindFBO();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		glState.scissorTest.pushSet(true);
 | 
							glState.scissorTest.pushSet(true);
 | 
				
			||||||
| 
						 | 
					@ -271,7 +244,6 @@ Bitmap::Bitmap(const Bitmap &other)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p->gl = shState->texPool().request(other.width(), other.height());
 | 
						p->gl = shState->texPool().request(other.width(), other.height());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	other.flush();
 | 
					 | 
				
			||||||
	blt(0, 0, other, rect());
 | 
						blt(0, 0, other, rect());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -368,8 +340,6 @@ void Bitmap::stretchBlt(const IntRect &destRect,
 | 
				
			||||||
	if (opacity == 255 && !p->touchesTaintedArea(destRect))
 | 
						if (opacity == 255 && !p->touchesTaintedArea(destRect))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/* Fast blit */
 | 
							/* Fast blit */
 | 
				
			||||||
		flush();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		FBO::bind(source.p->gl.fbo, FBO::Read);
 | 
							FBO::bind(source.p->gl.fbo, FBO::Read);
 | 
				
			||||||
		FBO::bind(p->gl.fbo, FBO::Draw);
 | 
							FBO::bind(p->gl.fbo, FBO::Draw);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -379,8 +349,6 @@ void Bitmap::stretchBlt(const IntRect &destRect,
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/* Fragment pipeline */
 | 
							/* Fragment pipeline */
 | 
				
			||||||
		flush();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		float normOpacity = (float) opacity / 255.0f;
 | 
							float normOpacity = (float) opacity / 255.0f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		TEXFBO &gpTex = shState->gpTexFBO(destRect.w, destRect.h);
 | 
							TEXFBO &gpTex = shState->gpTexFBO(destRect.w, destRect.h);
 | 
				
			||||||
| 
						 | 
					@ -461,8 +429,6 @@ void Bitmap::gradientFillRect(const IntRect &rect,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GUARD_MEGA;
 | 
						GUARD_MEGA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flush();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	SimpleColorShader &shader = shState->shaders().simpleColor;
 | 
						SimpleColorShader &shader = shState->shaders().simpleColor;
 | 
				
			||||||
	shader.bind();
 | 
						shader.bind();
 | 
				
			||||||
	shader.setTranslation(Vec2i());
 | 
						shader.setTranslation(Vec2i());
 | 
				
			||||||
| 
						 | 
					@ -520,8 +486,6 @@ void Bitmap::blur()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GUARD_MEGA;
 | 
						GUARD_MEGA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flush();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Quad &quad = shState->gpQuad();
 | 
						Quad &quad = shState->gpQuad();
 | 
				
			||||||
	FloatRect rect(0, 0, width(), height());
 | 
						FloatRect rect(0, 0, width(), height());
 | 
				
			||||||
	quad.setTexPosRect(rect, rect);
 | 
						quad.setTexPosRect(rect, rect);
 | 
				
			||||||
| 
						 | 
					@ -567,8 +531,6 @@ void Bitmap::radialBlur(int angle, int divisions)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GUARD_MEGA;
 | 
						GUARD_MEGA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flush();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	angle     = clamp<int>(angle, 0, 359);
 | 
						angle     = clamp<int>(angle, 0, 359);
 | 
				
			||||||
	divisions = clamp<int>(divisions, 2, 100);
 | 
						divisions = clamp<int>(divisions, 2, 100);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -666,9 +628,6 @@ void Bitmap::clear()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GUARD_MEGA;
 | 
						GUARD_MEGA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Any queued points won't be visible after this anyway */
 | 
					 | 
				
			||||||
	p->pointArray.reset();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	p->bindFBO();
 | 
						p->bindFBO();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	glState.clearColor.pushSet(Vec4());
 | 
						glState.clearColor.pushSet(Vec4());
 | 
				
			||||||
| 
						 | 
					@ -682,7 +641,7 @@ void Bitmap::clear()
 | 
				
			||||||
	modified();
 | 
						modified();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Vec4 Bitmap::getPixel(int x, int y) const
 | 
					Color Bitmap::getPixel(int x, int y) const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	GUARD_DISPOSED;
 | 
						GUARD_DISPOSED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -691,24 +650,34 @@ Vec4 Bitmap::getPixel(int x, int y) const
 | 
				
			||||||
	if (x < 0 || y < 0 || x >= width() || y >= height())
 | 
						if (x < 0 || y < 0 || x >= width() || y >= height())
 | 
				
			||||||
		return Vec4();
 | 
							return Vec4();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flush();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	FBO::bind(p->gl.fbo, FBO::Read);
 | 
						FBO::bind(p->gl.fbo, FBO::Read);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	glState.viewport.pushSet(IntRect(0, 0, width(), height()));
 | 
						glState.viewport.pushSet(IntRect(0, 0, width(), height()));
 | 
				
			||||||
	Vec4 pixel = FBO::getPixel(x, y);
 | 
					
 | 
				
			||||||
 | 
						uint8_t pixel[4];
 | 
				
			||||||
 | 
						glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	glState.viewport.pop();
 | 
						glState.viewport.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return pixel;
 | 
						return Color(pixel[0], pixel[1], pixel[2], pixel[3]);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Bitmap::setPixel(int x, int y, const Vec4 &color)
 | 
					void Bitmap::setPixel(int x, int y, const Color &color)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	GUARD_DISPOSED;
 | 
						GUARD_DISPOSED;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GUARD_MEGA;
 | 
						GUARD_MEGA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p->pointArray.append(Vec2(x+.5, y+.5), color);
 | 
						uint8_t pixel[] =
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							(uint8_t) clamp<double>(color.red,   0, 255),
 | 
				
			||||||
 | 
							(uint8_t) clamp<double>(color.green, 0, 255),
 | 
				
			||||||
 | 
							(uint8_t) clamp<double>(color.blue,  0, 255),
 | 
				
			||||||
 | 
							(uint8_t) clamp<double>(color.alpha, 0, 255)
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TEX::bind(p->gl.tex);
 | 
				
			||||||
 | 
						TEX::uploadSubImage(x, y, 1, 1, &pixel, GL_RGBA);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p->addTaintedArea(IntRect(x, y, 1, 1));
 | 
						p->addTaintedArea(IntRect(x, y, 1, 1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -724,8 +693,6 @@ void Bitmap::hueChange(int hue)
 | 
				
			||||||
	if ((hue % 360) == 0)
 | 
						if ((hue % 360) == 0)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flush();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	TEXFBO newTex = shState->texPool().request(width(), height());
 | 
						TEXFBO newTex = shState->texPool().request(width(), height());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	FloatRect texRect(rect());
 | 
						FloatRect texRect(rect());
 | 
				
			||||||
| 
						 | 
					@ -748,8 +715,6 @@ void Bitmap::hueChange(int hue)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p->blitQuad(quad);
 | 
						p->blitQuad(quad);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	shader.unbind();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	p->popViewport();
 | 
						p->popViewport();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	TEX::unbind();
 | 
						TEX::unbind();
 | 
				
			||||||
| 
						 | 
					@ -779,8 +744,6 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align)
 | 
				
			||||||
	if (str[0] == ' ' && str[1] == '\0')
 | 
						if (str[0] == ' ' && str[1] == '\0')
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flush();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	TTF_Font *font = p->font->getSdlFont();
 | 
						TTF_Font *font = p->font->getSdlFont();
 | 
				
			||||||
	Color *fontColor = p->font->getColor();
 | 
						Color *fontColor = p->font->getColor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1011,17 +974,6 @@ IntRect Bitmap::textSize(const char *str)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEF_ATTR_SIMPLE(Bitmap, Font, Font*, p->font)
 | 
					DEF_ATTR_SIMPLE(Bitmap, Font, Font*, p->font)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Bitmap::flush() const
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (isDisposed())
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (p->megaSurface)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	p->flushPoints();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TEXFBO &Bitmap::getGLTypes()
 | 
					TEXFBO &Bitmap::getGLTypes()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return p->gl;
 | 
						return p->gl;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,8 +81,8 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void clear();
 | 
						void clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Vec4 getPixel(int x, int y) const;
 | 
						Color getPixel(int x, int y) const;
 | 
				
			||||||
	void setPixel(int x, int y, const Vec4 &color);
 | 
						void setPixel(int x, int y, const Color &color);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void hueChange(int hue);
 | 
						void hueChange(int hue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -105,9 +105,6 @@ public:
 | 
				
			||||||
	DECL_ATTR(Font, Font*)
 | 
						DECL_ATTR(Font, Font*)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* <internal> */
 | 
						/* <internal> */
 | 
				
			||||||
	/* Warning: Flushing might change the current
 | 
					 | 
				
			||||||
	 * FBO binding (so don't call it during 'draw()' routines */
 | 
					 | 
				
			||||||
	void flush() const;
 | 
					 | 
				
			||||||
	TEXFBO &getGLTypes();
 | 
						TEXFBO &getGLTypes();
 | 
				
			||||||
	SDL_Surface *megaSurface() const;
 | 
						SDL_Surface *megaSurface() const;
 | 
				
			||||||
	void ensureNonMega() const;
 | 
						void ensureNonMega() const;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,7 +35,6 @@ namespace po = boost::program_options;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Config::Config()
 | 
					Config::Config()
 | 
				
			||||||
    : debugMode(false),
 | 
					    : debugMode(false),
 | 
				
			||||||
      screenshots(false),
 | 
					 | 
				
			||||||
      winResizable(false),
 | 
					      winResizable(false),
 | 
				
			||||||
      fullscreen(false),
 | 
					      fullscreen(false),
 | 
				
			||||||
      fixedAspectRatio(true),
 | 
					      fixedAspectRatio(true),
 | 
				
			||||||
| 
						 | 
					@ -57,7 +56,6 @@ void Config::read(int argc, char *argv[])
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#define PO_DESC_ALL \
 | 
					#define PO_DESC_ALL \
 | 
				
			||||||
	PO_DESC(debugMode, bool) \
 | 
						PO_DESC(debugMode, bool) \
 | 
				
			||||||
	PO_DESC(screenshots, bool) \
 | 
					 | 
				
			||||||
	PO_DESC(winResizable, bool) \
 | 
						PO_DESC(winResizable, bool) \
 | 
				
			||||||
	PO_DESC(fullscreen, bool) \
 | 
						PO_DESC(fullscreen, bool) \
 | 
				
			||||||
	PO_DESC(fixedAspectRatio, bool) \
 | 
						PO_DESC(fixedAspectRatio, bool) \
 | 
				
			||||||
| 
						 | 
					@ -85,6 +83,7 @@ void Config::read(int argc, char *argv[])
 | 
				
			||||||
	podesc.add_options()
 | 
						podesc.add_options()
 | 
				
			||||||
	        PO_DESC_ALL
 | 
						        PO_DESC_ALL
 | 
				
			||||||
	        ("RTP", po::value<StringVec>()->composing())
 | 
						        ("RTP", po::value<StringVec>()->composing())
 | 
				
			||||||
 | 
						        ("fontSub", po::value<StringVec>()->composing())
 | 
				
			||||||
	        ;
 | 
						        ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	po::variables_map vm;
 | 
						po::variables_map vm;
 | 
				
			||||||
| 
						 | 
					@ -117,6 +116,8 @@ void Config::read(int argc, char *argv[])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GUARD_ALL( rtps = vm["RTP"].as<StringVec>(); );
 | 
						GUARD_ALL( rtps = vm["RTP"].as<StringVec>(); );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						GUARD_ALL( fontSubs = vm["fontSub"].as<StringVec>(); );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#undef PO_DESC
 | 
					#undef PO_DESC
 | 
				
			||||||
#undef PO_DESC_ALL
 | 
					#undef PO_DESC_ALL
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,7 +28,6 @@
 | 
				
			||||||
struct Config
 | 
					struct Config
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	bool debugMode;
 | 
						bool debugMode;
 | 
				
			||||||
	bool screenshots;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool winResizable;
 | 
						bool winResizable;
 | 
				
			||||||
	bool fullscreen;
 | 
						bool fullscreen;
 | 
				
			||||||
| 
						 | 
					@ -56,6 +55,8 @@ struct Config
 | 
				
			||||||
	std::string customScript;
 | 
						std::string customScript;
 | 
				
			||||||
	std::vector<std::string> rtps;
 | 
						std::vector<std::string> rtps;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::vector<std::string> fontSubs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Game INI contents */
 | 
						/* Game INI contents */
 | 
				
			||||||
	struct {
 | 
						struct {
 | 
				
			||||||
		std::string scripts;
 | 
							std::string scripts;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,7 +46,7 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	~Debug()
 | 
						~Debug()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		std::clog << buf.str() << "\n";
 | 
							std::clog << buf.str() << std::endl;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -209,9 +209,6 @@ void EventThread::process(RGSSThreadData &rtData)
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (event.key.keysym.scancode == SDL_SCANCODE_F3 && rtData.config.screenshots)
 | 
					 | 
				
			||||||
				rtData.rqScreenshot = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			keyStates[event.key.keysym.scancode] = true;
 | 
								keyStates[event.key.keysym.scancode] = true;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -178,8 +178,6 @@ struct RGSSThreadData
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::string rgssErrorMsg;
 | 
						std::string rgssErrorMsg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	volatile bool rqScreenshot;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	RGSSThreadData(EventThread *ethread,
 | 
						RGSSThreadData(EventThread *ethread,
 | 
				
			||||||
	               const char *argv0,
 | 
						               const char *argv0,
 | 
				
			||||||
	               SDL_Window *window,
 | 
						               SDL_Window *window,
 | 
				
			||||||
| 
						 | 
					@ -190,8 +188,7 @@ struct RGSSThreadData
 | 
				
			||||||
	      argv0(argv0),
 | 
						      argv0(argv0),
 | 
				
			||||||
	      window(window),
 | 
						      window(window),
 | 
				
			||||||
	      sizeResoRatio(1, 1),
 | 
						      sizeResoRatio(1, 1),
 | 
				
			||||||
	      config(newconf),
 | 
						      config(newconf)
 | 
				
			||||||
	      rqScreenshot(false)
 | 
					 | 
				
			||||||
	{}
 | 
						{}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,6 +21,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "filesystem.h"
 | 
					#include "filesystem.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "font.h"
 | 
				
			||||||
#include "util.h"
 | 
					#include "util.h"
 | 
				
			||||||
#include "exception.h"
 | 
					#include "exception.h"
 | 
				
			||||||
#include "boost-hash.h"
 | 
					#include "boost-hash.h"
 | 
				
			||||||
| 
						 | 
					@ -297,8 +298,12 @@ RGSS_openArchive(PHYSFS_Io *io, const char *, int forWrite)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Check header */
 | 
						/* Check header */
 | 
				
			||||||
	uint32_t header1, header2;
 | 
						uint32_t header1, header2;
 | 
				
			||||||
	readUint32(io, header1);
 | 
					
 | 
				
			||||||
	readUint32(io, header2);
 | 
						if (!readUint32(io, header1))
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!readUint32(io, header2))
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (header1 != RGSS_HEADER_1 || header2 != RGSS_HEADER_2)
 | 
						if (header1 != RGSS_HEADER_1 || header2 != RGSS_HEADER_2)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
| 
						 | 
					@ -476,41 +481,133 @@ RGSS_noop2(void*, const char*)
 | 
				
			||||||
static const PHYSFS_Archiver RGSS_Archiver =
 | 
					static const PHYSFS_Archiver RGSS_Archiver =
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	0,
 | 
						0,
 | 
				
			||||||
    {
 | 
						{
 | 
				
			||||||
        "RGSSAD",
 | 
							"RGSSAD",
 | 
				
			||||||
        "RGSS encrypted archive format",
 | 
							"RGSS encrypted archive format",
 | 
				
			||||||
        "Jonas Kulla <Nyocurio@gmail.com>",
 | 
							"Jonas Kulla <Nyocurio@gmail.com>",
 | 
				
			||||||
        "http://k-du.de/rgss/rgss.html",
 | 
							"http://k-du.de/rgss/rgss.html",
 | 
				
			||||||
        0 /* symlinks not supported */
 | 
							0 /* symlinks not supported */
 | 
				
			||||||
    },
 | 
						},
 | 
				
			||||||
    RGSS_openArchive,
 | 
						RGSS_openArchive,
 | 
				
			||||||
    RGSS_enumerateFiles,
 | 
						RGSS_enumerateFiles,
 | 
				
			||||||
    RGSS_openRead,
 | 
						RGSS_openRead,
 | 
				
			||||||
    RGSS_noop1, /* openWrite */
 | 
						RGSS_noop1, /* openWrite */
 | 
				
			||||||
    RGSS_noop1, /* openAppend */
 | 
						RGSS_noop1, /* openAppend */
 | 
				
			||||||
    RGSS_noop2, /* remove */
 | 
						RGSS_noop2, /* remove */
 | 
				
			||||||
    RGSS_noop2, /* mkdir */
 | 
						RGSS_noop2, /* mkdir */
 | 
				
			||||||
    RGSS_stat,
 | 
						RGSS_stat,
 | 
				
			||||||
    RGSS_closeArchive
 | 
						RGSS_closeArchive
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline PHYSFS_File *sdlPHYS(SDL_RWops *ops)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return static_cast<PHYSFS_File*>(ops->hidden.unknown.data1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static Sint64 SDL_RWopsSize(SDL_RWops *ops)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PHYSFS_File *f = sdlPHYS(ops);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!f)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return PHYSFS_fileLength(f);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static Sint64 SDL_RWopsSeek(SDL_RWops *ops, int64_t offset, int whence)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PHYSFS_File *f = sdlPHYS(ops);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!f)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int64_t base;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (whence)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
						case RW_SEEK_SET :
 | 
				
			||||||
 | 
							base = 0;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case RW_SEEK_CUR :
 | 
				
			||||||
 | 
							base = PHYSFS_tell(f);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case RW_SEEK_END :
 | 
				
			||||||
 | 
							base = PHYSFS_fileLength(f);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int result = PHYSFS_seek(f, base + offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (result != 0) ? PHYSFS_tell(f) : -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static size_t SDL_RWopsRead(SDL_RWops *ops, void *buffer, size_t size, size_t maxnum)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PHYSFS_File *f = sdlPHYS(ops);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!f)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						PHYSFS_sint64 result = PHYSFS_readBytes(f, buffer, size*maxnum);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (result != -1) ? (result / size) : 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static size_t SDL_RWopsWrite(SDL_RWops *ops, const void *buffer, size_t size, size_t num)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PHYSFS_File *f = sdlPHYS(ops);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!f)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						PHYSFS_sint64 result = PHYSFS_writeBytes(f, buffer, size*num);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (result != -1) ? (result / size) : 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int SDL_RWopsClose(SDL_RWops *ops)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						PHYSFS_File *f = sdlPHYS(ops);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!f)
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int result = PHYSFS_close(f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						f = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (result != 0) ? 0 : -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int SDL_RWopsCloseFree(SDL_RWops *ops)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int result = SDL_RWopsClose(ops);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SDL_FreeRW(ops);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Uint32 SDL_RWOPS_PHYSFS = SDL_RWOPS_UNKNOWN+10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct FileSystemPrivate
 | 
					struct FileSystemPrivate
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/* All keys are lower case */
 | 
						/* Maps: lower case filename, To: actual (mixed case) filename.
 | 
				
			||||||
 | 
						 * This is for compatibility with games that take Windows'
 | 
				
			||||||
 | 
						 * case insensitivity for granted */
 | 
				
			||||||
	BoostHash<std::string, std::string> pathCache;
 | 
						BoostHash<std::string, std::string> pathCache;
 | 
				
			||||||
 | 
						bool havePathCache;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::vector<std::string> extensions[FileSystem::Undefined+1];
 | 
						std::vector<std::string> extensions[FileSystem::Undefined+1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// FIXME Need to find a better way to do this..
 | 
					 | 
				
			||||||
	char pathBuffer[512];
 | 
					 | 
				
			||||||
	bool havePathCache;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Attempt to locate an extension string in a filename.
 | 
						/* Attempt to locate an extension string in a filename.
 | 
				
			||||||
	 * Either a pointer into the input string pointing at the
 | 
						 * Either a pointer into the input string pointing at the
 | 
				
			||||||
	 * extension, or null is returned */
 | 
						 * extension, or null is returned */
 | 
				
			||||||
	const char *findExt(const char *filename)
 | 
						const char *findExt(const char *filename)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		int len;
 | 
							size_t len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (len = strlen(filename); len > 0; --len)
 | 
							for (len = strlen(filename); len > 0; --len)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
| 
						 | 
					@ -524,110 +621,147 @@ struct FileSystemPrivate
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const char *completeFileName(const char *filename,
 | 
						/* Complete filename via regular physfs lookup */
 | 
				
			||||||
	                             FileSystem::FileType type,
 | 
						bool completeFilenameReg(const char *filename,
 | 
				
			||||||
	                             const char **foundExt)
 | 
						                         FileSystem::FileType type,
 | 
				
			||||||
 | 
						                         char *outBuffer,
 | 
				
			||||||
 | 
						                         size_t outN,
 | 
				
			||||||
 | 
						                         const char **foundExt)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (!havePathCache)
 | 
							/* Try supplementing extensions to find an existing path */
 | 
				
			||||||
 | 
							const std::vector<std::string> &extList = extensions[type];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (size_t i = 0; i < extList.size(); ++i)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (PHYSFS_exists(filename))
 | 
								const char *ext = extList[i].c_str();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								snprintf(outBuffer, outN, "%s.%s", filename, ext);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (PHYSFS_exists(outBuffer))
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				if (foundExt)
 | 
									if (foundExt)
 | 
				
			||||||
					*foundExt = findExt(filename);
 | 
										*foundExt = ext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				return filename;
 | 
									return true;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					 | 
				
			||||||
			const std::vector<std::string> &extList = extensions[type];
 | 
					 | 
				
			||||||
			for (size_t i = 0; i < extList.size(); ++i)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				const char *ext = extList[i].c_str();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				snprintf(pathBuffer, sizeof(pathBuffer), "%s.%s", filename, ext);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				if (PHYSFS_exists(pathBuffer))
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					if (foundExt)
 | 
					 | 
				
			||||||
						*foundExt = ext;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					return pathBuffer;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			// Is this even necessary?
 | 
					 | 
				
			||||||
			if (foundExt)
 | 
					 | 
				
			||||||
				*foundExt = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			return 0;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		char buff[512];
 | 
							/* Doing the check without supplemented extension
 | 
				
			||||||
		size_t i;
 | 
							 * fits the usage pattern of RMXP games */
 | 
				
			||||||
 | 
							if (PHYSFS_exists(filename))
 | 
				
			||||||
		for (i = 0; i < sizeof(buff) && filename[i]; ++i)
 | 
					 | 
				
			||||||
			buff[i] = tolower(filename[i]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		buff[i] = '\0';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		std::string key(buff);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* If the path was already complete,
 | 
					 | 
				
			||||||
		 * we are done at this point */
 | 
					 | 
				
			||||||
		if (pathCache.contains(key))
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			/* The extension might already be included here,
 | 
								strncpy(outBuffer, filename, outN);
 | 
				
			||||||
			 * so try to find it */
 | 
					
 | 
				
			||||||
			if (foundExt)
 | 
								if (foundExt)
 | 
				
			||||||
				*foundExt = findExt(filename);
 | 
									*foundExt = findExt(filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return pathCache[key].c_str();
 | 
								return true;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		char buff2[512];
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Try supplementing extensions
 | 
						/* Complete filename via path cache */
 | 
				
			||||||
		 * to find an existing path */
 | 
						bool completeFilenamePC(const char *filename,
 | 
				
			||||||
		if (type != FileSystem::Undefined)
 | 
						                        FileSystem::FileType type,
 | 
				
			||||||
 | 
					                            char *outBuffer,
 | 
				
			||||||
 | 
					                            size_t outN,
 | 
				
			||||||
 | 
					                            const char **foundExt)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							size_t i;
 | 
				
			||||||
 | 
							char lowCase[512];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (i = 0; i < sizeof(lowCase)-1 && filename[i]; ++i)
 | 
				
			||||||
 | 
								lowCase[i] = tolower(filename[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							lowCase[i] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							std::string key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							const std::vector<std::string> &extList = extensions[type];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (size_t i = 0; i < extList.size(); ++i)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			std::vector<std::string> &extList = extensions[type];
 | 
								const char *ext = extList[i].c_str();
 | 
				
			||||||
			for (size_t i = 0; i < extList.size(); ++i)
 | 
					
 | 
				
			||||||
 | 
								snprintf(outBuffer, outN, "%s.%s", lowCase, ext);
 | 
				
			||||||
 | 
								key = outBuffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (pathCache.contains(key))
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				const char *ext = extList[i].c_str();
 | 
									strncpy(outBuffer, pathCache[key].c_str(), outN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				snprintf(buff2, sizeof(buff2), "%s.%s", buff, ext);
 | 
									if (foundExt)
 | 
				
			||||||
				key = buff2;
 | 
										*foundExt = ext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (pathCache.contains(key))
 | 
									return true;
 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					if (foundExt)
 | 
					 | 
				
			||||||
						*foundExt = ext;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					return pathCache[key].c_str();
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (foundExt)
 | 
							key = lowCase;
 | 
				
			||||||
			*foundExt = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return 0;
 | 
							if (pathCache.contains(key))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								strncpy(outBuffer, pathCache[key].c_str(), outN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (foundExt)
 | 
				
			||||||
 | 
									*foundExt = findExt(filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	PHYSFS_File *openReadInt(const char *filename,
 | 
						/* Try to complete 'filename' with file extensions
 | 
				
			||||||
	                         FileSystem::FileType type,
 | 
						 * based on 'type'. If no combination could be found,
 | 
				
			||||||
	                         const char **foundExt)
 | 
						 * returns false, and 'foundExt' is untouched */
 | 
				
			||||||
 | 
						bool completeFileName(const char *filename,
 | 
				
			||||||
 | 
						                      FileSystem::FileType type,
 | 
				
			||||||
 | 
					                          char *outBuffer,
 | 
				
			||||||
 | 
					                          size_t outN,
 | 
				
			||||||
 | 
					                          const char **foundExt)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		const char *foundName = completeFileName(filename, type, foundExt);
 | 
							if (havePathCache)
 | 
				
			||||||
 | 
								return completeFilenamePC(filename, type, outBuffer, outN, foundExt);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								return completeFilenameReg(filename, type, outBuffer, outN, foundExt);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!foundName)
 | 
						PHYSFS_File *openReadHandle(const char *filename,
 | 
				
			||||||
 | 
						                            FileSystem::FileType type,
 | 
				
			||||||
 | 
						                            const char **foundExt)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							char found[512];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!completeFileName(filename, type, found, sizeof(found), foundExt))
 | 
				
			||||||
			throw Exception(Exception::NoFileError, "%s", filename);
 | 
								throw Exception(Exception::NoFileError, "%s", filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		PHYSFS_File *handle = PHYSFS_openRead(foundName);
 | 
							PHYSFS_File *handle = PHYSFS_openRead(found);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!handle)
 | 
							if (!handle)
 | 
				
			||||||
			throw Exception(Exception::PHYSFSError, "PhysFS: %s", PHYSFS_getLastError());
 | 
								throw Exception(Exception::PHYSFSError, "PhysFS: %s", PHYSFS_getLastError());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return handle;
 | 
							return handle;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void initReadOps(PHYSFS_File *handle,
 | 
				
			||||||
 | 
						                 SDL_RWops &ops,
 | 
				
			||||||
 | 
						                 bool freeOnClose)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							ops.size  = SDL_RWopsSize;
 | 
				
			||||||
 | 
							ops.seek  = SDL_RWopsSeek;
 | 
				
			||||||
 | 
							ops.read  = SDL_RWopsRead;
 | 
				
			||||||
 | 
							ops.write = SDL_RWopsWrite;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (freeOnClose)
 | 
				
			||||||
 | 
								ops.close = SDL_RWopsCloseFree;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								ops.close = SDL_RWopsClose;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ops.type = SDL_RWOPS_PHYSFS;
 | 
				
			||||||
 | 
							ops.hidden.unknown.data1 = handle;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FileSystem::FileSystem(const char *argv0,
 | 
					FileSystem::FileSystem(const char *argv0,
 | 
				
			||||||
| 
						 | 
					@ -724,123 +858,83 @@ void FileSystem::createPathCache()
 | 
				
			||||||
	p->havePathCache = true;
 | 
						p->havePathCache = true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline PHYSFS_File *sdlPHYS(SDL_RWops *ops)
 | 
					static void strToLower(std::string &str)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return static_cast<PHYSFS_File*>(ops->hidden.unknown.data1);
 | 
						for (size_t i = 0; i < str.size(); ++i)
 | 
				
			||||||
 | 
							str[i] = tolower(str[i]);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Sint64 SDL_RWopsSize(SDL_RWops *ops)
 | 
					struct FontSetsCBData
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	PHYSFS_File *f = sdlPHYS(ops);
 | 
						FileSystemPrivate *p;
 | 
				
			||||||
 | 
						SharedFontState *sfs;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!f)
 | 
					static void fontSetEnumCB(void *data, const char *,
 | 
				
			||||||
		return -1;
 | 
					                          const char *fname)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						FontSetsCBData *d = static_cast<FontSetsCBData*>(data);
 | 
				
			||||||
 | 
						FileSystemPrivate *p = d->p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return PHYSFS_fileLength(f);
 | 
						/* Only consider filenames with font extensions */
 | 
				
			||||||
 | 
						const char *ext = p->findExt(fname);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!ext)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string lower(ext);
 | 
				
			||||||
 | 
						strToLower(lower);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!contains(p->extensions[FileSystem::Font], lower))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string filename("Fonts/");
 | 
				
			||||||
 | 
						filename += fname;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						PHYSFS_File *handle = PHYSFS_openRead(filename.c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!handle)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SDL_RWops ops;
 | 
				
			||||||
 | 
						p->initReadOps(handle, ops, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						d->sfs->initFontSetCB(ops, filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SDL_RWclose(&ops);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Sint64 SDL_RWopsSeek(SDL_RWops *ops, int64_t offset, int whence)
 | 
					void FileSystem::initFontSets(SharedFontState &sfs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	PHYSFS_File *f = sdlPHYS(ops);
 | 
						FontSetsCBData d = { p, &sfs };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!f)
 | 
						PHYSFS_enumerateFilesCallback("Fonts", fontSetEnumCB, &d);
 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int64_t base;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (whence)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
	case RW_SEEK_SET :
 | 
					 | 
				
			||||||
		base = 0;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case RW_SEEK_CUR :
 | 
					 | 
				
			||||||
		base = PHYSFS_tell(f);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case RW_SEEK_END :
 | 
					 | 
				
			||||||
		base = PHYSFS_fileLength(f);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int result = PHYSFS_seek(f, base + offset);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return (result != 0) ? PHYSFS_tell(f) : -1;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static size_t SDL_RWopsRead(SDL_RWops *ops, void *buffer, size_t size, size_t maxnum)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	PHYSFS_File *f = sdlPHYS(ops);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!f)
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	PHYSFS_sint64 result = PHYSFS_readBytes(f, buffer, size*maxnum);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return (result != -1) ? (result / size) : 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static size_t SDL_RWopsWrite(SDL_RWops *ops, const void *buffer, size_t size, size_t num)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	PHYSFS_File *f = sdlPHYS(ops);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!f)
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	PHYSFS_sint64 result = PHYSFS_writeBytes(f, buffer, size*num);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return (result != -1) ? (result / size) : 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int SDL_RWopsClose(SDL_RWops *ops)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	PHYSFS_File *f = sdlPHYS(ops);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!f)
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int result = PHYSFS_close(f);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	f = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return (result != 0) ? 0 : -1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int SDL_RWopsCloseFree(SDL_RWops *ops)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int result = SDL_RWopsClose(ops);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	SDL_FreeRW(ops);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const Uint32 SDL_RWOPS_PHYSFS = SDL_RWOPS_UNKNOWN+10;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void FileSystem::openRead(SDL_RWops &ops,
 | 
					void FileSystem::openRead(SDL_RWops &ops,
 | 
				
			||||||
                          const char *filename,
 | 
					                          const char *filename,
 | 
				
			||||||
                          FileType type,
 | 
					                          FileType type,
 | 
				
			||||||
                          bool freeOnClose,
 | 
					                          bool freeOnClose,
 | 
				
			||||||
                          const char **foundExt)
 | 
					                          const char **foundExt)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	PHYSFS_File *handle = p->openReadInt(filename, type, foundExt);
 | 
						PHYSFS_File *handle = p->openReadHandle(filename, type, foundExt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ops.size  = SDL_RWopsSize;
 | 
						p->initReadOps(handle, ops, freeOnClose);
 | 
				
			||||||
	ops.seek  = SDL_RWopsSeek;
 | 
					}
 | 
				
			||||||
	ops.read  = SDL_RWopsRead;
 | 
					 | 
				
			||||||
	ops.write = SDL_RWopsWrite;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (freeOnClose)
 | 
					void FileSystem::openReadRaw(SDL_RWops &ops,
 | 
				
			||||||
		ops.close = SDL_RWopsCloseFree;
 | 
					                             const char *filename,
 | 
				
			||||||
	else
 | 
					                             bool freeOnClose)
 | 
				
			||||||
		ops.close = SDL_RWopsClose;
 | 
					{
 | 
				
			||||||
 | 
						PHYSFS_File *handle = PHYSFS_openRead(filename);
 | 
				
			||||||
 | 
						assert(handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ops.type = SDL_RWOPS_PHYSFS;
 | 
						p->initReadOps(handle, ops, freeOnClose);
 | 
				
			||||||
	ops.hidden.unknown.data1 = handle;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool FileSystem::exists(const char *filename, FileType type)
 | 
					bool FileSystem::exists(const char *filename, FileType type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char *foundName = p->completeFileName(filename, type, 0);
 | 
						char found[512];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (foundName != 0);
 | 
						return p->completeFileName(filename, type, found, sizeof(found), 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,6 +25,7 @@
 | 
				
			||||||
#include <SDL_rwops.h>
 | 
					#include <SDL_rwops.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct FileSystemPrivate;
 | 
					struct FileSystemPrivate;
 | 
				
			||||||
 | 
					class SharedFontState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FileSystem
 | 
					class FileSystem
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -35,9 +36,13 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void addPath(const char *path);
 | 
						void addPath(const char *path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Call this after the last 'addPath()' */
 | 
						/* Call these after the last 'addPath()' */
 | 
				
			||||||
	void createPathCache();
 | 
						void createPathCache();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Scans "Fonts/" and creates inventory of
 | 
				
			||||||
 | 
						 * available font assets */
 | 
				
			||||||
 | 
						void initFontSets(SharedFontState &sfs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* For extension supplementing */
 | 
						/* For extension supplementing */
 | 
				
			||||||
	enum FileType
 | 
						enum FileType
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -53,6 +58,11 @@ public:
 | 
				
			||||||
	              bool freeOnClose = false,
 | 
						              bool freeOnClose = false,
 | 
				
			||||||
	              const char **foundExt = 0);
 | 
						              const char **foundExt = 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Circumvents extension supplementing */
 | 
				
			||||||
 | 
						void openReadRaw(SDL_RWops &ops,
 | 
				
			||||||
 | 
						                 const char *filename,
 | 
				
			||||||
 | 
						                 bool freeOnClose = false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool exists(const char *filename,
 | 
						bool exists(const char *filename,
 | 
				
			||||||
	            FileType type = Undefined);
 | 
						            FileType type = Undefined);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,7 +55,7 @@ public:
 | 
				
			||||||
		flashAlpha = flashColor.w;
 | 
							flashAlpha = flashColor.w;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void update()
 | 
						virtual void update()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (!flashing)
 | 
							if (!flashing)
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										176
									
								
								src/font.cpp
									
										
									
									
									
								
							
							
						
						
									
										176
									
								
								src/font.cpp
									
										
									
									
									
								
							| 
						 | 
					@ -26,6 +26,7 @@
 | 
				
			||||||
#include "exception.h"
 | 
					#include "exception.h"
 | 
				
			||||||
#include "boost-hash.h"
 | 
					#include "boost-hash.h"
 | 
				
			||||||
#include "util.h"
 | 
					#include "util.h"
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
#include <utility>
 | 
					#include <utility>
 | 
				
			||||||
| 
						 | 
					@ -45,88 +46,151 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef std::pair<std::string, int> FontKey;
 | 
					typedef std::pair<std::string, int> FontKey;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void strToLower(std::string &str)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	for (size_t i = 0; i < str.size(); ++i)
 | 
					 | 
				
			||||||
		str[i] = tolower(str[i]);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct FontPoolPrivate
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	BoostHash<FontKey, TTF_Font*> hash;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FontPool::FontPool()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	p = new FontPoolPrivate;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FontPool::~FontPool()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	BoostHash<FontKey, TTF_Font*>::const_iterator iter;
 | 
					 | 
				
			||||||
	for (iter = p->hash.cbegin(); iter != p->hash.cend(); ++iter)
 | 
					 | 
				
			||||||
		TTF_CloseFont(iter->second);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	delete p;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static SDL_RWops *openBundledFont()
 | 
					static SDL_RWops *openBundledFont()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return SDL_RWFromConstMem(BNDL_F_D(BUNDLED_FONT), BNDL_F_L(BUNDLED_FONT));
 | 
						return SDL_RWFromConstMem(BNDL_F_D(BUNDLED_FONT), BNDL_F_L(BUNDLED_FONT));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_TTF_Font *FontPool::request(const char *filename,
 | 
					struct FontSet
 | 
				
			||||||
                             int size)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	// FIXME Find out how font path resolution is done in VX/Ace
 | 
						/* 'Regular' style */
 | 
				
			||||||
	std::string nameKey(filename);
 | 
						std::string regular;
 | 
				
			||||||
	strToLower(nameKey);
 | 
					 | 
				
			||||||
	strReplace(nameKey, ' ', '_');
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool useBundled = false;
 | 
						/* Any other styles (used in case no 'Regular' exists) */
 | 
				
			||||||
	std::string path = std::string("Fonts/") + nameKey;
 | 
						std::string other;
 | 
				
			||||||
	if (!shState->fileSystem().exists(path.c_str(), FileSystem::Font))
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct SharedFontStatePrivate
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* Maps: font family name, To: substituted family name,
 | 
				
			||||||
 | 
						 * as specified via configuration file / arguments */
 | 
				
			||||||
 | 
						BoostHash<std::string, std::string> subs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Maps: font family name, To: set of physical
 | 
				
			||||||
 | 
						 * font filenames located in "Fonts/" */
 | 
				
			||||||
 | 
						BoostHash<std::string, FontSet> sets;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Pool of already opened fonts; once opened, they are reused
 | 
				
			||||||
 | 
						 * and never closed until the termination of the program */
 | 
				
			||||||
 | 
						BoostHash<FontKey, TTF_Font*> pool;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SharedFontState::SharedFontState(const Config &conf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						p = new SharedFontStatePrivate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Parse font substitutions */
 | 
				
			||||||
 | 
						for (size_t i = 0; i < conf.fontSubs.size(); ++i)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/* Use the same name key for the bundled font
 | 
							const std::string &raw = conf.fontSubs[i];
 | 
				
			||||||
		 * even when it resulted from multiple different
 | 
							size_t sepPos = raw.find_first_of('>');
 | 
				
			||||||
		 * font name requests. The space at the front is
 | 
					
 | 
				
			||||||
		 * to prevent collisions (spaces are normally
 | 
							if (sepPos == std::string::npos)
 | 
				
			||||||
		 * replaced with '_' */
 | 
								continue;
 | 
				
			||||||
		useBundled = true;
 | 
					
 | 
				
			||||||
		nameKey = " bundled";
 | 
							std::string from = raw.substr(0, sepPos);
 | 
				
			||||||
 | 
							std::string to   = raw.substr(sepPos+1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							p->subs.insert(from, to);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SharedFontState::~SharedFontState()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						BoostHash<FontKey, TTF_Font*>::const_iterator iter;
 | 
				
			||||||
 | 
						for (iter = p->pool.cbegin(); iter != p->pool.cend(); ++iter)
 | 
				
			||||||
 | 
							TTF_CloseFont(iter->second);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						delete p;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SharedFontState::initFontSetCB(SDL_RWops &ops,
 | 
				
			||||||
 | 
					                                    const std::string &filename)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						TTF_Font *font = TTF_OpenFontRW(&ops, 0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!font)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string family = TTF_FontFaceFamilyName(font);
 | 
				
			||||||
 | 
						std::string style = TTF_FontFaceStyleName(font);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TTF_CloseFont(font);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FontSet &set = p->sets[family];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (style == "Regular")
 | 
				
			||||||
 | 
							set.regular = filename;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							set.other = filename;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_TTF_Font *SharedFontState::getFont(std::string family,
 | 
				
			||||||
 | 
					                                    int size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* Check for substitutions */
 | 
				
			||||||
 | 
						if (p->subs.contains(family))
 | 
				
			||||||
 | 
							family = p->subs[family];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Find out if the font asset exists */
 | 
				
			||||||
 | 
						const FontSet &req = p->sets[family];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (req.regular.empty() && req.other.empty())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							/* Doesn't exist; use built-in font */
 | 
				
			||||||
 | 
							family = "";
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	FontKey key(nameKey, size);
 | 
						FontKey key(family, size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	TTF_Font *font = p->hash.value(key, 0);
 | 
						TTF_Font *font = p->pool.value(key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (font)
 | 
						if (font)
 | 
				
			||||||
		return font;
 | 
							return font;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Not in hash, open */
 | 
						/* Not in pool; open new handle */
 | 
				
			||||||
	SDL_RWops *ops;
 | 
						SDL_RWops *ops;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (useBundled)
 | 
						if (family.empty())
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							/* Built-in font */
 | 
				
			||||||
		ops = openBundledFont();
 | 
							ops = openBundledFont();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							/* Use 'other' path as alternative in case
 | 
				
			||||||
 | 
							 * we have no 'regular' styled font asset */
 | 
				
			||||||
 | 
							const char *path = !req.regular.empty()
 | 
				
			||||||
 | 
							                 ? req.regular.c_str() : req.other.c_str();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ops = SDL_AllocRW();
 | 
							ops = SDL_AllocRW();
 | 
				
			||||||
		shState->fileSystem().openRead(*ops, path.c_str(), FileSystem::Font, true);
 | 
							shState->fileSystem().openReadRaw(*ops, path, true);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// FIXME 0.9 is guesswork at this point
 | 
						// FIXME 0.9 is guesswork at this point
 | 
				
			||||||
	font = TTF_OpenFontRW(ops, 1, (float) size * .90);
 | 
					//	float gamma = (96.0/45.0)*(5.0/14.0)*(size-5);
 | 
				
			||||||
 | 
					//	font = TTF_OpenFontRW(ops, 1, gamma /** .90*/);
 | 
				
			||||||
 | 
						font = TTF_OpenFontRW(ops, 1, size* .90);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!font)
 | 
						if (!font)
 | 
				
			||||||
		throw Exception(Exception::SDLError, "SDL: %s", SDL_GetError());
 | 
							throw Exception(Exception::SDLError, "%s", SDL_GetError());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p->hash.insert(key, font);
 | 
						p->pool.insert(key, font);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return font;
 | 
						return font;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool SharedFontState::fontPresent(std::string family)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* Check for substitutions */
 | 
				
			||||||
 | 
						if (p->subs.contains(family))
 | 
				
			||||||
 | 
							family = p->subs[family];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const FontSet &set = p->sets[family];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return !(set.regular.empty() && set.other.empty());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct FontPrivate
 | 
					struct FontPrivate
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -173,7 +237,7 @@ struct FontPrivate
 | 
				
			||||||
	{}
 | 
						{}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::string FontPrivate::defaultName   = "MS PGothic";
 | 
					std::string FontPrivate::defaultName   = "Arial";
 | 
				
			||||||
int         FontPrivate::defaultSize   = 22;
 | 
					int         FontPrivate::defaultSize   = 22;
 | 
				
			||||||
bool        FontPrivate::defaultBold   = false;
 | 
					bool        FontPrivate::defaultBold   = false;
 | 
				
			||||||
bool        FontPrivate::defaultItalic = false;
 | 
					bool        FontPrivate::defaultItalic = false;
 | 
				
			||||||
| 
						 | 
					@ -183,9 +247,7 @@ Color FontPrivate::defaultColorTmp(255, 255, 255, 255);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool Font::doesExist(const char *name)
 | 
					bool Font::doesExist(const char *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	std::string path = std::string("Fonts/") + std::string(name);
 | 
						return shState->fontState().fontPresent(name);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return shState->fileSystem().exists(path.c_str(), FileSystem::Font);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Font::Font(const char *name,
 | 
					Font::Font(const char *name,
 | 
				
			||||||
| 
						 | 
					@ -223,6 +285,10 @@ void Font::setSize(int value)
 | 
				
			||||||
	if (p->size == value)
 | 
						if (p->size == value)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Catch illegal values (according to RMXP) */
 | 
				
			||||||
 | 
						if (value < 6 || value > 96)
 | 
				
			||||||
 | 
							throw Exception(Exception::ArgumentError, "%s", "bad value for size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p->size = value;
 | 
						p->size = value;
 | 
				
			||||||
	p->sdlFont = 0;
 | 
						p->sdlFont = 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -253,8 +319,8 @@ void Font::setDefaultName(const char *value)
 | 
				
			||||||
_TTF_Font *Font::getSdlFont()
 | 
					_TTF_Font *Font::getSdlFont()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!p->sdlFont)
 | 
						if (!p->sdlFont)
 | 
				
			||||||
		p->sdlFont = shState->fontPool().request(p->name.c_str(),
 | 
							p->sdlFont = shState->fontState().getFont(p->name.c_str(),
 | 
				
			||||||
		                                         p->size);
 | 
							                                          p->size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int style = TTF_STYLE_NORMAL;
 | 
						int style = TTF_STYLE_NORMAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										46
									
								
								src/font.h
									
										
									
									
									
								
							
							
						
						
									
										46
									
								
								src/font.h
									
										
									
									
									
								
							| 
						 | 
					@ -25,22 +25,50 @@
 | 
				
			||||||
#include "etc.h"
 | 
					#include "etc.h"
 | 
				
			||||||
#include "util.h"
 | 
					#include "util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct SDL_RWops;
 | 
				
			||||||
struct _TTF_Font;
 | 
					struct _TTF_Font;
 | 
				
			||||||
struct FontPoolPrivate;
 | 
					struct Config;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FontPool
 | 
					struct SharedFontStatePrivate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SharedFontState
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	FontPool();
 | 
						SharedFontState(const Config &conf);
 | 
				
			||||||
	~FontPool();
 | 
						~SharedFontState();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_TTF_Font *request(const char *filename,
 | 
						/* Called from FileSystem during font cache initialization
 | 
				
			||||||
 | 
						 * (when "Fonts/" is scanned for available assets).
 | 
				
			||||||
 | 
						 * 'ops' is an opened handle to a possible font file,
 | 
				
			||||||
 | 
						 * 'filename' is the corresponding path */
 | 
				
			||||||
 | 
						void initFontSetCB(SDL_RWops &ops,
 | 
				
			||||||
 | 
						                   const std::string &filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_TTF_Font *getFont(std::string family,
 | 
				
			||||||
	                   int size);
 | 
						                   int size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool fontPresent(std::string family);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	FontPoolPrivate *p;
 | 
						SharedFontStatePrivate *p;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Concerning Font::name/defaultName :
 | 
				
			||||||
 | 
					 * In RGSS, this is not actually a string; any type of
 | 
				
			||||||
 | 
					 * object is accepted, however anything but strings and
 | 
				
			||||||
 | 
					 * arrays is ignored (and text drawing turns blank).
 | 
				
			||||||
 | 
					 * Single strings are interpreted as font family names,
 | 
				
			||||||
 | 
					 * and directly passed to the underlying C++ object;
 | 
				
			||||||
 | 
					 * arrays however are searched for the first string
 | 
				
			||||||
 | 
					 * object corresponding to a valid font family name,
 | 
				
			||||||
 | 
					 * and rendering is done with that. In mkxp, we pass
 | 
				
			||||||
 | 
					 * this first valid font family as the 'name' attribute
 | 
				
			||||||
 | 
					 * back to the C++ object on assignment and object
 | 
				
			||||||
 | 
					 * creation (in case Font.default_name is also an array).
 | 
				
			||||||
 | 
					 * Invalid parameters (things other than strings or
 | 
				
			||||||
 | 
					 * arrays not containing any valid family name) are
 | 
				
			||||||
 | 
					 * passed back as "". */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct FontPrivate;
 | 
					struct FontPrivate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Font
 | 
					class Font
 | 
				
			||||||
| 
						 | 
					@ -57,9 +85,9 @@ public:
 | 
				
			||||||
	const char *getName() const;
 | 
						const char *getName() const;
 | 
				
			||||||
	void setName(const char *value);
 | 
						void setName(const char *value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	DECL_ATTR( Size,   int )
 | 
						DECL_ATTR( Size,   int    )
 | 
				
			||||||
	DECL_ATTR( Bold,   bool )
 | 
						DECL_ATTR( Bold,   bool   )
 | 
				
			||||||
	DECL_ATTR( Italic, bool )
 | 
						DECL_ATTR( Italic, bool   )
 | 
				
			||||||
	DECL_ATTR( Color,  Color* )
 | 
						DECL_ATTR( Color,  Color* )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	DECL_ATTR_STATIC( DefaultName,   const char* )
 | 
						DECL_ATTR_STATIC( DefaultName,   const char* )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -216,15 +216,6 @@ namespace FBO
 | 
				
			||||||
		blit(srcX, srcY, srcW, srcH, dstX, dstY, srcW, srcH, mode);
 | 
							blit(srcX, srcY, srcW, srcH, dstX, dstY, srcW, srcH, mode);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline Vec4 getPixel(int x, int y)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		Vec4 pixel;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		glReadPixels(x, y, 1, 1, GL_RGBA, GL_FLOAT, &pixel.x);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return pixel;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	inline void clear()
 | 
						inline void clear()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		glClear(GL_COLOR_BUFFER_BIT);
 | 
							glClear(GL_COLOR_BUFFER_BIT);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,6 +20,7 @@
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "glstate.h"
 | 
					#include "glstate.h"
 | 
				
			||||||
 | 
					#include "shader.h"
 | 
				
			||||||
#include "etc.h"
 | 
					#include "etc.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <glew.h>
 | 
					#include <glew.h>
 | 
				
			||||||
| 
						 | 
					@ -95,6 +96,11 @@ void GLViewport::apply(const IntRect &value)
 | 
				
			||||||
	glViewport(value.x, value.y, value.w, value.h);
 | 
						glViewport(value.x, value.y, value.w, value.h);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void GLProgram::apply(const unsigned int &value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						glUseProgram(value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GLState::Caps::Caps()
 | 
					GLState::Caps::Caps()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
 | 
						glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
 | 
				
			||||||
| 
						 | 
					@ -110,4 +116,5 @@ GLState::GLState()
 | 
				
			||||||
	scissorTest.init(false);
 | 
						scissorTest.init(false);
 | 
				
			||||||
	scissorBox.init(IntRect(0, 0, 640, 480));
 | 
						scissorBox.init(IntRect(0, 0, 640, 480));
 | 
				
			||||||
	texture2D.init(true);
 | 
						texture2D.init(true);
 | 
				
			||||||
 | 
						program.init(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -99,6 +99,11 @@ class GLViewport : public GLProperty<IntRect>
 | 
				
			||||||
	void apply(const IntRect &value);
 | 
						void apply(const IntRect &value);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GLProgram : public GLProperty<unsigned int> /* GLuint */
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						void apply(const unsigned int &value);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GLState
 | 
					class GLState
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -109,6 +114,7 @@ public:
 | 
				
			||||||
	GLTexture2D texture2D;
 | 
						GLTexture2D texture2D;
 | 
				
			||||||
	GLBlendMode blendMode;
 | 
						GLBlendMode blendMode;
 | 
				
			||||||
	GLViewport viewport;
 | 
						GLViewport viewport;
 | 
				
			||||||
 | 
						GLProgram program;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct Caps
 | 
						struct Caps
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -191,7 +191,6 @@ public:
 | 
				
			||||||
		screenQuad.draw();
 | 
							screenQuad.draw();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		glState.blendMode.pop();
 | 
							glState.blendMode.pop();
 | 
				
			||||||
		shader.unbind();
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef RGSS2
 | 
					#ifdef RGSS2
 | 
				
			||||||
| 
						 | 
					@ -508,44 +507,6 @@ struct GraphicsPrivate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		swapGLBuffer();
 | 
							swapGLBuffer();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	void writeScreenshot(const char *filename)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		int bpp;
 | 
					 | 
				
			||||||
		uint32_t rm, gm, bm, am;
 | 
					 | 
				
			||||||
		SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_ABGR8888, &bpp, &rm, &gm, &bm, &am);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* Discard alpha channel because it might have bogus values */
 | 
					 | 
				
			||||||
		SDL_Surface *screenshot =
 | 
					 | 
				
			||||||
		        SDL_CreateRGBSurface(0, scRes.x, scRes.y, bpp, rm, gm, bm, 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		screen.getPP().bindLastBuffer();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		glReadPixels(0, 0, scRes.x, scRes.y, GL_RGBA, GL_UNSIGNED_BYTE, screenshot->pixels);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		IMG_SavePNG(screenshot, filename);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		SDL_FreeSurface(screenshot);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void checkScreenshotRq()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (!threadData->rqScreenshot)
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		threadData->rqScreenshot = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		struct timeval tv;
 | 
					 | 
				
			||||||
		gettimeofday(&tv, 0);
 | 
					 | 
				
			||||||
		struct tm tm = *localtime(&tv.tv_sec);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		char filename[32];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		snprintf(filename, sizeof(filename), "%d%02d%02d-%02d%02d%02d.png",
 | 
					 | 
				
			||||||
		         tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		writeScreenshot(filename);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Graphics::Graphics(RGSSThreadData *data)
 | 
					Graphics::Graphics(RGSSThreadData *data)
 | 
				
			||||||
| 
						 | 
					@ -569,8 +530,6 @@ void Graphics::update()
 | 
				
			||||||
//	p->cpuTimer->endTiming();
 | 
					//	p->cpuTimer->endTiming();
 | 
				
			||||||
//	p->gpuTimer->startTiming();
 | 
					//	p->gpuTimer->startTiming();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p->checkScreenshotRq();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (p->frozen)
 | 
						if (p->frozen)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -93,9 +93,6 @@ struct PlanePrivate
 | 
				
			||||||
			updateQuadSource();
 | 
								updateQuadSource();
 | 
				
			||||||
			quadSourceDirty = false;
 | 
								quadSourceDirty = false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (bitmap)
 | 
					 | 
				
			||||||
			bitmap->flush();
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										135
									
								
								src/quadarray.h
									
										
									
									
									
								
							
							
						
						
									
										135
									
								
								src/quadarray.h
									
										
									
									
									
								
							| 
						 | 
					@ -34,17 +34,41 @@
 | 
				
			||||||
typedef uint32_t index_t;
 | 
					typedef uint32_t index_t;
 | 
				
			||||||
#define _GL_INDEX_TYPE GL_UNSIGNED_INT
 | 
					#define _GL_INDEX_TYPE GL_UNSIGNED_INT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ColorQuadArray
 | 
					/* A small hack to get mutable QuadArray constructors */
 | 
				
			||||||
 | 
					inline void initBufferBindings(Vertex *)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	std::vector<Vertex> vertices;
 | 
						glEnableVertexAttribArray(Shader::Color);
 | 
				
			||||||
 | 
						glEnableVertexAttribArray(Shader::Position);
 | 
				
			||||||
 | 
						glEnableVertexAttribArray(Shader::TexCoord);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						glVertexAttribPointer(Shader::Color,    4, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::colorOffset());
 | 
				
			||||||
 | 
						glVertexAttribPointer(Shader::Position, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::posOffset());
 | 
				
			||||||
 | 
						glVertexAttribPointer(Shader::TexCoord, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::texPosOffset());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline void initBufferBindings(SVertex *)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						glEnableVertexAttribArray(Shader::Position);
 | 
				
			||||||
 | 
						glEnableVertexAttribArray(Shader::TexCoord);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						glVertexAttribPointer(Shader::Position, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex), SVertex::posOffset());
 | 
				
			||||||
 | 
						glVertexAttribPointer(Shader::TexCoord, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex), SVertex::texPosOffset());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class VertexType>
 | 
				
			||||||
 | 
					struct QuadArray
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::vector<VertexType> vertices;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	VBO::ID vbo;
 | 
						VBO::ID vbo;
 | 
				
			||||||
	VAO::ID vao;
 | 
						VAO::ID vao;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int quadCount;
 | 
						int quadCount;
 | 
				
			||||||
 | 
						GLsizeiptr vboSize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ColorQuadArray()
 | 
						QuadArray()
 | 
				
			||||||
	    : quadCount(0)
 | 
						    : quadCount(0),
 | 
				
			||||||
 | 
						      vboSize(-1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		vbo = VBO::gen();
 | 
							vbo = VBO::gen();
 | 
				
			||||||
		vao = VAO::gen();
 | 
							vao = VAO::gen();
 | 
				
			||||||
| 
						 | 
					@ -53,20 +77,16 @@ struct ColorQuadArray
 | 
				
			||||||
		VBO::bind(vbo);
 | 
							VBO::bind(vbo);
 | 
				
			||||||
		shState->bindQuadIBO();
 | 
							shState->bindQuadIBO();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		glEnableVertexAttribArray(Shader::Color);
 | 
							/* Call correct implementation here via overloading */
 | 
				
			||||||
		glEnableVertexAttribArray(Shader::Position);
 | 
							VertexType *dummy = 0;
 | 
				
			||||||
		glEnableVertexAttribArray(Shader::TexCoord);
 | 
							initBufferBindings(dummy);
 | 
				
			||||||
 | 
					 | 
				
			||||||
		glVertexAttribPointer(Shader::Color,    4, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::colorOffset());
 | 
					 | 
				
			||||||
		glVertexAttribPointer(Shader::Position, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::posOffset());
 | 
					 | 
				
			||||||
		glVertexAttribPointer(Shader::TexCoord, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::texPosOffset());
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		VAO::unbind();
 | 
							VAO::unbind();
 | 
				
			||||||
		IBO::unbind();
 | 
							IBO::unbind();
 | 
				
			||||||
		VBO::unbind();
 | 
							VBO::unbind();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	~ColorQuadArray()
 | 
						~QuadArray()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		VBO::del(vbo);
 | 
							VBO::del(vbo);
 | 
				
			||||||
		VAO::del(vao);
 | 
							VAO::del(vao);
 | 
				
			||||||
| 
						 | 
					@ -78,15 +98,36 @@ struct ColorQuadArray
 | 
				
			||||||
		quadCount = size;
 | 
							quadCount = size;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void clear()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							vertices.clear();
 | 
				
			||||||
 | 
							quadCount = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* This needs to be called after the final 'append()' call
 | 
						/* This needs to be called after the final 'append()' call
 | 
				
			||||||
	 * and previous to the first 'draw()' call. */
 | 
						 * and previous to the first 'draw()' call. */
 | 
				
			||||||
	void commit()
 | 
						void commit()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		VBO::bind(vbo);
 | 
							VBO::bind(vbo);
 | 
				
			||||||
		VBO::uploadData(vertices.size() * sizeof(Vertex), &vertices[0], GL_DYNAMIC_DRAW);
 | 
					 | 
				
			||||||
		VBO::unbind();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		shState->ensureQuadIBO(quadCount);
 | 
							GLsizeiptr size = vertices.size() * sizeof(VertexType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (size > vboSize)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								/* New data exceeds already allocated size.
 | 
				
			||||||
 | 
								 * Reallocate VBO. */
 | 
				
			||||||
 | 
								VBO::uploadData(size, &vertices[0], GL_DYNAMIC_DRAW);
 | 
				
			||||||
 | 
								vboSize = size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								shState->ensureQuadIBO(quadCount);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								/* New data fits in allocated size */
 | 
				
			||||||
 | 
								VBO::uploadSubData(0, size, &vertices[0]);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							VBO::unbind();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void draw(size_t offset, size_t count)
 | 
						void draw(size_t offset, size_t count)
 | 
				
			||||||
| 
						 | 
					@ -110,67 +151,7 @@ struct ColorQuadArray
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct PointArray
 | 
					typedef QuadArray<Vertex> ColorQuadArray;
 | 
				
			||||||
{
 | 
					typedef QuadArray<SVertex> SimpleQuadArray;
 | 
				
			||||||
	std::vector<Vertex> vertices;
 | 
					 | 
				
			||||||
	VBO::ID vbo;
 | 
					 | 
				
			||||||
	VAO::ID vao;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	PointArray()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		vbo = VBO::gen();
 | 
					 | 
				
			||||||
		vao = VAO::gen();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		VAO::bind(vao);
 | 
					 | 
				
			||||||
		VBO::bind(vbo);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		glEnableVertexAttribArray(Shader::Color);
 | 
					 | 
				
			||||||
		glEnableVertexAttribArray(Shader::Position);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		glVertexAttribPointer(Shader::Color,    4, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::colorOffset());
 | 
					 | 
				
			||||||
		glVertexAttribPointer(Shader::Position, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), Vertex::posOffset());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		VAO::unbind();
 | 
					 | 
				
			||||||
		VBO::unbind();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	~PointArray()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		VBO::del(vbo);
 | 
					 | 
				
			||||||
		VAO::del(vao);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void append(const Vec2 &pos, const Vec4 &color)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		Vertex vert;
 | 
					 | 
				
			||||||
		vert.pos = pos;
 | 
					 | 
				
			||||||
		vert.color = color;
 | 
					 | 
				
			||||||
		vertices.push_back(vert);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void commit()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		VBO::bind(vbo);
 | 
					 | 
				
			||||||
		VBO::uploadData(vertices.size() * sizeof(Vertex), &vertices[0]);
 | 
					 | 
				
			||||||
		VBO::unbind();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void reset()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		vertices.clear();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void draw()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		VAO::bind(vao);
 | 
					 | 
				
			||||||
		glDrawArrays(GL_POINTS, 0, count());
 | 
					 | 
				
			||||||
		VAO::unbind();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int count()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return vertices.size();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // QUADARRAY_H
 | 
					#endif // QUADARRAY_H
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -99,13 +99,13 @@ Shader::~Shader()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Shader::bind()
 | 
					void Shader::bind()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	glUseProgram(program);
 | 
						glState.program.set(program);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Shader::unbind()
 | 
					void Shader::unbind()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	glActiveTexture(GL_TEXTURE0);
 | 
						glActiveTexture(GL_TEXTURE0);
 | 
				
			||||||
	glUseProgram(0);
 | 
						glState.program.set(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Shader::init(const unsigned char *vert, int vertSize,
 | 
					void Shader::init(const unsigned char *vert, int vertSize,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,8 +67,8 @@ struct SharedStatePrivate
 | 
				
			||||||
	ShaderSet shaders;
 | 
						ShaderSet shaders;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	TexPool texPool;
 | 
						TexPool texPool;
 | 
				
			||||||
	FontPool fontPool;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SharedFontState fontState;
 | 
				
			||||||
	Font *defaultFont;
 | 
						Font *defaultFont;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	TEX::ID globalTex;
 | 
						TEX::ID globalTex;
 | 
				
			||||||
| 
						 | 
					@ -90,6 +90,7 @@ struct SharedStatePrivate
 | 
				
			||||||
	      rtData(*threadData),
 | 
						      rtData(*threadData),
 | 
				
			||||||
	      config(threadData->config),
 | 
						      config(threadData->config),
 | 
				
			||||||
	      graphics(threadData),
 | 
						      graphics(threadData),
 | 
				
			||||||
 | 
						      fontState(threadData->config),
 | 
				
			||||||
	      stampCounter(0)
 | 
						      stampCounter(0)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (!config.gameFolder.empty())
 | 
							if (!config.gameFolder.empty())
 | 
				
			||||||
| 
						 | 
					@ -121,6 +122,8 @@ struct SharedStatePrivate
 | 
				
			||||||
		if (config.pathCache)
 | 
							if (config.pathCache)
 | 
				
			||||||
			fileSystem.createPathCache();
 | 
								fileSystem.createPathCache();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							fileSystem.initFontSets(fontState);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		globalTexW = 128;
 | 
							globalTexW = 128;
 | 
				
			||||||
		globalTexH = 64;
 | 
							globalTexH = 64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -206,8 +209,8 @@ GSATT(Audio&, audio)
 | 
				
			||||||
GSATT(GLState&, _glState)
 | 
					GSATT(GLState&, _glState)
 | 
				
			||||||
GSATT(ShaderSet&, shaders)
 | 
					GSATT(ShaderSet&, shaders)
 | 
				
			||||||
GSATT(TexPool&, texPool)
 | 
					GSATT(TexPool&, texPool)
 | 
				
			||||||
GSATT(FontPool&, fontPool)
 | 
					 | 
				
			||||||
GSATT(Quad&, gpQuad)
 | 
					GSATT(Quad&, gpQuad)
 | 
				
			||||||
 | 
					GSATT(SharedFontState&, fontState)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SharedState::setBindingData(void *data)
 | 
					void SharedState::setBindingData(void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,8 +43,8 @@ class Input;
 | 
				
			||||||
class Audio;
 | 
					class Audio;
 | 
				
			||||||
class GLState;
 | 
					class GLState;
 | 
				
			||||||
class TexPool;
 | 
					class TexPool;
 | 
				
			||||||
class FontPool;
 | 
					 | 
				
			||||||
class Font;
 | 
					class Font;
 | 
				
			||||||
 | 
					class SharedFontState;
 | 
				
			||||||
struct GlobalIBO;
 | 
					struct GlobalIBO;
 | 
				
			||||||
struct Config;
 | 
					struct Config;
 | 
				
			||||||
struct Vec2i;
 | 
					struct Vec2i;
 | 
				
			||||||
| 
						 | 
					@ -74,8 +74,8 @@ struct SharedState
 | 
				
			||||||
	ShaderSet &shaders();
 | 
						ShaderSet &shaders();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	TexPool &texPool();
 | 
						TexPool &texPool();
 | 
				
			||||||
	FontPool &fontPool();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SharedFontState &fontState();
 | 
				
			||||||
	Font &defaultFont();
 | 
						Font &defaultFont();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sigc::signal<void> prepareDraw;
 | 
						sigc::signal<void> prepareDraw;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										195
									
								
								src/sprite.cpp
									
										
									
									
									
								
							
							
						
						
									
										195
									
								
								src/sprite.cpp
									
										
									
									
									
								
							| 
						 | 
					@ -32,6 +32,9 @@
 | 
				
			||||||
#include "transform.h"
 | 
					#include "transform.h"
 | 
				
			||||||
#include "shader.h"
 | 
					#include "shader.h"
 | 
				
			||||||
#include "glstate.h"
 | 
					#include "glstate.h"
 | 
				
			||||||
 | 
					#include "quadarray.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <math.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <SDL_rect.h>
 | 
					#include <SDL_rect.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,6 +66,22 @@ struct SpritePrivate
 | 
				
			||||||
	Color *color;
 | 
						Color *color;
 | 
				
			||||||
	Tone *tone;
 | 
						Tone *tone;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef RGSS2
 | 
				
			||||||
 | 
						struct
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							int amp;
 | 
				
			||||||
 | 
							int length;
 | 
				
			||||||
 | 
							int speed;
 | 
				
			||||||
 | 
							float phase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Wave effect is active (amp != 0) */
 | 
				
			||||||
 | 
							bool active;
 | 
				
			||||||
 | 
							/* qArray needs updating */
 | 
				
			||||||
 | 
							bool dirty;
 | 
				
			||||||
 | 
							SimpleQuadArray qArray;
 | 
				
			||||||
 | 
						} wave;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	EtcTemps tmp;
 | 
						EtcTemps tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sigc::connection prepareCon;
 | 
						sigc::connection prepareCon;
 | 
				
			||||||
| 
						 | 
					@ -87,6 +106,13 @@ struct SpritePrivate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		prepareCon = shState->prepareDraw.connect
 | 
							prepareCon = shState->prepareDraw.connect
 | 
				
			||||||
		        (sigc::mem_fun(this, &SpritePrivate::prepare));
 | 
							        (sigc::mem_fun(this, &SpritePrivate::prepare));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef RGSS2
 | 
				
			||||||
 | 
							wave.amp = 0;
 | 
				
			||||||
 | 
							wave.length = 180;
 | 
				
			||||||
 | 
							wave.speed = 360;
 | 
				
			||||||
 | 
							wave.phase = 0.0;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	~SpritePrivate()
 | 
						~SpritePrivate()
 | 
				
			||||||
| 
						 | 
					@ -117,6 +143,10 @@ struct SpritePrivate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		quad.setPosRect(IntRect(0, 0, srcRect->width, srcRect->height));
 | 
							quad.setPosRect(IntRect(0, 0, srcRect->width, srcRect->height));
 | 
				
			||||||
		recomputeBushDepth();
 | 
							recomputeBushDepth();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef RGSS2
 | 
				
			||||||
 | 
							wave.dirty = true;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void updateSrcRectCon()
 | 
						void updateSrcRectCon()
 | 
				
			||||||
| 
						 | 
					@ -141,6 +171,16 @@ struct SpritePrivate
 | 
				
			||||||
		if (!opacity)
 | 
							if (!opacity)
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef RGSS2
 | 
				
			||||||
 | 
							if (wave.active)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								/* Don't do expensive wave bounding box
 | 
				
			||||||
 | 
								 * calculations */
 | 
				
			||||||
 | 
								isVisible = true;
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Compare sprite bounding box against the scene */
 | 
							/* Compare sprite bounding box against the scene */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* If sprite is zoomed/rotated, just opt out for now
 | 
							/* If sprite is zoomed/rotated, just opt out for now
 | 
				
			||||||
| 
						 | 
					@ -161,10 +201,101 @@ struct SpritePrivate
 | 
				
			||||||
		isVisible = SDL_HasIntersection(&self, &sceneRect);
 | 
							isVisible = SDL_HasIntersection(&self, &sceneRect);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef RGSS2
 | 
				
			||||||
 | 
						void emitWaveChunk(SVertex *&vert, float phase, int width,
 | 
				
			||||||
 | 
						                   float zoomY, int chunkY, int chunkLength)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							float wavePos = phase + (chunkY / (float) wave.length) * M_PI * 2;
 | 
				
			||||||
 | 
							float chunkX = sin(wavePos) * wave.amp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							FloatRect tex(0, chunkY / zoomY, width, chunkLength / zoomY);
 | 
				
			||||||
 | 
							FloatRect pos = tex;
 | 
				
			||||||
 | 
							pos.x = chunkX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Quad::setTexPosRect(vert, tex, pos);
 | 
				
			||||||
 | 
							vert += 4;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void updateWave()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (!bitmap)
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (wave.amp == 0)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								wave.active = false;
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							wave.active = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							int width = srcRect->width;
 | 
				
			||||||
 | 
							int height = srcRect->height;
 | 
				
			||||||
 | 
							float zoomY = trans.getScale().y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (wave.amp < -(width / 2))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								wave.qArray.resize(0);
 | 
				
			||||||
 | 
								wave.qArray.commit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* RMVX does this, and I have no fucking clue why */
 | 
				
			||||||
 | 
							if (wave.amp < 0)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								wave.qArray.resize(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								int x = -wave.amp;
 | 
				
			||||||
 | 
								int w = width - x * 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								FloatRect tex(x, srcRect->y, w, srcRect->height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Quad::setTexPosRect(&wave.qArray.vertices[0], tex, tex);
 | 
				
			||||||
 | 
								wave.qArray.commit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* The length of the sprite as it appears on screen */
 | 
				
			||||||
 | 
							int visibleLength = height * zoomY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* First chunk length (aligned to 8 pixel boundary */
 | 
				
			||||||
 | 
							int firstLength = ((int) trans.getPosition().y) % 8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Amount of full 8 pixel chunks in the middle */
 | 
				
			||||||
 | 
							int chunks = (visibleLength - firstLength) / 8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Final chunk length */
 | 
				
			||||||
 | 
							int lastLength = (visibleLength - firstLength) % 8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							wave.qArray.resize(!!firstLength + chunks + !!lastLength);
 | 
				
			||||||
 | 
							SVertex *vert = &wave.qArray.vertices[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							float phase = (wave.phase * M_PI) / 180.f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (firstLength > 0)
 | 
				
			||||||
 | 
								emitWaveChunk(vert, phase, width, zoomY, 0, firstLength);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (int i = 0; i < chunks; ++i)
 | 
				
			||||||
 | 
								emitWaveChunk(vert, phase, width, zoomY, firstLength + i * 8, 8);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (lastLength > 0)
 | 
				
			||||||
 | 
								emitWaveChunk(vert, phase, width, zoomY, firstLength + chunks * 8, lastLength);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							wave.qArray.commit();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void prepare()
 | 
						void prepare()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (bitmap)
 | 
					#ifdef RGSS2
 | 
				
			||||||
			bitmap->flush();
 | 
							if (wave.dirty)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								updateWave();
 | 
				
			||||||
 | 
								wave.dirty = false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		updateVisibility();
 | 
							updateVisibility();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -196,14 +327,21 @@ DEF_ATTR_RD_SIMPLE(Sprite, Angle,     float,   p->trans.getRotation())
 | 
				
			||||||
DEF_ATTR_RD_SIMPLE(Sprite, Mirror,    bool,    p->mirrored)
 | 
					DEF_ATTR_RD_SIMPLE(Sprite, Mirror,    bool,    p->mirrored)
 | 
				
			||||||
DEF_ATTR_RD_SIMPLE(Sprite, BushDepth, int,     p->bushDepth)
 | 
					DEF_ATTR_RD_SIMPLE(Sprite, BushDepth, int,     p->bushDepth)
 | 
				
			||||||
DEF_ATTR_RD_SIMPLE(Sprite, BlendType, int,     p->blendType)
 | 
					DEF_ATTR_RD_SIMPLE(Sprite, BlendType, int,     p->blendType)
 | 
				
			||||||
DEF_ATTR_RD_SIMPLE(Sprite, Width,     int,     p->srcRect->width)
 | 
					 | 
				
			||||||
DEF_ATTR_RD_SIMPLE(Sprite, Height,    int,     p->srcRect->height)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEF_ATTR_SIMPLE(Sprite, BushOpacity, int,    p->bushOpacity)
 | 
					DEF_ATTR_SIMPLE(Sprite, BushOpacity, int,    p->bushOpacity)
 | 
				
			||||||
DEF_ATTR_SIMPLE(Sprite, Opacity,     int,    p->opacity)
 | 
					DEF_ATTR_SIMPLE(Sprite, Opacity,     int,    p->opacity)
 | 
				
			||||||
DEF_ATTR_SIMPLE(Sprite, Color,       Color*, p->color)
 | 
					DEF_ATTR_SIMPLE(Sprite, Color,       Color*, p->color)
 | 
				
			||||||
DEF_ATTR_SIMPLE(Sprite, Tone,        Tone*,  p->tone)
 | 
					DEF_ATTR_SIMPLE(Sprite, Tone,        Tone*,  p->tone)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef RGSS2
 | 
				
			||||||
 | 
					DEF_ATTR_RD_SIMPLE(Sprite, Width,      int,   p->srcRect->width)
 | 
				
			||||||
 | 
					DEF_ATTR_RD_SIMPLE(Sprite, Height,     int,   p->srcRect->height)
 | 
				
			||||||
 | 
					DEF_ATTR_RD_SIMPLE(Sprite, WaveAmp,    int,   p->wave.amp)
 | 
				
			||||||
 | 
					DEF_ATTR_RD_SIMPLE(Sprite, WaveLength, int,   p->wave.length)
 | 
				
			||||||
 | 
					DEF_ATTR_RD_SIMPLE(Sprite, WaveSpeed,  int,   p->wave.speed)
 | 
				
			||||||
 | 
					DEF_ATTR_RD_SIMPLE(Sprite, WavePhase,  float, p->wave.phase)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Sprite::setBitmap(Bitmap *bitmap)
 | 
					void Sprite::setBitmap(Bitmap *bitmap)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	GUARD_DISPOSED
 | 
						GUARD_DISPOSED
 | 
				
			||||||
| 
						 | 
					@ -221,6 +359,10 @@ void Sprite::setBitmap(Bitmap *bitmap)
 | 
				
			||||||
	*p->srcRect = bitmap->rect();
 | 
						*p->srcRect = bitmap->rect();
 | 
				
			||||||
	p->onSrcRectChange();
 | 
						p->onSrcRectChange();
 | 
				
			||||||
	p->quad.setPosRect(p->srcRect->toFloatRect());
 | 
						p->quad.setPosRect(p->srcRect->toFloatRect());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef RGSS2
 | 
				
			||||||
 | 
						p->wave.dirty = true;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Sprite::setSrcRect(Rect *rect)
 | 
					void Sprite::setSrcRect(Rect *rect)
 | 
				
			||||||
| 
						 | 
					@ -255,6 +397,10 @@ void Sprite::setY(int value)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p->trans.setPosition(Vec2(getX(), value));
 | 
						p->trans.setPosition(Vec2(getX(), value));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef RGSS2
 | 
				
			||||||
 | 
						p->wave.dirty = true;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Sprite::setOX(int value)
 | 
					void Sprite::setOX(int value)
 | 
				
			||||||
| 
						 | 
					@ -296,6 +442,10 @@ void Sprite::setZoomY(float value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p->trans.setScale(Vec2(getZoomX(), value));
 | 
						p->trans.setScale(Vec2(getZoomX(), value));
 | 
				
			||||||
	p->recomputeBushDepth();
 | 
						p->recomputeBushDepth();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef RGSS2
 | 
				
			||||||
 | 
						p->wave.dirty = true;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Sprite::setAngle(float value)
 | 
					void Sprite::setAngle(float value)
 | 
				
			||||||
| 
						 | 
					@ -349,6 +499,36 @@ void Sprite::setBlendType(int type)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef RGSS2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DEF_WAVE_SETTER(Name, name, type) \
 | 
				
			||||||
 | 
						void Sprite::setWave##Name(type value) \
 | 
				
			||||||
 | 
						{ \
 | 
				
			||||||
 | 
							GUARD_DISPOSED; \
 | 
				
			||||||
 | 
							if (p->wave.name == value) \
 | 
				
			||||||
 | 
								return; \
 | 
				
			||||||
 | 
							p->wave.name = value; \
 | 
				
			||||||
 | 
							p->wave.dirty = true; \
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEF_WAVE_SETTER(Amp,    amp,    int)
 | 
				
			||||||
 | 
					DEF_WAVE_SETTER(Length, length, int)
 | 
				
			||||||
 | 
					DEF_WAVE_SETTER(Speed,  speed,  int)
 | 
				
			||||||
 | 
					DEF_WAVE_SETTER(Phase,  phase,  float)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef DEF_WAVE_SETTER
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Flashable */
 | 
				
			||||||
 | 
					void Sprite::update()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Flashable::update();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p->wave.phase += p->wave.speed / 180;
 | 
				
			||||||
 | 
						p->wave.dirty = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Disposable */
 | 
					/* Disposable */
 | 
				
			||||||
void Sprite::releaseResources()
 | 
					void Sprite::releaseResources()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -410,7 +590,14 @@ void Sprite::draw()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p->bitmap->bindTex(*base);
 | 
						p->bitmap->bindTex(*base);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef RGSS2
 | 
				
			||||||
 | 
						if (p->wave.active)
 | 
				
			||||||
 | 
							p->wave.qArray.draw();
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							p->quad.draw();
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
	p->quad.draw();
 | 
						p->quad.draw();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	glState.blendMode.pop();
 | 
						glState.blendMode.pop();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										15
									
								
								src/sprite.h
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								src/sprite.h
									
										
									
									
									
								
							| 
						 | 
					@ -41,9 +41,6 @@ public:
 | 
				
			||||||
	Sprite(Viewport *viewport = 0);
 | 
						Sprite(Viewport *viewport = 0);
 | 
				
			||||||
	~Sprite();
 | 
						~Sprite();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int getWidth()  const;
 | 
					 | 
				
			||||||
	int getHeight() const;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	DECL_ATTR( Bitmap,      Bitmap* )
 | 
						DECL_ATTR( Bitmap,      Bitmap* )
 | 
				
			||||||
	DECL_ATTR( SrcRect,     Rect*   )
 | 
						DECL_ATTR( SrcRect,     Rect*   )
 | 
				
			||||||
	DECL_ATTR( X,           int     )
 | 
						DECL_ATTR( X,           int     )
 | 
				
			||||||
| 
						 | 
					@ -61,6 +58,18 @@ public:
 | 
				
			||||||
	DECL_ATTR( Color,       Color*  )
 | 
						DECL_ATTR( Color,       Color*  )
 | 
				
			||||||
	DECL_ATTR( Tone,        Tone*   )
 | 
						DECL_ATTR( Tone,        Tone*   )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef RGSS2
 | 
				
			||||||
 | 
						int getWidth()  const;
 | 
				
			||||||
 | 
						int getHeight() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DECL_ATTR( WaveAmp,    int   )
 | 
				
			||||||
 | 
						DECL_ATTR( WaveLength, int   )
 | 
				
			||||||
 | 
						DECL_ATTR( WaveSpeed,  int   )
 | 
				
			||||||
 | 
						DECL_ATTR( WavePhase,  float )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void update();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	SpritePrivate *p;
 | 
						SpritePrivate *p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,8 +21,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "tileatlas.h"
 | 
					#include "tileatlas.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <list>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace TileAtlas
 | 
					namespace TileAtlas
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,8 +35,7 @@ struct Column
 | 
				
			||||||
	{}
 | 
						{}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// FIXME: this can be optimized to a vector
 | 
					typedef std::vector<Column> ColumnVec;
 | 
				
			||||||
typedef std::list<Column> ColumnList;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Autotile area width */
 | 
					/* Autotile area width */
 | 
				
			||||||
static const int atAreaW = 96*4;
 | 
					static const int atAreaW = 96*4;
 | 
				
			||||||
| 
						 | 
					@ -79,9 +76,10 @@ Vec2i minSize(int tilesetH, int maxAtlasSize)
 | 
				
			||||||
	return Vec2i(-1, -1);
 | 
						return Vec2i(-1, -1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ColumnList calcSrcCols(int tilesetH)
 | 
					static ColumnVec calcSrcCols(int tilesetH)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	ColumnList cols;
 | 
						ColumnVec cols;
 | 
				
			||||||
 | 
						cols.reserve(2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cols.push_back(Column(0, 0, tilesetH));
 | 
						cols.push_back(Column(0, 0, tilesetH));
 | 
				
			||||||
	cols.push_back(Column(tsLaneW, 0, tilesetH));
 | 
						cols.push_back(Column(tsLaneW, 0, tilesetH));
 | 
				
			||||||
| 
						 | 
					@ -89,9 +87,10 @@ static ColumnList calcSrcCols(int tilesetH)
 | 
				
			||||||
	return cols;
 | 
						return cols;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ColumnList calcDstCols(int atlasW, int atlasH)
 | 
					static ColumnVec calcDstCols(int atlasW, int atlasH)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	ColumnList cols;
 | 
						ColumnVec cols;
 | 
				
			||||||
 | 
						cols.reserve(3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Columns below the autotile area */
 | 
						/* Columns below the autotile area */
 | 
				
			||||||
	const int underAt = atlasH - atAreaH;
 | 
						const int underAt = atlasH - atAreaH;
 | 
				
			||||||
| 
						 | 
					@ -110,19 +109,21 @@ static ColumnList calcDstCols(int atlasW, int atlasH)
 | 
				
			||||||
	return cols;
 | 
						return cols;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static BlitList calcBlitsInt(ColumnList &srcCols, ColumnList &dstCols)
 | 
					static BlitVec calcBlitsInt(ColumnVec &srcCols, ColumnVec &dstCols)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	BlitList blits;
 | 
						BlitVec blits;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (!srcCols.empty())
 | 
						/* Using signed indices here is safer, as we
 | 
				
			||||||
 | 
						 * might decrement dstI while it is zero. */
 | 
				
			||||||
 | 
						int dstI = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (size_t srcI = 0; srcI < srcCols.size(); ++srcI)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Column srcCol = srcCols.front();
 | 
							Column &srcCol = srcCols[srcI];
 | 
				
			||||||
		srcCols.pop_front();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		while (!dstCols.empty() && srcCol.h > 0)
 | 
							for (; dstI < (int) dstCols.size() && srcCol.h > 0; ++dstI)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Column dstCol = dstCols.front();
 | 
								Column &dstCol = dstCols[dstI];
 | 
				
			||||||
			dstCols.pop_front();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (srcCol.h > dstCol.h)
 | 
								if (srcCol.h > dstCol.h)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
| 
						 | 
					@ -141,7 +142,10 @@ static BlitList calcBlitsInt(ColumnList &srcCols, ColumnList &dstCols)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				dstCol.y += srcCol.h;
 | 
									dstCol.y += srcCol.h;
 | 
				
			||||||
				dstCol.h -= srcCol.h;
 | 
									dstCol.h -= srcCol.h;
 | 
				
			||||||
				dstCols.push_front(dstCol);
 | 
					
 | 
				
			||||||
 | 
									/* Queue this column up again for processing */
 | 
				
			||||||
 | 
									--dstI;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				srcCol.h = 0;
 | 
									srcCol.h = 0;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
| 
						 | 
					@ -156,10 +160,10 @@ static BlitList calcBlitsInt(ColumnList &srcCols, ColumnList &dstCols)
 | 
				
			||||||
	return blits;
 | 
						return blits;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
BlitList calcBlits(int tilesetH, const Vec2i &atlasSize)
 | 
					BlitVec calcBlits(int tilesetH, const Vec2i &atlasSize)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	ColumnList srcCols = calcSrcCols(tilesetH);
 | 
						ColumnVec srcCols = calcSrcCols(tilesetH);
 | 
				
			||||||
	ColumnList dstCols = calcDstCols(atlasSize.x, atlasSize.y);
 | 
						ColumnVec dstCols = calcDstCols(atlasSize.x, atlasSize.y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return calcBlitsInt(srcCols, dstCols);
 | 
						return calcBlitsInt(srcCols, dstCols);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,16 +46,17 @@ struct Blit
 | 
				
			||||||
	{}
 | 
						{}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef std::vector<Blit> BlitList;
 | 
					typedef std::vector<Blit> BlitVec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Calculates the minimum atlas size required to hold
 | 
					/* Calculates the minimum atlas size required to hold
 | 
				
			||||||
 * a tileset of height 'tilesetH'. If the required dimensions
 | 
					 * a tileset of height 'tilesetH'. If the required dimensions
 | 
				
			||||||
 * exceed 'maxAtlasSize', Vec2i(-1, -1) is returned. */
 | 
					 * exceed 'maxAtlasSize', Vec2i(-1, -1) is returned. */
 | 
				
			||||||
Vec2i minSize(int tilesetH, int maxAtlasSize);
 | 
					Vec2i minSize(int tilesetH, int maxAtlasSize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Calculates a series of blits necessary to fill dstRows
 | 
					/* Calculates a series of blits necessary to fill an atlas
 | 
				
			||||||
 * with srcRows without wasting any space */
 | 
					 * of size 'atlasSize' with a tileset of height 'tilesetH'.
 | 
				
			||||||
BlitList calcBlits(int tilesetH, const Vec2i &atlasSize);
 | 
					 * Usually fed results from 'minSize()'. */
 | 
				
			||||||
 | 
					BlitVec calcBlits(int tilesetH, const Vec2i &atlasSize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Translates a tile coordinate (not pixel!) to a physical
 | 
					/* Translates a tile coordinate (not pixel!) to a physical
 | 
				
			||||||
 * pixel coordinate in the atlas */
 | 
					 * pixel coordinate in the atlas */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,13 +48,6 @@ extern const StaticRect autotileRects[];
 | 
				
			||||||
typedef std::vector<SVertex> SVVector;
 | 
					typedef std::vector<SVertex> SVVector;
 | 
				
			||||||
typedef struct { SVVector v[4]; } TileVBuffer;
 | 
					typedef struct { SVVector v[4]; } TileVBuffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Check if [C]ontainer contains [V]alue */
 | 
					 | 
				
			||||||
template<typename C, typename V>
 | 
					 | 
				
			||||||
inline bool contains(const C &c, const V &v)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return std::find(c.begin(), c.end(), v) != c.end();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const int tilesetW  = 8 * 32;
 | 
					static const int tilesetW  = 8 * 32;
 | 
				
			||||||
static const int autotileW = 3 * 32;
 | 
					static const int autotileW = 3 * 32;
 | 
				
			||||||
static const int autotileH = 4 * 32;
 | 
					static const int autotileH = 4 * 32;
 | 
				
			||||||
| 
						 | 
					@ -511,8 +504,6 @@ struct TilemapPrivate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			usableATs.push_back(i);
 | 
								usableATs.push_back(i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			autotiles[i]->flush();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (autotiles[i]->width() > autotileW)
 | 
								if (autotiles[i]->width() > autotileW)
 | 
				
			||||||
				animatedATs.push_back(i);
 | 
									animatedATs.push_back(i);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -623,14 +614,9 @@ struct TilemapPrivate
 | 
				
			||||||
	/* Assembles atlas from tileset and autotile bitmaps */
 | 
						/* Assembles atlas from tileset and autotile bitmaps */
 | 
				
			||||||
	void buildAtlas()
 | 
						void buildAtlas()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		tileset->flush();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		updateAutotileInfo();
 | 
							updateAutotileInfo();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (size_t i = 0; i < atlas.usableATs.size(); ++i)
 | 
							TileAtlas::BlitVec blits = TileAtlas::calcBlits(atlas.efTilesetH, atlas.size);
 | 
				
			||||||
			autotiles[atlas.usableATs[i]]->flush();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		TileAtlas::BlitList blits = TileAtlas::calcBlits(atlas.efTilesetH, atlas.size);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Clear atlas */
 | 
							/* Clear atlas */
 | 
				
			||||||
		FBO::bind(atlas.gl.fbo, FBO::Draw);
 | 
							FBO::bind(atlas.gl.fbo, FBO::Draw);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,6 +24,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <algorithm>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int
 | 
					static inline int
 | 
				
			||||||
wrapRange(int value, int min, int max)
 | 
					wrapRange(int value, int min, int max)
 | 
				
			||||||
| 
						 | 
					@ -93,6 +94,13 @@ inline void strReplace(std::string &str,
 | 
				
			||||||
			str[i] = after;
 | 
								str[i] = after;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Check if [C]ontainer contains [V]alue */
 | 
				
			||||||
 | 
					template<typename C, typename V>
 | 
				
			||||||
 | 
					inline bool contains(const C &c, const V &v)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return std::find(c.begin(), c.end(), v) != c.end();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ARRAY_SIZE(obj) (sizeof(obj) / sizeof((obj)[0]))
 | 
					#define ARRAY_SIZE(obj) (sizeof(obj) / sizeof((obj)[0]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define elementsN(obj) const int obj##N = ARRAY_SIZE(obj)
 | 
					#define elementsN(obj) const int obj##N = ARRAY_SIZE(obj)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -508,12 +508,6 @@ struct WindowPrivate
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		bool updateBaseQuadArray = false;
 | 
							bool updateBaseQuadArray = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (windowskin)
 | 
					 | 
				
			||||||
			windowskin->flush();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (contents)
 | 
					 | 
				
			||||||
			contents->flush();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (baseVertDirty)
 | 
							if (baseVertDirty)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			buildBaseVert();
 | 
								buildBaseVert();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue