Jump to content

  • Log In with Google      Sign In   
  • Create Account

Andreas Jonsson

Member Since 26 Mar 2000
Offline Last Active Yesterday, 11:09 AM

#5252703 *.fnt files and Game Maker Studio

Posted by Andreas Jonsson on 17 September 2015 - 12:04 PM

xadvance is how much the cursor should be advanced after rendering the character before rendering the next character. It is unrelated to the xoffset, x and width values. Note, that kerning pairs alter this value for specific combinations of characters as determined by the font designer.


xoffset and yoffset are the offsets from the current position where the character quad should be rendered. xoffset is usually near 0, unless the character is designed to have an overlap with previous character (negative xoffset) or have extra spacing between previous character (positive xoffset). As yoffset is the distance from the top of the line to the top of the quad, it will have a higher value for smaller characters, e.g. capital A (id 65) has a small yoffset, and small a (id 97) has a larger yoffset, underline _ (id 95) has an even larger yoffset.


width and height give the size of the quad that should be rendered.


x and y show the position in the texture where the character should be copied from when rendering it.




I'm not sure what format and layout that Game Maker requires for its bitmap fonts, so I can't say what you need to do to transform the BMFont format into the Game Maker format.


I think you would benefit from taking a look at how fonts are actually rendered directly from the BMFont format. Take a look at the various tutorials and resouces that I link to from my site. Hopefully by seeing the code it will be easier for you to figure what needs to be done to transform the format.

#5252593 *.fnt files and Game Maker Studio

Posted by Andreas Jonsson on 16 September 2015 - 08:37 PM

I didn't even know of the Littera web app, much less that it exported fonts in the same format that I came up with for BMFont long back. biggrin.png


I'll gladly link to your project for converting the png+fnt BMFont format into the Game Maker format from my site. I'm sure others will be interested in using it too.

#5250697 How is cast<T>() registered?

Posted by Andreas Jonsson on 05 September 2015 - 10:22 AM

cast<T>() is not registered. This is a built-in function, and serves the same purpose as dynamic_cast<T>() in C++.


You can implement the opImplConv overload in the typeof<T>() class to allow it to be implicitly converted to the Type object.


You may want to take a look at this post. cvet has already implemented and shared code that does exactly what you want.

#5250338 Would this be misuse of aslScriptContext::Suspend()?

Posted by Andreas Jonsson on 02 September 2015 - 04:48 PM

A) This is a perfectly valid use case. Using this script engine like this can be thought of a form of coroutine. Just remember that it is currently not possible to serialize a context's state, so if you plan on allowing the user to save the game in the middle of a playthrough with coroutines still running you'll face trouble.


B) You'll probably be fine with 50 something contexts. Expect each context to take up a few KB of memory. If you're targeting platforms with limited amount of memory you can tweak the amount of memory that is allocated for the callstack in the contexts by setting the engine property asEP_MAX_STACK_SIZE.


C) Take a look at the code for the ExecuteString helper function. It is a good place to start, but you'll likely want to make some adaptions to suite your own specific needs. For example, resuming the context after it has been suspended. By default the function doesn't support resuming, since it discards the script code before returning.


D) Yes, PushState/PopState can be used to call the different script. Though, obviously you cannot resume the original script before the called script finishes if you do.




#5250195 Implicit parameter to factory function?

Posted by Andreas Jonsson on 01 September 2015 - 06:45 PM

You could implement the factory function for the object as a functor, and register it with the calling convention asCALL_THISCALL_ASGLOBAL. The functor object can then hold the value that you wish to pass to the object constructor.


class MyFunctor
Object *Factory() { return new Object(value); };
int value;
MyFunctor *factoryFunctor = new MyFunctor;
factoryFunctor->value = 42; // change this whenever you want a different value for the Object constructor
engine->RegisterObjectBehaviour("Object", asBEHAVE_FACTORY, "Object @f()", asMETHOD(MyFunctor, Factory), asCALL_THISCALL_ASGLOBAL, factoryFunctor);

#5249739 AngelScript 2.30.2 is out

Posted by Andreas Jonsson on 30 August 2015 - 12:07 PM

With this version I've spent most of the time on optimizations. Specifically the time for loading pre-compiled byte code has improved significantly for applications that exposes a large interface to the scripts. There are some run-time optimizations too, but those are probably only noticeable in very specific cases.


Besides the optimizations I've implemented support for anonymous functions, a.k.a. lambdas, in the script language. The anonymous functions are so far just global functions declared locally in the expression that needs them, but I'll continue to expand on the usefulness of them for future releases.




#5249721 Lots of the same warnings when compiling under VS 2015

Posted by Andreas Jonsson on 30 August 2015 - 10:49 AM

Looks like Microsoft has added new warnings in the latest version of the compiler. 


It's nothing to worry about for now, but I'll take care of them once I upgrade to MSVC2015 myself (I'm still using MSVC2012). 




#5249094 Error when saving bytecode on x64

Posted by Andreas Jonsson on 26 August 2015 - 07:56 PM

I've fixed this bug in revision 2215.


Thanks for making it easy for me to reproduce the problem.

#5248657 AngelScript class property with indirection

Posted by Andreas Jonsson on 24 August 2015 - 07:09 PM

I downloaded the source code and reviewed the code. 


These are the problems I found:


  1. You're using version 2.30.0 WIP. Upgrade to 2.30.1 to get the support for registering the position member as a &. (while you're at it you might as well upgrade to 2.30.2 WIP to get the very latest code).
  2. You're registering the value types Transform, Vector3, etc with the flag asOBJ_ASHANDLE. This what is causing the problem you're facing.


I understand you came to the conclusion that you needed asOBJ_ASHANDLE because your members are pointers, but this is not what asOBJ_ASHANDLE is meant for. This flag has a very specific use case, which is to build a container class that should function as a handle. You can see its use in the ScriptHandle add-on.




Upgrade the library, change the code to remove the asOBJ_ASHANDLE in RegisterType<T>, and then change to register the Transform::position as:


r = engine->RegisterObjectProperty("Transform", "Vector3 &position", asOFFSET(Transform, position));




Doing this should make your code work as you want.

#5248426 AngelScript class property with indirection

Posted by Andreas Jonsson on 23 August 2015 - 04:35 PM

I don't see any immediate error in the code that you have shared so far.


As far as I can tell, it should work as you want it.


Perhaps you can show how you're calling the script's Update method. It might be that the problem is there.

#5248388 AngelScript class property with indirection

Posted by Andreas Jonsson on 23 August 2015 - 12:34 PM

Are you getting any errors when executing the script? Is asIScriptContext::Execute returning asEXECUTION_FINISHED or something else?


Why is the Transform::position registered as a handle (@) when Transform::rotation and Transform::scalling aren't? Is the Transform class allocating the position member in the constructor?


I suggest you debug your code to make sure the script is actually having the correct reference to the Transform object in the Actor class. 

#5243305 AngelScript WIP - anonymous functions

Posted by Andreas Jonsson on 28 July 2015 - 07:04 PM

I've added support for anonymous functions in the latest revision (2202) of the AngelScript WIP.


The syntax for using anonymous functions look like this:


void main()
   // Passing an anonymous function to a function expecting a function pointer
   DoSomethingWithACallback(function(a,b) {return a+b});
   // Store a pointer to an anonymous function for later use
   callback @cb = function(a,b) {return a*b;}
// The anonymous function will take on the signature that is expected by the target
funcdef int callback(int, int);
int DoSomethingACallback(callback @cb)
   return cb(1, 2);


Let me know your thoughts, and if you find any problem with this new feature please let me know so I can have it fixed before I make the official release.


Observe, the anonymous functions cannot be used as closures yet. That will have to wait for future time (if ever) as it would require a lot more changes in the compiler.







#5243241 Possible dictionary optimization

Posted by Andreas Jonsson on 28 July 2015 - 01:40 PM

Thanks for letting me know about this.


There is no specific reason for not using the shorter code that you propose. It is just that I never thought about using the operator[] on the std::map container. I never had a reason to look for a shorter implementation as the current one was good enough for me.


That's one of the things I love about C++. No matter how many years of experience you have, there is always something new to learn. biggrin.png



I'll make the changes. Not for the potential performance improvement, but for the sake of cleaner code.



BTW. It's quite useless to do performance comparisons in debug mode. Performance comparisons should always be done in release mode to get as close to the actual code you would use in a released project as possible. Comparing performance of two algorithms in debug mode can easily make you chose to worse of the two, especially when considering cache management, branch-prediction, and multicore features in current day CPUs. In debug mode many of these features are all but eliminated due to all the extra checks that the debug code executes to check the sanity of the code.


I've personally seen cases where algorithms that 'should' be faster due to doing less work, actually becomes a lot slower due to causing more cache-misses or incorrect branch-predictions.


What's worse is that different CPU families/brands behave differently. So never trust numbers you get from only a single machine.

#5241788 About using old objects after recompiling scripts

Posted by Andreas Jonsson on 21 July 2015 - 04:09 PM

AngelScript uses magic to make it work. :)



Discarding a module doesn't immediately remove the module if there are still live objects or other external references to the module. It will be kept in memory until all those references are released in order to avoid dangling pointers, or other lose ends that may cause crashes in the application.


However, this also means that the re-compiled script doesn't share anything with the previous script (unless the script entities have been explicitly declared as shared). Global variables, object types, etc will be distinct for each compilation.

#5238285 AngelScript 2.30.1 is out

Posted by Andreas Jonsson on 03 July 2015 - 07:24 PM

In this new version I had the fortune to get my hands on a MIPS Creator CI20 board, thanks to Alexandru Voica from Imagination Technologies, so I spent some time on adding support for native calling conventions for MIPS processors on Linux and Android.


Adding support for the native calling conventions on Linux was easy enough, since I had already done similar work with ARM, and AngelScript already had support for MIPS on PSP. The ABI used by Linux (MIPS O32) is different than what is used by PSP (MIPS N32) so I still had to do a fair bit of reverse engineering of the ABI by reading assembler code and figure out how values are passed in and out of functions, but the original implementation by Manu Evans for PSP back in 2006 still helped a lot.


The Android support took more time. Not because of the ABI itself, which turned out to be identical to Linux, but because I had never worked with Android myself before. But, I decided it was time to sit down and learn the tools, so I went ahead and installed Android Studio, and Android NDK. It took some time to figure out how it works, but I managed to get the regression test suite to compile and upload it to the CI20. I didn't manage to figure out how to debug the native code on Android, but luckily I didn't have to as the ABI worked perfectly so it was mostly a matter of figuring out how to setup the configurations in as_config.h.


It's been fun learning about Android. I'm still a newbie in this world, but perhaps sometime in the future I'll start writing apps for Android too.


Of course, support for native calling conventions on MIPS is not the only improvement with this version. I've made some optimizations, especially scripts that do a lot of array access operations should hopefully notice a boost in performance. Loading pre-compiled byte-code should also be a lot faster, especially on mobile devices that don't have so much raw computing power.


dkrusu contributed a small language enhancement: for-loops can now have multiple increment expressions separated by commas.


Other than that, there is the usual load of bug fixes and minor improvements throughout. Refer to the changelist for the details.