Torque 2D – Image Maps
Introduction
This document is intended to give you a complete overview of Torque 2D's (T2D) Image-Map system from what Image-Maps are to how they are typically used so without delay, let's begin.
One of the big hurdles when developing any product is managing resources and there are few types of resources more troublesome than images. Not only do images occupy lots of disk space and memory but they are typically numerous. Add to this that there are performance issues related to the way images are stored/accessed and that these images have various runtime options associated with them and the situation can get quite complex.
Here's where T2D provides a helping hand; introducing the 't2dImageMapDatablock'. As the name implies, the 't2dImageMapDatablock' is a type of datablock hereto referred to as an Image-Map.
The first question here is naturally, "what is a datablock?" and although a full discussion of the capabilities of datablocks is beyond this document, it's worth providing a very quick overview.
Datablocks are specialized objects that provide a portable/reusable container for common and typically-static 'data'. Data here could refer to characteristics of an enemy's movement, the look/feel of GUI elements or more importantly for this document, definition of your imagery.
An example of a datablock would be one that defines the properties of an enemy so that whenever an enemy is created, it takes its start-up properties from the datablock. By changing the datablock definition, you can globally change the behavior of your enemies.
Typically, datablocks do not change at runtime but there is absolutely nothing to stop you doing this. Some things can be changed dynamically, some can't.
The great thing about datablocks is that they have their own keyword within the Torque-Script language call "datablock" in the same sense that a function has, err … well, "function" but we'll get into the details of configuring datablocks shortly.
The most important way to think about datablocks are that they are objects that allow you to group logical, common data for groups of objects to use allowing you to make broad changes to any aspect of your game whether that be the look/feel or even the behaviors of game elements such as enemies or weapons.
Well this is all rather vague so let's get into something more practical; let's start defining some real datablocks and see how they work.
Frame Configuration
So now we've provided a basic idea of what a datablock is, let's breakdown what exactly Image-Maps allow you to do. The idea here is to specify an image, how the frames within this image are organized and to provide various runtime options. The basic format for an Image-Map is:
|
datablock t2dImageMapDatablock( myImageMap ) { }; |
Note that you define a datablock by using the keyword "datablock" followed by the type of datablock you want to define. In this case, it's a 't2dImageMapDatablock', a type which we simply call "Image-Maps". The final part of the definition is the name, here we're calling it "myImageMap" but you would probably call it something more related to its usage, perhaps "playerShip" or "bigFont".
Now that we've got the basic definition of Image-Maps, let's start populating the datablock with useful information. We do this by adding a datablock "field" to the standard datablock definition. A field has the following format:
|
datablock t2dImageMapDatablock( myImageMap ) { myField = "foobar"; }; |
The above example isn't that useful but what it does do is create a field called "myField" and assigns it the string "foobar". To access this field we'd use something like:
|
echo( myImageMap.myField ); |
This shouldn't be difficult to understand as this dynamic-field creation is just an extension of standard torque-script you've probably already been using. So now that we know we can put our own custom-fields into our datablocks, let's look at the very important predefined ones that drive Image-Maps:
“imageName” - Source Imagery
“imageMode” - Previously called the ambiguous "mode"
“frameCount” - Optional; specifies the expected frame-count.
“cellCountX” - CELL mode only; 'horizontal' span of cells.
“cellCountY” - CELL mode only; 'vertical' span of cells.
“cellWidth” - CELL mode only; size of 'horizontal' cells.
“cellHeight” - CELL mode only; size of 'vertical' cells.
“cellOffsetX” – CELL mode only; ‘horizontal’ pixel-offset to start of tile capture.
“cellOffsetY” – CELL mode only; ‘vertical; pixel-offset to start of tile capture.
“cellStrideX” - CELL mode only; ‘horizontal’ pixel-stride during tile capture.
“cellStrideY” - CELL mode only; ‘vertical’ pixel-stride during tile capture.
“cellRowOrder” - CELL mode only; Specifies if row-order is used during tile capture.
“linkImageMaps” – LINK mode only; Specifies the list of image-maps to link together.
“filterMode” - Rendering control of the GPU filter mode.
“filterPad” - GPU filtering artifact fix.
“preferPerf” – Prefer Performance over least-waste.
“preload” – Preload Textures when created. Texture(s) are always active!
“allowUnload” – Specifies whether the texture(s) can unload.
This list of fields may at first seem daunting but bear in mind that most of the time you’ll only uses a couple of them, a handful are for more advanced control of image-maps only. Okay, let's go through each of these fields and expose how indeed, Image-Maps do provide plenty of flexibility in getting your artwork into T2D.
“imageName”
This field defines where the source image is located on the disk. An important thing to note here is the use of the term "image". When we say "image", we are referring to a bitmap on the disk that contains imagery. Now although this sounds like an overstatement, it's important in understanding what a "frame" is. Quite often, developers use a single "image" that contains multiple "frames".
Here's an example of a typical image from the SDK that contains multiple frames:
As you can see, this single image contains four separate frames. The image size is 256 wide by 256 high but each frame is 128 wide by 128 high. We'll use this image for some examples so you may want to note these dimensions so that as we discuss frames you'll have the dimensions to hand.
Multiple frames are great but why would we make it so complicated by combining frames when we could've easily created four separate images? Well, the answer is essentially simple but hides complex inner workings of your graphics-card. The combining of frames into a single image reduces not only the overhead of storing potentially hundreds of separate files but also loading/interpreting them. A more complex reason is due to the way that graphics hardware works (see technical note at the end of this "imageName" section).
So let's specify the image above in our example image-map:
|
datablock t2dImageMapDatablock( myImageMap ) { imageName = "t2d/data/images/tileMap"; }; |
Here we've told T2D that we've got a bitmap located in the directory "t2d/data/images/" and its name is "tileMap". We’ve highlighted this field in bold to indicate that you must always specify this field in an image-map. Some fields are optional and we’ll not highlighted those. Note also that we purposely omitted the files' extension as T2D will attempt to load the different formats that it supports automatically, in a specific order as follows:
|
|
24/32-Bit Images (Typical) |
8-Bit (Palletized) Images |
|
1st |
*.jpg |
*.bm8 |
|
2nd |
*.png |
*.bmp |
|
3rd |
*.gif |
*.jpg |
|
4th |
*.bmp |
*.png |
|
5th |
- |
*.jpg |
|
Non-palletized 24-bit images can get their alpha-layer automatically loaded from a separate ".jpg" file if it is alongside the specified one and it contains a suffix of ".alpha.jpg" |
|
***TECHNICAL NOTE *** When T2D uploads your imagery into the graphics card, it attempts to place them into the same graphics object called a "texture". Current graphics cards have limitations on the dimensions of these texture objects. Older cards can only handle 256 wide by 256 high textures whereas more modern cards can handle up to 4096 by 4096. There's also a limitation (on some cards) that the dimensions of these texture-objects have to be a power-of-two in size e.g. 2,4,8,16,32,64,128,256,1024,2048,4096 etc. Another complexity is that when T2D is rendering your sprites, it needs to tell the graphics card which texture it requires and the graphics-card selects the appropriate texture accordingly. This is no problem until T2D is selecting frame after frame which all reside on different textures. Because the graphics-card can only select one texture-object at a time, this can lead to the graphics-card swapping between different texture-objects continuously. This is commonly called "texture thrashing" and generally reduces performance, sometimes quite considerably. T2D objects such as the t2dTileLayer can cause this as it renders lots of tiles (therefore frames) during a single screen-update. There are a couple of ways counteracting this problem; rendering the objects in a specific order so that all objects that use the same image are rendered together or alternatively, try to keep as many frames in as few textures as possible. Also, grouping similar frames into the same texture can be of benefit. The good news is that T2D has an intelligent packing routine that will take the frames from your bitmap images that you supply, reorganize them internally to ensure that the texture card not only gets textures that it can handle but also to try to produce the best performance texture-objects that it can, totally automatically. Put another way; unlike the older versions of T2D (v1.0.2-), your input bitmap sizes DO NOT have to meet the above conditions. T2D will extract the frames and reorganize them into compatible textures. Feel free to create bitmaps that you're happy with! The only exception is that no individual frame can be larger than that supported by the graphics hardware. In the future, even this condition may be removed with T2D automatically splitting-up the frame into manageable chunks allowing T2D to render it seamlessly albeit at a loss in performance. More details on this later. |
“imageMode” (previously called just “mode”)
So now we've told the image-map which image contains the frames we're interested in but it doesn't know where the frames are within the image so we need to define those. This is done by defining a specific Image-Mode. The concept of an Image-Mode is probably the most complex part of an Image-Map so as soon as you've mastered this field, you're pretty much ready to go.
There are four types of image-modes that you can use, these are:
FULL – Full-Image (Single-Frame).
CELL – Regularly-Spaced (Multiple-Frames).
KEY – Color-Keyed (Multiple-Frames).
LINK – Linked Image-Map (Multiple-Frames).
These four types of image-modes allow you to extract frames from your imagery in different ways. To some degree, T2D is flexible on the arrangement of frames within images but you'll still need to be careful to arrange your frames so that you get expected results.
Let's go through each of these image-modes in turn.
"FULL" Image-Mode
This mode is extremely simple to understand as it simply tells T2D that the whole image is a single frame. There are no extra parameters you need to specify at all! It's probably a good time to mention that T2D will assign any frames it finds, a single number starting at zero. In this mode, you'll get a single frame referred to as frame 0 (zero).
Here's an example datablock defining a "full" image-mode image-map:
As you can see, we simply add the field "imageMode" and set it to "full" and we're done. Note that this field is highlighted bold here which means you must always specify this field.
"CELL" Image-Mode
This mode is more complex but still easy to understand once you’ve used it a few times. It’s also the “bread and butter” image-mode that you’ll more than likely be using all the time so it’s important to go through this particular mode in detail. Because this mode is the most common one used, it’s also the default that if you don’t actually specify “imageMode”, T2D will automatically assume you want “cell” mode.
In "cell" mode, you're telling T2D that your frames are organized into a regular grid where all frames have a common width/height, each frame being termed a "cell".
As you can see, our image-map has suddenly expanded with lots of extra fields. Well, don't worry, everything will become clear soon. We've added the "imageMode" as "cell" as discussed above but we've also added four more fields described briefly at the beginning of this topic. The reason we're adding them now is because these fields are only used when you're in "cell" mode. Let's talk about these extra fields.
In "cell" mode, T2D scans across your image from top-left until it reaches the right of your image, it then moves down a "cell" and repeats until it reaches the bottom of your image. To do this, T2D needs at least two pieces of information, these are the "cellWidth" and the "cellHeight". Given these two fields, T2D can successfully capture frames from the image. As you may notice these fields must be specified but only if the “imageMode” is “cell”. So what about the two other fields "cellCountX" and "cellCountY"? Well these are optional fields that allow you to restrict how many cells horizontally and vertically you want from the starting position of top-left. If you omit either of these fields, T2D will try to get as many of these cells in the respective direction as it can.
So if we look at the example image-map datablock we've provided, we can see that we've told T2D that we expect a bunch of cells that are 128 wide by 128 high and that we expect 2 cells horizontally and 2 cells vertically. Of course, we didn't need to explicitly state that we wanted two cells horizontally and vertically, we could've just specified the following:
|
datablock t2dImageMapDatablock( myImageMap ) { imageName = "t2d/data/images/tileMap" imageMode = cell; cellWidth = 128; cellHeight = 128; };
|
This would've given us exactly the same results because as T2D scans across the image horizontally, it only finds room for two 128 wide cells (frames 0 and 1) before it hits the edge of the image so it moves down by the "cellHeight" and scans another row. It then finds another two cells (frames 2 and 3) before it again hits the edge of the image so it moves down by the "cellHeight" again and hits the bottom of the image so it quits. At this point, it's found 4 frames (frames 0, 1, 2 and 3).
When you’re using optional fields, such as “cellCountX” or “cellCountY”, T2D does not force you to use both at the same time. It’s quite happy if you only want to specify the Y count and leave the X count for it to determine. This goes for all optional field pairs!
Let's say, for some reason, that we only want to get two frames at the left of the image (the stone tile and the crate tile). What we need to do here is simply tell the image-map that we only want a single tile in the horizontal direction but two in the vertical like so:
If you’re pretty happy with what you’ve seen so far, it might be worth you trying out both the “FULL” image-mode and the “CELL” image-mode before we go further. Come back when you’re ready to proceed, we’ll still be here!
You back already?
Okay, let’s continue discussing the “CELL” image-mode now that you’re more familiar with the basics.
Now that you’ve used this mode a little, you may have noticed a few restrictions when extracting frames from your images. To start with, it looks like you’re restricted to starting at the top-left of your image. Also, frames are extracted rightwards and downwards. Well, as you would expect, T2D doesn’t restrict you like this at all. Let’s introduce a couple of the remainder of the “CELL” image-mode fields:
“cellOffsetX” – CELL mode only; ‘horizontal’ pixel-offset to start of tile capture.
“cellOffsetY” – CELL mode only; ‘vertical; pixel-offset to start of tile capture.
Take the first restriction we spoke about which was that the frame extraction always starts at the top-left of your image. Well this isn’t so! If you don’t specify either “cellOffsetX” or “cellOffsetY” then indeed, frame extraction will start at the top-left of your image. In-fact, these cell-offsets both default to zero so that’s why T2D starts at the top-left! If you want to start at a specific position within your image, you can specify how many horizontal/vertical pixels you want with “cellOffsetX” or “cellOffsetY”. Let’s show an example to see this working:
What we did here was to specify the offset as 128 pixels horizontally and 0 pixels vertically which equates to the pixel at the top-left of the region marked “0” above. In other words, the top-left of where our frame extraction will begin. If we look at the other fields we specified told T2D that there is 1 cell horizontally, 2 cells vertically and that the cells are 128 wide by 128 high each. T2D will start at the offset position and extract the first frame 0. It will then move right by the cell-width where it hits the right of the image so it moves down by the cell-height back to the specified “cellOffsetX” where it extracts frame 1. It then moves right by the cell-width, hits the right of the image, moves down by the cell-height but hits the bottom of the image so it finishes. The result; two frames (0 and 1).
So the rule is that cell-offsets specify the top-left position of your starting frame.
As we mentioned before, some of these fields are optional meaning that T2D can still make sense of what it thinks you want without them but it may sometimes get it wrong if you want something special.
In the datablock above, we specify the “cellOffsetY” as 0 but it defaults to that so we didn’t really need to do it. Also, we set “cellCountX” to 1 but T2D will already determine that it can only extract a single frame horizontally from the specified offset. So why did we do it? Well, it’s always a good thing to make your intent clear, especially as other programmers/artists may not know what the defaults are and you may yourself forget at a later date. This is not a rule, that’s why these fields are totally optional, just good advice!
Well, we’ve covered the cell-offsets so let’s move onto the final set of fields that might at first be a little confusing. Let’s step back to one of the restrictions we spoke about earlier. We stated that all frames are extracted rightwards and downwards. Indeed all our descriptions so far have been based upon the extraction routine moving right, hitting the edge of your image and then moving down with the extraction process stopping when it hits the bottom of your image.
Well, it shouldn’t be surprising to know that T2D allows you to specify how it moves to the next frame. Let’s introduce nearly the remainder of the “CELL” image-mode fields:
“cellStrideX” - CELL mode only; ‘horizontal’ pixel-stride during tile capture.
“cellStrideY” - CELL mode only; ‘vertical’ pixel-stride during tile capture.
If you don’t specify either of these fields, T2D will extract frames as we’ve so far specified moving rightwards and downwards. What these fields allow you to do is override this movement! Okay, say we’ve gone crazy and we want to extract some frames in very specific order. Again, we’ll use the example image but this time, we want to extract our frames starting at the bottom-right frame, moving leftwards and upwards which is completely reverse to what T2D does by default. Here goes:
As you can see, our frames are now in the reverse-order to what we originally had. All we did to achieve this was to specify the cell “stride”. The “stride” is the movement that occurs after each frame is extracted. Let’s go through what we did above.
First, you’ll note that we specified the offset to be (128 horizontally by 128 vertically) which equates to the top-left of the frame marked “0” above. You must always use the top-left of your starting frame for your offset! The new part is that we’ve specified both a horizontal and vertical stride. These are both -128. Why the minus? Well, as you’ve probably already worked-out, minus for the horizontal means “move left” whilst minus vertical means “move up”. Positive values for these strides mean “right” and “down” respectively.
So what T2D did was to start at the frame marked “0” because we specified an offset of (128,128), it then extracted that frame and because we specified a horizontal stride, it moved that stride which is (-128) which placed us at the top-left of the frame marked “1” where it extracted that frame. It then moved the horizontal stride again but hit the left of the image so T2D moved by the vertical stride which is (-128) and reset the position to the “cellOffsetX” which placed it at the frame marked “2” where it extracted that frame. Finally, it moved the horizontal stride again which placed it at the final frame marked “3”. After extracting this frame, it moved by the horizontal stride which hit the left of the image so T2D moved by the vertical stride which also hit the top of the image causing the image extraction to finish.
As you can see, cell-strides allow you to change the direction of the image-extraction. This combined with the ability to specify a starting position using the cell-offsets provides great flexibility.
Okay, now that we’ve covered using cell-strides, let’s talk about using them for a possibly unexpected reason. Say that our example imageMap had frames that were still 128 wide by 128 high but that they had “gaps” between the frames that we don’t want to acquire; how do we get the frames but ignore the gaps? Here’s how:-
First, let’s describe the example image; the image has four frames, each frame being 128 wide by 128 high as before but now there is a gap of two pixels horizontally between the frames making the total image-width 128+2+128 = 258 and the total image-height 128+128 = 256 as before.
So how do we tell T2D so skip that annoying gap? Well, it’s actually really easy as it’s just an extension of what you’ve already seen. Notice we didn’t specify the cell-offset so T2D will start at the top-left of our image which is just fine with us. As you know, when T2D has extracted the first frame marked “0” above, it will either move horizontally by the cell-width or, if we’ve specified, move horizontally by the “cellStrideX”. As you can see, we did specify it as 130. What T2D will obviously now do is to step 130 pixels horizontally to the right to the next frame which positions us at the frame marked “1”. We successfully bridged the gap! The rest is quite easy to understand as we’ve done it before. When T2D hits the right of the image, it will move down either by the cell-height or, if we specified, the “cellStrideY”. Well we didn’t specify it in this example so T2D moves down by the cell-height which takes us to the frame marked “2”. The final stage is that T2D moves horizontally by our specified “cellStrideX” of 130 which takes us to our final frame marked “3”.
As you can see, strides not only allow you to extract frames in different directions but also allow you to skip regular spacing in your images. Quite often, older “color-keyed” images surround each frame with a specific colour and you can use your offsets/strides to skip these borders and directly extract the frames.
Phew! As you can see, there’s lots of different ways you can extract stuff in “cell” mode and thankfully, we’ve only got a single field to go and then you'll know all there is to know about this mode.
The final field is:
“cellRowOrder” - CELL mode only; Specifies if row-order is used during tile capture.
It shouldn’t be too much trouble understanding this one as it’s really just a change of direction. As we’ve mentioned in all the examples so far, T2D is very flexible on how it extracts frames using offsets/strides/widths and heights. The one thing, that you may have noticed, that has stayed the same during all these frame extraction examples is the fact that T2D always moves horizontally until it hits either the left or right of your image and then vertically until it hits either the top or bottom of your image.
In-fact, as you may have guessed, this is only the default and can again be changed. The field “cellRowOrder” is simply a flag either true or false (defaults to true) that specifies if cells are to be extracted in row-order or alternately column-order so true = row-order and false = column-order.
For our final example in “cell” mode, let’s use the bog-standard example we used in the beginning but let’s extract the images in the non-standard column-mode like so:
As you can see, instead of the frames being extracted horizontally, they’ve been extracted vertically simply by changing this field. Note that you can still use the offsets/strides as explained previously; the only change is that frames are extracted columns first rather than rows, you should still get the same number of frames extracted, just in a different order.
Although this offers limited practical value, it does allow a preferred style of storing your frames or even the flexibility if someone provides you with frames in this order.
Okay, I think you can give yourself a pat on the back here as you’ve now completely covered “cell” mode. Go away and practice with it until you’re totally happy that it does what you want. Come back here when you’re ready to continue our tour of T2D image-maps.
"KEY" Image-Mode
Welcome back! Well, so far you should know how to setup an image-map to get a single full-frame using "FULL" image-mode as well as creating multiple, regularly-spaced, same-sized frames using "CELL" mode but what if we want multiple-frames of different sizes and they're not regularly-spaced in our image? Well, T2D provides another mode to allow you to do just that, the "KEY" image-mode.
In this mode, you can place your frames with a large degree of freedom. The frames can also be of different sizes. So how does T2D know where the frames are? Well, it uses a technique called color-keying. Color-keying is a technique used for special-effects in the movies albeit T2D uses it slightly differently. In the movies, a specific color is used in the scene to identify the "background" so that nice scenes can be added later. If you've seen actors working against blue or green backgrounds, you've seen color-keying. Unlike in the movies, we're not interested in the background; we're not interested in the actors e.g. the frames.
This "key" mode can at first be difficult to understand but there only a few rules you need to be aware of. As motivation in understanding this mode, it's important to know that the image-format used here is identical to the one used when skinning GUI elements in T2D so by understanding this, you'll also understand how to format your images to skin your GUI!
Okay then, let's start with an image that's been setup to have its frames extracted using the "key" image-mode:
As you can see, there are 14 frames of various sizes placed in non-regular positions. So how does T2D extract the frames and in what order? Well, T2D uses simple rules to achieve this and although it looks like the frames have been placed arbitrarily, they've actually been placed according to these rules. Let's start by explaining the steps that T2D goes through to find frames. Note that unlike the "cell" image-mode, frame-extraction is always fixed moving rightwards and downwards.
The first step T2D takes before looking for frames is to choose the color-key. It does this by simply using the color at location (0, 0) e.g. the top-left pixel of the image. As you can see, this is red. From now on, T2D assumes that everything that is this color is background only and nothing to do with frames. It is for this reason that that it's extremely important that you choose a color that isn't used by your frames! You can choose a different color for each image-map but the same one must be used within each individual image.
Okay, now that T2D has the color-key, it can begin looking for frames. To make this explanation a little easier, here's the same image and its image-map definition but we've marked areas that we're going to discuss as well as showing the order of frame-extraction that T2D uses:
|
|
The first step it takes is to determine a row to scan across to look for the top-left of your frames. It does this by scanning down the left-most column for a color that isn't the color-key. As you can see, if it does this, it'll encounter the top-left of frame 0 (marked with the green pixel). When it's found this, T2D then scans along the row to the right until it finds the color-key. As you can see, this will be the cyan pixel in frame 0. Now T2D knows the top-left of the frame and its width so it only needs to determine the frames height and it can extract the frame. It does this by scanning-down from the top-left of the frame (marked with a green pixel) until it reaches the bottom-left of the frame 0 (marked with a blue pixel). Now T2D has the top-left, width and height of the frame so it extracts it!
What happens next is very important. T2D starts scanning from just past the top-right of the last frame (marked with a cyan pixel) until it reaches a non-color-key pixel. When it does this, it finds the top-left of frame 1 (marked with a green pixel). It continues to find the width and height of this frame exactly as it did the previous frame. T2D then extracts the frame and repeats finding frames until it hits the right-side of the image.
Okay, let's continue to extract more frames. After T2D has extracted the first 3 frames and has hit the right-side of the image, it moves straight back to the left-side of the image and continues scanning for more frames. The next frame it encounters will be the top-left of frame 3 (marked with a green pixel). T2D then repeats the procedure outline above. T2D will continue extracting frames until it hits the bottom of the image.
Before we go any further, let's show some of the rules with what we've learned so far. First, it should be obvious that you need to put your color-key in pixel (0, 0) e.g. the top-left. Because T2D scans down the leftmost column looking for non-color-key pixels, you should place the left of your frames against the left of your image. Also, T2D will totally ignore the first row of the image. When T2D encounters a frame, it scans rightwards capturing frames in-between non-color-key pixels. For this reason, you should align the top of all your frames. Frames can be any size but all frames must be no higher than the first frame extracted from that row. When T2D is scanning either down the first columns looking for rows to scan or actually scanning rows, it doesn't matter how many color-keys are between frames.
Phew! You may need a little time to absorb that but it shouldn't be that bad after you've read it a few times. As a summary, here are the rules to follow when creating "key" images:
First, it should be obvious that you need to put your color-key in pixel (0, 0) e.g. the top-left.
Because T2D scans down the leftmost column looking for non-color-key pixels, you should place the left of your frames against the left of your image.
T2D will totally ignore the first row of the image.
When T2D encounters a frame, it scans rightwards capturing frames in-between non-color-key pixels. For this reason, you should align the top of all your frames against the first one in that row.
Frames can be any size but the next row of frames must be below the tallest frame in the previous row otherwise part of the tall frame will be extracted as part of the next row.
When T2D is scanning either down the first columns looking for rows to scan or actually scanning rows, it doesn't matter how many color-keys are between frames.
Although not essential, it's a good idea to "fill" non-frame space with your color-key.
To understand these rules and their implications, read through them again looking at the example image below as a guide.
Give yourself a pat on the back; you've now completely covered the "key" image-mode!
"LINK" Image-Mode
With our review of T2D image-modes, something very important becomes evident. It looks like an image-map is restricted to a single incoming bitmap from which frames are extracted. If you thought this then you’d be correct but you’d also be wrong! In-fact, T2D does limit image-modes to acquire from a single incoming image but it also lets you do something extremely flexible, it allows you to link-together image-maps!
Now at first, this may not seem that important but think about it; T2D allows you to gather-up your frames using various techniques to extract the frames and then allows you to refer to all those frames using a single object that you’re already familiar with; the imageMap!
Okay, let’s look at how this works; let’s start by assuming we’ve got a couple of image-maps already, inventively called “myImageMap1” and “myImageMap2”; these look like this:
|
|
|
As you can see, these image-maps different image-modes of “key” and “cell” to acquire their frames but the good news is that a linked image-map doesn’t care at all! It’s important to note that in this example, we’re only using two image-maps but you can use as many as you like, the minimum being two.
The first image-map contains 14 frames from “0” to “13” whilst the second contains 4 frames from “0” to “3”. Now we’ve configured these, let’s define an image-map to link them up. Here’s how we’d do it:
|
datablock t2dImageMapDatablock( myLinkedImageMap ) { imageMode = link; linkImageMaps = “myImageMap1 myImageMap2”; }; |
As you can see, we selected the image-mode “link” and then specified the image-maps we wanted to link together as a string with space-separators. Note that we didn’t specify the “imageName” field even though we started by saying that this isn’t an optional field! Okay, we lied a little, so let’s clarify; “imageName” is mandatory for all image-modes except “link” mode as it’s simply not needed here.
Something that’s extremely important to understand is that the referenced image-maps must exist when the link image-map is configured, in other words, define a linked image-map after you define the image-maps that it links together in the “linkImageMaps” field.
Now believe it or not, that’s all we need to do! You can use this image-map exactly as you would any other image-map with no other configuration needed. You can still refer to the linked image-maps “myImageMap1” and “myImageMap2” as normal if you wish; they’ve not been altered at all.
Now that we know how to setup a linked image-map, let's talk about how the frame numbers are organized as it’s these we need to access. Quite simply, each linked image-map specified appends its frame numbers to the frame list of the link image-map.
This sounds a little confusing so using our example above, here are the linked image-maps with the frame numbers used in our new “myLinkedImageMap” image-map:
As you can see, the first set of frames are “0” to “13” which correspond to the frames from the image-map we first specified e.g. “myImageMap1”. Now comes the interesting part which is the fact that the frames “0” to “3” from the “myImageMap2” are now referenced by using frames “14” to “17”. As you can see, these have been appended to the frames list.
Let's go into a little more detail on exactly what happened here. The first thing to understand is that linking image-maps in this way doesn’t duplicate the image-map images either in memory or in your graphics card. Linking image-maps is very efficient and uses relatively small amounts of memory. The next point is that the original image-maps are not altered in anyway, in-fact, you can still access them as normal. You should understand that accessing frame “0” from “myImageMap1” is the same as accessing frame “14” from “myLinkedImageMap”. Yeah? If not, you might want to go back and read this section again as this is an important concept.
A cautionary note now is that T2D will not pack the frames from multiple image-maps together to reduce any wasted space. If it were to do this, it would be duplicating the imagery and therefore doubling the memory consumption both on your computer and your graphics card. The caution here relates to the fact that the original textures from the linked image-maps are used when selecting frames. This means that you need to be careful that you’re not producing lots of texture-swaps because you’re constantly swapping between textures. Typically, this problem only becomes a problem if you’re really pushing the limit as to how many frames you’re rendering per screen-update so initially, it’s probably not something you want to be worrying about.
Now that you know how to link-up different image-maps, you should feel confident that you can have different images for your player walking left and right and perhaps jumping and link them all together into a single image-map that your player sprite can refer to.
Happy linking!
“frameCount”
Now that you've seen the various image-modes available and the way to organize your images for frame extraction, the more cautious of you may be asking, "How do I verify I've got all my frames?"
Well, this leads us nicely into our next optional field, "frameCount". Let's use the example image in the previous "key" image-mode tutorial although this field is relevant to all image-modes. In that tutorial, we had an image with 14 frames like so:
Let's suppose we were to incorrectly setup either the image-map datablock or the image itself which caused us to get something like 13 frames instead of our expected 14 frames. If this were to happen, normally T2D wouldn’t do anything because as far as it knows, you've got what you expected. Sometimes this can be hard to track down, especially if the image-map contains lots of frames. You'd only notice if you didn't get the expected frames or your animations looked screwy!
To provide a little sanity and immediate feedback during development, T2D provides the "frameCount" field which allows you to specify how many frames you expect from your image-map.
“frameCount” - Optional; specifies the expected frame-count.
This hint allows T2D to take immediate action if the expected number of frames isn't found. If this happens, T2D will abort the image-map creation and issue a warning. You'll also then find that objects attempting to use this image-map will also issue warnings tell you that the image-map doesn't exist. A quick scan of the log will show you the offending image-map. You can then take immediate action to rectify the problem.
Finally, here's how we'd used the field:
|
datablock t2dImageMapDatablock( myImageMap ) { imageName = "t2d/data/images/guiMap" imageMode = key; frameCount = 14; }; |
So this is a simple field but can save lots of time tracing problems in image-maps.
|
*** NOTE ***
You can use “frameCount” in “link” mode in which case it refers to all the frames from all linked image-maps! |
“filterMode”
This field is slightly different than the ones we've so far discussed. Unlike the others, this field can be changed dynamically at runtime. T2D also provides a nice function call to do the same but we'll get to that later in this document. More importantly, this document is a rendering option, not a frame extraction option, hence you being able to change it dynamically.
There are two types of filter-modes that you can use, these are:
NONE – No Image Filtering.
SMOOTH – Bilinear Filtering.
It is beyond the scope of this document to detail GPU filtering modes so we'll simply focus on the result of selecting a specific filtering mode.
In "none" mode, the GPU does no filtering. The effects of this don’t become apparent if each pixel from your frame gets rendered to a pixel on the screen. You will start seeing this if you either enlarge/shrink the image on the screen; you'll get an effect called pixilation as shown below:
|
Original |
Scaled Up |
Scaled Down |
Although this effect looks poor, sometimes it can be useful artistically in providing an "old school" look. It can also be used to remove certain rendering artifacts that we'll discuss shortly.
Now let's look at "smooth" mode. In this mode, the GPU interpolates between neighbor pixels when rendering which removes the pixilation effect seen above. Also, there's no need to worry about performance here as most if not all graphics cards provide this feature for free e.g. it's as fast as turning off filtering.
Here's an example of "smooth" filtering in action:
|
Original |
Scaled Up |
Scaled Down |
As you can see, the "smooth" filtering removes the pixilation effect but unfortunately tends to blur the images, especially when scaled-up by large amounts.
|
*** NOTE *** You can use “filterMode” in “link” mode in which case it refers to all linked image-maps! |
“filterPad”
Now that you've seen the filter-modes, it's time to introduce a potential problem with using the "smooth" filter-mode. Due to the way that the GPU calculates the "smooth" (bilinear) filter, it has a tendency to sample neighbor pixels. What does this mean? Well, let's look at the image below:
Let's assume we've extracted these four frames and we're using the "water" frame at the bottom-right in a tile-map object and that we're using the "smooth" filter-mode.  Well, this is an unfortunate artifact created by having multiple-frames not only in the same texture but actually located next to each other. If you look at the horizontal lines in the image above, you may have noticed that they appear to be a brownish color? The reason for this is actually quite simple; when using the "smooth" filter-mode, your graphics card renders each pixel of your frame by looking at the respective pixels' neighbors so that it can smooth what it renders. This works well until the graphics card tries to render pixels at the edge of your frame where the neighbor pixels are actually part of another frame!
So we started this document by saying that T2D will try to pack all these frames together inside your graphics card but now we're saying that this causes problems! What's going on here? Well, packing frames together into as few textures as possible is far more important than the artifacts produced by doing so but with that said, we can't live with these artifacts so we need a way to stop them.
Thankfully, it's relatively simple to fix this problem; if you surround each frame with a copy of the pixels on the border of the frame, when the filter looks at the edge of the frame and therefore looks at the neighbor pixels to calculate the "smooth" version, these neighbor pixels are identical as they are just a copy of the frames border which means, you get no nasty artifacts!
This sounds great, how do I get this to work then? Well, as you may have guessed, this section is entitled "filterPad" and it's this flag that allows you to instruct T2D to achieve "padding" of border pixels to remove the artifact like so:-
Note that filterPad current defaults to false (off) but this default may change in the future. To ensure you get the same effect independent of any future updates, you can explicitly specify the "filterPad" but note that it's not highlighted here meaning it's not a mandatory field.
You may be wondering if there are any side-effects of using this option and you'd be correct for asking this question. There are indeed some side-effects, although not visual, of using doing this. We'll discuss the frame-packing process later in the document but it should be evident that these border pixels take a little more room in the final textures although only a relatively small amount.
The greater potential trouble is related to the previous "technical note" you may have read. In this note, we mentioned that a majority of graphics card require the textures on your graphics card to be a power-of-two in size e.g. 2,4,8,16,32,64,128,256,1024,2048,4096 etc. Note that we're talking about the texture that T2D uploads to your graphics card and NOT the bitmap you specify in the image-map using "imageName"!
If this condition is to be met, T2D needs to try to pack your frames into textures that are appropriately sized which isn't a problem for T2D but can unavoidably result in wasted space in the uploaded textures.
As an example of why this happens, imagine that you have the image above with four frames, each of 128 wide by 128 high and they all fit neatly into a 256 wide by 256 high image. Without frame-padding, this resultant texture will pretty much be the same but with frame-padding on, each frame has an additional single-pixel border surrounding it resulting in frames that are 130 wide by 130 high in size.
Simply putting frames into the same arrangement as the original image would result in an image that is (130x2) x (130x2) = 260x260 in size. This is slightly bigger than the previous power-of-two size of 256 so the next feasible power-of-two size is 512. Fitting of a 260x260 set of frames within a 512x512 image results in (5122 x 2602) = 194544 wasted pixels.
|
*** NOTE *** We keep referring to "pixels" when we talk about the texture but in-fact, this terminology is incorrect. A "pixel" is a "PIctureELement" e.g. something that is on-screen. The correct terminology to use is "texel" which is short for "TEXture Element". The reason we separate the two is that it's perfectly normal to render a single "texel" that appears across multiple "pixels". This can be confusing if you've not seen this before and therefore we'll keep using "pixel" to mean "texel". For those who understand this, please forgive the misuse! |
All these numbers are hard to visualize so let's show this another way:
As you can see, fitting these four 128x128 frames that are padded to 130x130 results in a required area of 260x260 which doesn't fit in a 256x256 so we need to use a 512x512 therefore wasting space as shown by the checker-pattern. Of course, T2D does a much better job than just arranging the frames as shown! In-fact, T2Ds intelligent packing routine packs these frames with only 129008 wasted pixels which is 65536 less than the above example.
“preferPerf”
Although T2D will pack your frames totally automatically, it does provide a field that allows you to give it a hint as to whether you prefer the image-map to have higher performance or least-waste. With the "preferPerf" set to true (on), it tells T2D that you prefer performance. With the flag set to false (off), it tells T2D that you prefer least-waste.
In "performance" mode, T2D will make the best attempt to minimize the number of textures used which reduces the need to swap between textures when rendering the frames contained within it. It is important to note that in "performance" mode, any performance increase may be negligible but can be potentially much higher for frames used in objects such as tile-maps.
In "least waste" mode, T2D will make the best attempt to minimize any wasted (unused) pixels in textures. Although T2D will attempt to keep the number of textures required as low as possible, it will ultimately prefer the least waste.
“preload”
Although you can happily leave T2D to deal with the memory used by image-maps, there comes a time when you might want to provide some hint on how it's handled. By default, when you create an image-map, T2D compiles all the imagery and packs it into textures which are then activated so you can start using it immediately. The trouble is that when the textures are activated, they occupy memory. If you define all your image-maps at the start of your game, they can occupy considerable memory. This is essentially preloading in action. The “preload” field allows you to control this aspect; if you set this field to false (off) then T2D will compile and pack the image-maps but it won't load the textures.
You can use "$prefs::T2D::imageMapPreloadDefault" to control the default value for the “preload” field.
“allowunload”
You can use "$prefs::T2D::imageMapAllowUnloadDefault" to control the default value for the “allowunload” field.
Memory Primer
Now let's assume you want your image-map to only activate when used and deactivate when not used. Your image-map would look like this...
Now let's assume you want your image-map to only activate when used but stay activated when not used. Your image-map would look like this...
So what do we mean when we say the image-map is “referenced” or “used”? Well, it's quite simple. If you assign the image-map to a t2dStaticSprite, t2dScroller or indeed, any T2D object, the image-map will recognize this and activate (assuming you're not using “preload”). Now if you change to another image-map or you destroy the T2D object that references the image-map, it will be deactivated (assuming you're not using “preload” and using “allowUnload”). It's that simple!
So what happens when multiple objects use the same image-map? Well, T2D counts the references that objects use. The first one can activate the texture so that's easy but what about deactivating when multiple objects have a reference? Again, it's pretty simple; when an object releases the reference to the image-map, T2D will check to see if the image-map has any references. If it does then T2D does nothing but if there are no references then T2D can deactivate the texture. Of course, as specified, this is dependent upon the options “preload” and “allowUnload”.
So as you can see, T2D provides a nice and simple mechanism to specify when image-map textures are activated/deactivated. You can specify this per image-map or globally using preferences.
Advanced Development
Okay, now that we've covered the image-map fields, it's easy to think that you've got everything you need and to some degree, you can take what you've learned so far and stop here. Please feel free to do that as we've definitely covered all you'll need to get started and enjoy T2D. When you're ready, come back and we'll discuss ways of getting more advanced information/control over your image-maps.
Welcome back!
For here on we'll be discussing the more advanced features of image-maps that can provide vital information when configuring image-maps, not only for debugging but to provide an interface to what's going on behind the scenes. This kind of information can enable you to write various tools to help you configure your image-maps.
Let's start with a discussion of what we mean when we say that T2D "packs" your frames into textures for the graphics card. When T2D looks at your image-map datablock, it finds some vital information. The first is the image-name which defines the bitmap that contains your frames. It then looks at the image-mode which tells T2D how to locate your frames within the specified bitmap. It then goes away and compiles a list of frames and their location in the specified bitmap.
Now comes the complex part! T2D now takes into account your preference of either performance or least-waste as well as whether your frames need padding and starts the process of "packing" your frames into textures. At this point T2D interrogates the maximum sized texture that your hardware can support. If you want to do this yourself, T2D provides the following function (note that you can find more information on this call in the T2D reference documentation):
|
%maxSize = getT2DMaxTextureSize(); |
Now that T2D knows the maximum-sized textures that it can create, it iterates through various combinations of texture sizes noting either how much waste there is or how few textures are created according to the preference rules. Iterating lots of frames through all the variations of texture sizes can be computationally expensive so T2D has some smarter algorithms that enable it to reduce the potential fits available.
When T2D has found the best solution, it starts the process of copying the frames from your original image into the appropriate locations in the new texture(s). It also adds any frame-padding if appropriate. When this is complete, T2D uploads these textures to your graphics card and compiles an internal list so that it can easily refer to the correct texture by frame number. T2D has then completed everything needed to compile an image-map.
During this packing process, T2D can encounter several problems. If a problem occurs, T2D will abort the image-map compilation and remove any resources that it current holds. The result of this will be an error in the console such as:
"Register object failed for object myImageMap of class t2dImageMapDatablock."
When you see this, you know that the image-map named "myImageMap" failed. What you'll probably see then are cascaded failures when you've subsequently tried to use the image-map in other T2D objects but the important one here is the initial failure. T2D is based upon the T3D engine which provides the message as shown above. Now although this message is useful in knowing that a problem occurred, it doesn't say what the problem was.
Luckily, T2D provides more information on any problems encountered. It does this in several ways. The first is that T2D issues script-callbacks which allow you to directly control what happens when any of your image-maps fail at runtime. Secondly, you can instruct T2D to additionally echo any error to the console.
Let's start with the script-callbacks; there are three callbacks in total, these are:
onImageMapPackStart() – Packing has started.
onImageMapPackEnd() – Packing has ended.
onImageMapError() – A Packing error occurred.
These callbacks enable you to monitor the packing start and stop of each image-map as well as any errors that may occur. Due to the fact that image-maps are not valid objects until they successfully complete the packing process, these callbacks are not passed the typical "%this" implicit object identifier. The callbacks appear in a specific order of "onImageMapPackStart", "onImageMapPackEnd" and "onImageMapError". They are used like so:
|
// Start Packing. function onImageMapPackStart( %imageMapName ) { echo( "Packing has started for image-map" SPC %imageMapName ); } // End Packing. function onImageMapPackEnd( %imageMapName ) { echo( "Packing has ended for image-map" SPC %imageMapName ); } // Packing Error. function onImageMapError( %imageMapName, %errorNumber, %errorDescription ) { echo( "An error occurred in image-map" SPC %imageMapName ); echo( "The error number was" SPC %errorNumber ); echo( "The error description was" SPC %errorDescription ); } |
The start/end packing calls are pretty simplistic and simply allow you to monitor which image-maps are being processed and when they complete. The end-packing call will happen irrelevant of any error occurring. Following the end-packing call, you may get an error callback. Let's go into a little more detail on this error callback.
When an image-map error occurs, it immediately aborts and results in the packing process ending and an error callback. Because image-maps stop on the first error they encounter, you'll only get a single error callback. Of course, if you resolve the problem and try again, you may then get another error.
All of the image-map callbacks return the name of the image-map as the first parameter to the callback which is useful in identifying which image-map has failed. As mentioned above, the image-map doesn't yet exist as an object to the scripts so you cannot refer to it directly so the name is your only reference.
The error callback provides two additional parameters which are extremely valuable in determining what went wrong. The first is the "error number" which is an integer starting at 1 which uniquely identifies each error. The second is a textual description of the error itself. You may want to provide specific responses to certain errors at runtime so the "error number" is more useful in this case.
Here's a list of potential error numbers and their respective description:
- "Invalid Mode; must be FULL, KEY, CELL or LINK!"
- "Invalid Bitmap File!"
- "Frame Width Too Big; Unsupported by current hardware!"
- "Frame Height Too Big; Unsupported by current hardware!"
- "Filter-Padded Frame Width Too Big; Unsupported by current hardware!"
- "Filter-Padded Frame Height Too Big; Unsupported by current hardware!"
- "Frame Width Too Big; Larger than selected limit!"
- "Frame Height Too Big; Larger than selected limit!"
- "Filter-Padded Frame Width Too Big; Larger than selected limit!"
- "Filter-Padded Frame Height Too Big; Larger than selected limit!"
- "Reported Maximum Hardware Texture Size is invalid!"
- "Selected Maximum Texture-Size is larger than the current hardware limit!"
- "Invalid CELL Offset X!"
- "Invalid CELL Offset Y!"
- "Invalid CELL Dimension!"
- "Invalid CELL Quantity!"
- "Invalid CELL Capture!"
- "Failed to get separator color!"
- "No frames have been acquired!"
- "Number of frames acquired differs from that specified!"
As we mentioned earlier, you can also ask T2D to additionally echo these errors to the console. Perhaps you're not interested in using the script callbacks and simply want to monitor your console log. T2D provides several preferences for image-maps, one of these being the echoing of image-map errors. Let's introduce these preferences now:
$prefs::T2D::imageMapEchoErrors
$prefs::T2D::imageMapShowPacking
$prefs::T2D::imageMapDumpTextures
$prefs::T2D::imageMapFixedMaxTextureSize
$prefs::T2D::imageMapFixedMaxTextureError
$pref::T2D::imageMapPreloadDefault
$pref::T2D::imageMapAllowUnloadDefault
Hopefully, you'll already know about your preference file(s). If you don't then you simply need to know that it is a script file where T2D exports any variables from the "$prefs::" namespace when you exit T2D. You can specify variable parameters to the T2D engine here therefore image-maps expose the previous five preferences here.
You can more detail on these preferences in the T2D reference documentation, nevertheless let's go through each of these preferences:
"$prefs::T2D::imageMapEchoErrors"
This preference tells T2D to echo any error to the console. T2D will still produce an error callback.
"$prefs::T2D::imageMapDumpShowPacking"
This preference tells T2D to echo image-map statistics at the start and stop of packing. These statistics contain comprehensive information on the packing process and can be invaluable in understanding what T2D is doing with your frames. As well as frame locations, texture-page dimensions and counts, T2D also provides timings for the packing process.
"$prefs::T2D::imageMapDumpTextures"
This preference tells T2D to dump the resultant textures that contain the packed frames to disk before uploading to your graphics card. You can use these images to visualize what exactly T2D is doing with your frames.
T2D will always dump these images to the root script directory into a subdirectory called "imageMapDump". The output images will be the same format as the original input image.
The nomenclature for these files is:
<image-map name>_Page_<Texture Page>.<original image extension>
An image-map called "myImageMap" that produces two textures from frames originally contained in a ".png" file will output the following files:
"myImageMap_Page_0.png"
"myImageMap_Page_1.png"
Note that T2D does not clear this directory prior to outputting files therefore files from previous executions may still be contained. Any files of identical names will be overwritten without confirmation.
"$prefs::T2D::imageMapFixedMaxTextureSize"
This preference tells T2D to override the maximum supported hardware texture size (MSHTS) in favor of this specified size. This value must be equal or less than the MSHTS. Additionally, this value must be a power-of-two. If it isn't, T2D will automatically raise it to the next power-of-two. It defaults to zero which tells T2D to ignore it and to use the MSHTS instead.
Although this preference would probably be left at its default most of the time, it does allow you to override under certain conditions. For instance, you may find that performance of the MSHTS is not adequate on specific hardware. You can use the scripts to identify this hardware and adjust this preference accordingly.
"$prefs::T2D::imageMapFixedMaxTextureError"
This preference is directly related to the previous preference. It allows you to override the situation where the specified maximum texture size is actually higher than the MSHTS. In this situation, T2D cannot honor the request and must do something to resolve the problem. T2D has two choices; defer to the MSHTS or abort with an error. This preference controls which option T2D chooses. The default is false (off) which means T2D will defer to the MSHTS. When set to true (on), T2D will abort with an error.
"$prefs::T2D::imageMapPreloadDefault"
If you don't specify the “preload” field then this preference allows you to select the value used by default. You can essentially use this setting to select a global default for the “preload” field, overriding it where necessary using the “preload” field.
"$prefs::T2D::imageMapAllowUnloadDefault"
If you don't specify the “allowUnload” field then this preference allows you to select the value used by default. You can essentially use this setting to select a global default for the “allowUnload” field, overriding it where necessary using the “allowUnload” field.
Now that we've covered both callbacks and preferences that can be used to monitor the image-map packing process as well as any errors generated, let's finish by discussing the functions that image-maps provide to allow you to control and interrogate them.
Here's a complete list of the functions provided by image-maps:
setFilterMode() – Set GPU Filter Mode.
getFilterMode() – Get GPU Filter Mode.
getImageMapMode() – Get Image-Map Image-Mode.
getSrcBitmapName() – Get Source Image Bitmap Name.
getSrcBitmapSize() – Get Source Image Bitmap Size.
getFrameCount() – Get Total Frame Count.
getFrameSize() – Get Specific Frame Size.
getTexturePageCount() – Get Total Texture-Page Count.
getTexturePageSize() – Get Specific Texture-Page Size.
getTexturePageFrameCount() – Get Frame Count on specific texture-page.
getFrameTexturePage() – Get Texture-Page that specific frame resides.
You can find more information on these functions in the T2D reference documentation, nevertheless let's go through these functions individually:
"setFilterMode(%mode) / getFilterMode()"
These two functions allow you to set/get the filter mode to either "none" or "smooth". This replicates the image-map field "filterMode" such that you can use either the field or the functions to set/get the filter-mode.
"getImageMapMode()"
This function retrieves the image-map mode. This replicates the image-map field "imageMode" such that you can use either the field or the function to get the image-map mode. Note that changing the field after the image-map has been created has no effect whatsoever.
"getSrcBitmapName()"
This function retrieves the name of the source image bitmap used to extract frames. This replicates the image-map field "imageName" such that you can use either the field or the function to get the image-name. Note that changing the field after the image-map has been created has no effect whatsoever.
"getSrcBitmapSize()"
This function retrieves the size of the source image bitmap used to extract frames. An 800 wide x 600 high bitmap would be returned as "800 600".
"getFrameCount()"
This function retrieves the total frame count calculated by the image-map.
"getFrameSize(%frame)"
This function retrieves the size of the specified frame. The frame-number is zero-based and is valid to the value returned by "getFrameCount()" minus one.
"getTexturePageCount()"
This function retrieves the total texture-page count calculated by the image-map.
"getTexturePageSize(%page)"
This function retrieves the size of the specified texture-page. The page-number is zero-based and is valid to the value returned by "getTexturePageCount()" minus one.
"getTexturePageFrameCount(%page)"
This function retrieves the total frame count on the specified texture-page. The page-number is zero-based and is valid to the value returned by "getTexturePageCount()" minus one.
"getFrameTexturePage(%frame)"
This function retrieves the index of the texture-page where the specified frame resides. The frame-number is zero-based and is valid to the value returned by "getFrameCount()" minus one. The page-number returned is zero-based and is valid to the value returned by "getTexturePageCount()" minus one.
It may not be obvious how you'd call image-map datablock functions but being as they are fundamentally an object within T2D, they can be used in much the same way as you would use any other object in T2D. As an example of this calling process, here's how you'd set the filter mode on an image-map:
|
myImageMap.SetFilterMode( smooth ); |
As you can see, there's a wealth of information that can be retrieved from image-maps but it is important to understand that if any error occurs during the image-map creation, the image-map object will not be available therefore neither will these functions.
Conclusion
We've now come to the end of our discussion on T2D image-maps and we hope that we've provided enough information for T2D novices and veterans alike. T2D image-maps are the "bread and butter" of using T2D so a fundamental understanding of how to use them is vital. Because they are so vital, they've become more and more powerful offering more ways to define your imagery and they'll get even more powerful in the future.
Don't forget that you can always find information on T2D image-maps in the T2D reference documentation.
All the best everyone and happy T2D'ing!


Competitive retail suppliers energy offers
Scrape offers from the utilities webpage and make them available as an API
-
Get the historical offers for a region (e.g. ISONE), posted between a start and end date. Note
that an offer can be out there for several months at a time. Currently only CT offers are
available. More will be added over time.


Canada among three G20 countries least likely to hit emissions targets
It says Canada, South Korea and Australia are the farthest off
by The Canadian PressA report card on global climate action says Canada’s plan to meet its greenhouse-gas emissions targets is among the worst in the G20.
Climate Transparency today is grading all the countries in the group of 20 with large economies on their climate performance and finds none of them has much to brag about.
It says Canada, South Korea and Australia are the farthest off meeting targets to cut emissions that are insufficient anyway.
The report says Canada is among the leaders in getting rid of coal power but is a laggard on a number of fronts, including energy use and emissions from cars and buildings.
Today’s report says Canada has four times the G20 average for emissions per person from transportation and has more than twice the average emissions from buildings.
The G20 nations account for 85 per cent of global economic activity and produce 80 per cent of all emissions, putting the onus almost entirely on them to reduce emissions to prevent catastrophic impacts of climate change.
READ MORE: ‘Your vehicle burns a lot of fuel:’ Victoria drivers wake up to angry notes
The Canadian Press


Posted on August 22, 2014 at 11:00 AM CST
Stereotype threat refers to being at risk of confirming, as self-characteristice, a negative stereotype about one's group.
Stereotype threat can happen to anybody. It happens when you feel that you may be confirming a negative stereotype about your group. A few symptoms of stereotype threat are anger, being self-conscious, feeling uncomfortable, timid, etc... Consequences of stereotype threat can be pushing people away, performing worse at a given task, or in extreme cases, violence. A couple of ways you can try to reduce the effects of stereotype threat are making people feel safe, and relating to the person through your own personal stories
Since relating to others with person stories of your own can help reduce the effects of stereotype threat, here is my story. My first job out of college I was hired on along with 2 other guys for a specific project. The two other guys that were hired were minorities and I am white. The job was funded by the state and the state has very strict rules protecting minories, and they were enforced. The guys on job had been working together for a few months before we started and thought that the new hires should be hazed. Because the other two guys were minorites, they were protected. If they had been hazed and reported it, the entire $40 million contract could be lost. This left just one new hire to haze, yours truly.
 And it was all day, every day. It became so bad my work began to suffer. Then I got to the point where I was so angry I tried defending my self by making fun of anyone who made fun of me. That is a losing battle when you are alone in a situation like that. It got so bad at one point, that I threatened one of the engineers right in fron of the Project Manager. By the time it got to this point and some of them began to realize they crossed a line, it was too late. I felt like everybody hated me and I could feel the mood in the room change the instant I walked in.
My saving grace came about 7 months into the project. They needed one person from the office to stay and manage a night crew of 3 guys. Miraculously I got the position. Almost immediately my work started to improve. I became really good friends with the night crew guys and I started to actually like my job. The work had not changed, my position or pay had not changed. I no longer had these guys taunting me for being the new guy. In this story I felt stereotype threat because of my professional position. I felt attacked and almost brought it to the extreme of the spectrum, violence. I am glad it did not come to that, and I hope I can prevent situations like this in the future by implementing this few simple strategies.
The part of personal identity - our sense of who we are - that comes from our group memberships and the social categories to which we belong: our age, sex, race, religion, profession, ethnicity, nationality, sexual orientation, religion, social class, ideological persuasion, political affiliation, mental health status, etc...


Keyboard layouts converter
Layout Code
Layout Name
Copyright
Saved
Group languages by
Language code (en-
US
)
Language domain (
en
-US)
Process selected


Each of the bedrooms have at least a double bed or bigger and one of them has 2 single beds. The 2 bedrooms in the flat area have access to a kitchen as well as a bathroom with double basin, toilet and shower. The main bedroom inside the house has a private balcony and access to a full en-suite bathroom. The remaining 2 rooms inside the house have direct access to a bathroom with basin, toilet and shower.
The kitchen inside the main house is a large open space with sufficient appliances, cookery and crockery for you to make use of while whipping up a deliscious home cooked meal. There is also access to a Dishwasher, Washing Maching and Drier.
The house has a large open deck looking out over Wilderness Village and the Indian Ocean and boasts some of the most amazing sunsets you will see. For days when you would prefer some shelter or a Braai (South African Barbeque) ther is also a semi enclosed balcony on othe other side of the house.


ayedocs recieve the render input and returns the content, simple that is.
A render input can be a path to a .md file (file
), a template name (template
), a custom rendering (rendering
).
The CLI load configuration from package.json
or .ayedocsrc.js
. See Options
section for detail. Using the API, config can be provided directly when init the module.
For example, my project has the package.json
like this:
{
"name": "my-package",
"description": "My package description.",
"ayedocsrc": {
"url": "https://docs.example.com",
"fileRender": {
"TEST.md": {
"head": true,
"section1": ["Lib", "SELF"]
}
}
}
}
With the configuration above (inside the ayedocsrc
key), you tell the CLI to create a file named TEST.md
with two sections:
head
section: a built-in section that display the package name and description.section1
section: a rendering section that display the source code element title and description.The TEST.md
content would be:
<\section id="head">
\# my-package
**My package description.**
</\section>
</\section id="section1">
\## The `Lib` class
**This is a Class element named `Lib`**
And this is the `Lib` element detail.
Supports Markdown content.
</\section>


For-Profit
We are building bridge,and making car company.
We made the water fountain and this water fountain is the best water fountain in the holl world. Because this water fountain is very light and very easy to carry beacuse it very small and it very beutiful and simple.
In this project we learned how to create web page and how to change back ground how to add picture how to edit the web page.collaboratively, incrementally
and how to


Flexible availability between 10am and 6pm, Monday through Friday. Previous office experience handling phones, filing, database entry, and/or creative project work preferred, but not required. Friendly and helpful within a diverse cross-cultural environment. Ability to maintain confidentiality and appropriately handle sensitive communications and confidential records. Strong computer skills. Experience using MS Office. Knowledge of PowerPoint, Illustrator, and/or Access desired, but not required. Takes initiative and can work independently. Ability to accurately sort and file documents. Strong oral and written communication skills. Ability to handle multiple projects and prioritize tasks. Please provide a resume/C.V. to the office (if you have one) or a description of relevant experience and skills. Skills assessment also will be held.


{% extends 'layouts/application.html' %}
{% set title = "Alert" %}
{% set body_classes = "layout-app" %}
{% block before_main %}
{% endblock %}
{% block content %}
UI ComponentsAlert
Alerts keep users informed of important and sometimes time-sensitive changes.
{% include "components/alert/success.html" %} {% include "components/alert/info.html" %} {% include "components/alert/warning.html" %} {% include "components/alert/error.html" %} {% endblock %}


Will solve your problem. 6 years experience. Having fun with programming (backend or frontend, office or remote, paid or open source). Currently welcome to relocation offered jobs.
Big Data Technologies 2019-09-01 —
Analytics for large online-store suppliers. Personally I've designed application architecture, taking into account the complexity of algorithms and big data, set up and supported infrastructure, implemented demo, implemented MVP and led all further technical solutions.
Highlights
- NodeJS
- Express
- Sequelize
- XLSX
- MySQL
- Clickhouse
- Docker
- React
- Material UI
- Grafana
Big Data Technologies 2019-09-01 — 2019-12-01
Chrome extension to share online-shop coupons and promotions. In short period I've set up project infrastructure, implemented MVP and led a developer who worked on the project afterwards. That allowed my client to move to next phase (marketing).
Highlights
- React
- Material-UI
- Styled Components
- SeleniumJS
- Chrome Extension
Big Data Technologies 2019-05-21 — 2019-09-01
Trends of Aliexpress products. In the project I've implemented a few versions of trending algorithm, added several complex filters to search, added social login, integrated application with a few payment systems, improved logging and monitoring, added integration to external online shops, improved analytics, improved performance of too long operations and added some tricky customizations to landing pages. Implemented features increased level of attraction and retention and allowed client to get paid subscriptions from users.
Highlights
- PHP
- Laravel
- Vue.js
- MySQL
- Clickhouse
- Redis
- Stripe
- Paypal
- Tilda
Freelance 2018-12-01 — 2019-02-18
Simple battleship-like board game. Personally I designed and implemented entire game which includes game logic, frontend, backend for online game and AI bot.
Highlights
- React
- Material UI
- Styled Components
- boardgame.io
- three.js
- brain.js
Issoft Solutions 2018-05-01 — 2018-11-15
React Question Board for meetings and planning using Interaxo document management system. Within the project I designed and implemented robust and secure REST API for the app and implemented new web pages like filterable cards list page, card forms, auth page, etc. Additionally I introduced a new library for all common components that are used across React applications of the customer. Plus configured CI, deployment and analytics. Now the project is easily scaled, monitored and successfully used by different customers who wants more and more new features.
Highlights
- Spring
- REST API
- Hibernate
- PostgreSQL
- React
- Material UI
- Redux
- React DnD
- React Virtualized
Freelance 2018-06-01 — 2018-09-15
Web project with courses for students and teachers. I implemented some new views and integrated the project with existing API according to the client requirements. I also introduced the project to new developers, tried to teach them project best practices, helped them and monitored their work.
Highlights
- React
- Redux
- Styled Components
- React Player
- Swagger
Issoft Solutions 2018-02-01 — 2018-05-01
Application allows to set up external workflow for different folders in document management system. Within the project with help of mentor I implemented the application that synchronizes folders in workflow using document management system API. Now the application is successfully used by several document management clients to simplify their real workflow.
Highlights
- Spring
- REST API
- Hibernate
- Apache Camel
- WebSocket
Freelance 2018-03-01 — 2018-04-15
Pinterest like room fittings. I set up frontend app, implemented registration and authentication flow, build responsive pinterest view and set up bitbucket pipelines. Now the client rapidly reviews the changes of client developers, offers new users a personal account, monitors new users and enjoys pinterest view for the products.
Highlights
- React
- Material UI
- Redux
- React Stack Grid
Freelance 2017-11-01 — 2018-02-01
Real estate search app. I used Material-UI Grid layout system to make application responsive, Material UI to create nice views, migrated sass to css-in-js to clean up sass files, replaced webpack config with create-react-app scripts and refactored plenty of code. Now the project is completely responsive and easier to read, support and implement new features.
Highlights
- React
- Material UI
- Redux
- Leaflet
Issoft Solutions 2017-01-01 — 2018-01-01
REST Public API for big document management system. I spent a lot of time learning REST API best practices and with help of mentor I implemented Public API, which is monitored, covered by different types of tests, secured by OAuth2, well-documented, versionable and follow many REST API best practices. Now API is successfully used by many internal document management system applications as well as external document management customer applications.
Highlights
- Spring
- REST API
- OpenID Connect
- OAuth2
- Keycloak
- Retrofit
- Swagger
- Docker
- Openshift
Issoft Solutions 2017-07-01 — 2017-08-15
Web and mobile applications for medical items monitoring on ships. I fixed all the bugs, provided by the client, and some bugs found by me in Spring Data logic and deployment to AWS. Now the application is used by captains and crew members on ships.
Highlights
- Spring
- Hibernate
- Spock
- AWS EC2
- Bamboo
Issoft Solutions 2014-10-10 — 2017-01-01
Enterprise document management system for engineering and oil industry in Norway. By the end date I've learnt all the areas of the application and have been able to quickly find and fix any bugs. I improved some areas like bulk import, download, upload, email handling, security, mobile app, etc. I also refactored a lot of code. Now the amount of the application users and new features still rapidly grows while the amount of bugs grows not so fast as it was before areas improvements.
Highlights
- Spring
- Alfresco
- CMIS
- JUnit
- Gradle
- ExtJS
- Cordova/Phonegap
- Google Analytics
- Jenkins
- Git
IBA Group 2014-08-01 — 2014-10-01
Support of bank content management system.
Highlights
- IBM Tivoli Storage Manager
IBA Group 2014-02-01 — 2014-08-01
Web based bank document management system.
Highlights
- Apache Struts
- Dojo
- Ant
- IBM FileNet
- IBM WebSphere
- Apache POI
- SVN
IBA Group 2013-09-20 — 2014-02-01
Web based document management system.
Highlights
- JSP
- Servlets
- XSLT
- Maven
- IBM FileNet
- IBM WebSphere
- Apache POI
- SVN
Welfare for animals in Goa 2019-01-15 — 2019-02-10
Hour a day helped injured cows and dogs in Indian shelters.
Boardgame.io on Github 2018-12-15 — 2019-02-01
Fixed several issues related to deployment and board game lobby
BSUIR 2011-09-01 — 2016-06-01
BSUIR 2016-09-01 — 2018-06-01
Docker Training
Amazon Web Services for Java Developers Training
Hibernate, JPA, Spring Training
ReactJS Basics Training
EJB Web Development Training
Java Web Development Training
Java Web Development Training
Android Development Basics Training
JavaScript
- 6 years
React JS
- 4 years
Java
- 5 years
Spring
- 4 years


{% extends "base.html" %} {% import 'bootstrap/wtf.html' as wtf %} {% block app_content %}
We need a SSH key, which is composed by a public and private part.
This key will be used to copy the generated artifacts from the slaves to the repo.
If do not have yet a SSH key, you can generate it by running the following command (make sure you have installed the openssh-client
package):
ssh-keygen -b 4096 -t rsa
This command will create two files in the ~/.ssh/
folder:
~/.ssh/id_rsa
file contains the private key.~/.ssh/id_rsa.pub
file contains the public key.Tip
Use cat ~/.ssh/id_rsa
to print out the private key, and
cat ~/.ssh/id_rsa.pub
to print out the public key.


Visually, we feel that Amour PWA is more polished and vastly different compared to its desktop app counterpart.
It is also more reactive, adaptive and more responsive; the in-app animations are improved;
together these changes make for an effortless and tailored experience. Your background colors are now adapable to your
album genres and change colors accordingly,
making your experience more personalized and unique—as a music player should be. We felt as
though Amour PWA went through a revamp when it comes to its functionality!
Menus such as Playlists, Made for you, Albums … are now relocated to the above of the main section, making the left panel
less clustered and enabling more room for users. This is especially useful for music enthusiasts who have lots of
playlists and in need of more space or users who are more on the orderly side and can’t stand a crowded UI.


Bar Fight!!!
You Won!!!
You Lost!!!
Clicks:
0
Click Button to Fill Bar
You Won!!!
You Lost!!!
Clicks:
0
Click Button to Fill Bar


Note
This section describes creating CSV file templates. For information on CSV field templates, see the "Using CSV field templates" section.
You can generate a template CSV file by running Workbench with the --get_csv_template
argument:
./workbench --config config.yml --get_csv_template
With this option, Workbench will fetch the field definitions for the content type named in your configuration's content_type
option and save a CSV file with a column for each of the content type's fields. You can then populate this template with values you want to use in a create
task. The template file is saved in the directory indicated in your configuration's input_dir
option, using the filename defined in input_csv
with .csv_file_template
appended.
The template also contains three additional rows:
- human-readable label
- whether or not the field is required in your CSV for
create
tasks - sample data
- number of values allowed (either a specific maximum number or 'unlimited')
- the name of the section in the documentation covering the field type
Here is a screenshot of this CSV file template loaded into a spreadsheet application:
Note that the first column, and all the rows other than the field machine names, should be deleted before you use a popluated version of this CSV file in a create
task. Also, you can remove any columns you do not intend on populating:


500
Internal server error
We are currently trying to fix the problem.
Illustration taken from
Manoj Kumar


At the beginning of this year, I was too broke to buy weed regularly, so I had resorted to smoking cigarettes like crazy and tripping on DXM. I was looking for something a bit more interesting than the usual disorientation of DXM. I remembered the Modest Mouse song Dramamine, and thought hell, sounds cool to me. Big mistake, wish I had heard of this site then. Not that it was a horrible trip, I just wish I had known what I was getting into.
My friend and I drove up to CVS and bought a box of Dramamine and later that night, at my own house all alone in my room, I took the pills. The first few were nasty as crap, so I went down stairs and used Sunny D as a chaser. I went back upstairs, turned the light on and began reading a MotorTrend.   I looked at the ground and found the magazine, picked it up, put it aside and turned out the lights. I turned on the Modest Mouse CD 'This Is A Long Drive For Someone With Nothing To Think About.' The first track is dramamine, an appropriate song :-p .
I put the clicker down and realized I had to pee. So I got up and walked down the hall, still fairly lucid, minus the blurred vision. I felt drunk. I ran into every door in the 20ft to my bathroom. It was pitch black and I couldn't see a damned thing. I finally made it into the bathroom and turned on the light, when I heard my dad yell something about being quiet, he was trying to sleep. I pissed, and went back to bed. I did the same thing about 8 more times, never actually pissing those times.
Once I was done 'peeing' I went back to my bed and turned the lights out again. I looked over at my stereo and hit play again, as the cd had ended. That's when I saw my dad behind my stereo unplugging it. I yelled at him to stop, and he just stared blankly at me as I yelled at him. Finally I heard him from the other room when he yelled 'SHUTUP!' It was about 2 in the morning at this point. His image in my room wisped away like a cloud of smoke. Very disturbing.
At this point, people starting walking into my room. People I didn't know. People from all era's of time. People who looked dead, like a walking zombie or something. People who looked quite alive. All sorts of people. All walking into my room and crawling under my bed. As with anytime I see dead people walking, I peed my pants. Thought the 8 trips to the toilet would have cleaned me out, but no, I peed my pants. I was too afraid to go across my room and feared letting my legs anywhere near the bottom of my bed, for fear that hands would grab them. After about an hour (or at least that's what it felt like) I decided that it was safe to stop standing on my bed with a pillow readied as defense. Then I saw my dog at the side of my bed.
I was wondering how the dog got in the room with the door being closed. Then again, that didn't stop all those people, so why I found it strange I have no idea. I leaned over to pet her and as my hand touched her she wisped away like smoke, in much the same manner as my father had. I got under my sheets and clung to them tightly, I was freaking out.  But then I got thirsty. So I went downstairs and was met by my mother, who assumed I was sneaking out. The conversation went something like this (this is how she retold it to me the next morning, I have no recollection of this):
Mom: 'What do you think you are doing?'
Me: 'I need wuuuter'
Mom: 'You're not sneaking out?'
Me: 'I'm wearing my boxers only. No I'm not sneaking out.'

Me: 'Ummm nothing, I need water'
Mom: 'Ok.'
She reaches for a glass and hands it to me, only to take it away shortly after because I was shaking so much, then she filled it up for me.
Me: 'I need pepcid' (sounding frantic)
Mom: 'ok...'
She hands me the pepcid, and it's in a wrapper I've never seen before, one that looks just like the wrapper the Dramamine pills come individually wrapped in. I came too (I remember from here on out) at that moment, looked in my hand and thought the pill was a Dramamine.  I'm fucked.' So I turned around and began walking upstairs with my hand clenched tightly and the water in the other hand.
Mom: 'Where are you going?'
Me: 'Bed'
Mom: 'What's in your hand?'
Me: 'Nothing...'
Mom: 'Are you on a drug?'
Me: 'No...'
Mom: 'Are you sleep walking?'
Me: 'Uhhh yeah that's it, that's it, I'm sleep walking.'
Mom: 'Ok go to bed and don't get back out tonight, you've been making a racket all night.'
 I went back to my room and attempted to fall asleep. I found that the more I thought about nothing, the more I thought about everything. The next hour or so I remember thinking about everything, but not in words. It was nothing that I could even begin to put into text. It was the most powerful thought I have ever experienced. I learned more in that hour or so than I have in my entire life. Everything fell into place. Everything just made sense. Nothing in the world has look quite the same since. The beautiful looks more beautiful, the hideous, more hideous. It is just simply the most incredible experience of my life.
From what I have read about other people's experiences, they experienced much the same scary hallucinations, but no one else seems to have experienced the deep session of thought. That was when Dramamine was enjoyable, and outright euphoric, just for the sheer amount of knowledge I gained, just from deep thought. The hallucinations are extremely realistic, and actually pretty cool, in retrospect. It was not cool at the time however. The scariest experience of my life, that was offset by the most amazing euphoric thinking of my life. Not the greatest drug, but it was overall worth it.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


{% extends "site.html" %} {% load i18n %} {% block title %}Disconnect failed{% endblock %} {% block page_title %}{% trans "An error occured while disconnecting the service" %}{% endblock page_title %} {% block content %}
{% trans "This issue might be temporary and could be solved by making a second try." %}
{% trans "If the issue persists even after a second try, please contact us. We will do our best to resolve it as fast as possible." %}
{% trans "Timestamp" %} : {% now "Y-m-d H:i:s" %}


Predicting rain with Scikit (Machine Learning)
Machine learning
SciKit
Python
In the olden days of yore, predicting the weather was near-impossible task reserved to fortunetellers and shamanistic figures. People would spend their lives, rather unfruitfully, read more...


KnowYour
Words.
Home
Demo
Search
Analyze
Contact
© KnowYourWords 2019. All Rights Reserved. Template courtesy
Colorlib


Current Rotation Rate:
Alpha:
If you can see this,
Beta:
this function
Gamma:
is not supported
RotationRate should be measurable


grammar::me::util - AST utilities
This package provides a number of utility command for the conversion between the various representations of abstract syntax trees as specified in the document grammar::me_ast.
This command converts an ast from value to object representation. All nodes in the ast will be converted into nodes of this tree, with the root of the AST a child of the node root. If this node is not explicitly specified the root of the tree is used. Existing content of tree is not touched, i.e. neither removed nor changed, with the exception of the specified root node, which will gain a new child.
This command is like ::grammar::me::util::ast2tree, except that the result is in the extended object representation of the input AST. The source of the extended information is the command prefix mcmd. It has to understand two methods, lc, and tok, with the semantics specified below.
Takes the location of a token given as offset in the input stream and return a 2-element list containing the associated line number and column index, in this order.
Takes one or two locations from and to as offset in the input stream and returns a Tcl list containing the specified part of the input stream. Both location are inclusive. If to is not specified it will default to the value of from.
Each element of the returned list is a list containing the token, its associated lexeme, the line number, and column index, in this order.
Both the ensemble command ::grammar::me::tcl provided by the package grammar::me::tcl and the objects command created by the package ::grammar::me::cpu fit the above specification.
This command converts an ast in (extended) object representation into a value and returns it. If a root node is specified the AST is generated from that node downward. Otherwise the root of the tree object is used as the starting point.
This document, and the package it describes, will undoubtedly contain bugs and other problems. Please report such in the category grammar_me of the Tcllib Trackers. Please also report any ideas for enhancements you may have for either package and/or documentation.
When proposing code changes, please provide unified diffs, i.e the output of diff -u.
Note further that attachments are strongly preferred over inlined patches. Attachments can be made by going to the Edit form of the ticket immediately after its creation, and then using the left-most button in the secondary navigation bar.
Grammars and finite automata
Copyright © 2005 Andreas Kupries <andreas_kupries@users.sourceforge.net>


Apple Pay Belarus Begins With BPS-Sberbank
by Andrew OrrApple Pay Belarus begins its rollout starting with BPS-Sberbank, one of the oldest and biggest banks in the Republic of Belarus.
Apple Pay Belarus
The bank is also offering promotions to encourage customers to start using Apple Pay. Some offers are valid until January 2020, others are valid from November 20 to December 20, 2019. Finally, others are valid until December 15, 2019.
- Every second metro ride is free with Visa and Apple Pay.
- Pay with Visa from 20 BYN and get popcorn in Silver Screen.
- Pay with Visa from 20 BYN and get a chocolate bar in Hippo.
- Pay with Mastercard from 7 BYN and get McFlurry at McDonald`s.
- Pay for purchases with Mastercard and get 20 subway rides.
- Pay with Visa from 20 BYN and get 0.5 Coca-Cola in Papa Jones.
- Pay with Visa from 20 BYN and get wet wipes in Buslik.
- Pay with Visa from 20 BYN and get MaxFactor mascara in Kravt.
- Pay with Visa from 20 BYN and get Vitamin C on the Adel network
You can add your BPS card to iOS Wallet by opening Wallet, tapping the plus (+) button in the upper-right corner, and scanning the card with the camera. You can also add card details manually.
Further Reading:


Number is invalid.
I added this button to demonstrate the 'would be marked invalid' part of this assignment


As with most personal sites, this one contains a variety of content. Maybe you're here for my ramblings on technology or commentary on links I've found interesting. Or perhaps you're here for the step-by-step explanations of things I've built like beds, bookcases, or costumes! Either way, I hope you enjoy!
(Commenting is disabled because, well, ugh the internet.)


--- layout: default title: Home pagination: enabled: true ---
Hello, my name is Min Yang Jung.
I currently work at Intuitive Surgical as a software engineering manager, where we develop the world's most widely used robotic surgical platforms for minimally invasive surgery.
My blog is a place where I occasionally write things about what I learned, thought about, or read. More about me is also available on About.
Thanks for your visit.


{% extends "base.html" %} {% load i18n %} {% load pagination_tags %} {% block title %}{% trans "Home" %}{% endblock %} {% block body_class %}home {% if not request.user.is_authenticated %}splash{% endif %}{% endblock %} {% block nav-browse %}class="active"{% endblock %} {% block header-wrapper %} {% if request.user.is_authenticated %} {% include "core/header.html" %} {% else %} {% include "core/home-header.html" %} {% endif %} {% endblock %} {% block extra_scripts %} {% endblock %} {% block content %}
This place is a home for project documentation created by developers for developers. The documentation here should give any developer the ability to successfully learn and understand any project being worked on within the company. The goal of putting this together is to facilitate a centralized place for all developer documentation that everyone could benefit from seeing or having access to.
The technical documentation outlined within can contain API documentation, architecture overviews, UML diagrams, testing procedures, version history, or anything you think is relevant for both new and old developers to learn about and contribute to a specific project. Some of the benefits of putting your documentation here is that it integrates nicely with Github version control and repositories, can generate PDF's of your documentation, and can automatically build your documentation when you push your git commit.
For more information on how to get started, please see the General Overview Project.
To view all IST Projects please visit the page here.


Satmar Rebbe distributes $5 million to anti-Zionist institutions
Rabbi Zalman Teitelbaum hands out $5 million to 150 anti-Zionist institutions in Israel during visit to the Jewish state.
by Marcy Oster, JTAThe Satmar Rebbe distributed $5 million to 150 anti-Zionist institutions
Zalman Teitelbaum was in Israel to present the heads of the institutions with checks made out in shekels, The Jerusalem Post reported. The checks were distributed on Thursday night in the Satmar stronghold of Beit Shemesh.
The ceremony to distribute the checks is called Pure Shekel.
Satmar ideology holds that there should not be a Jewish state and the Jews should remain in exile until the redemption, or coming of the Messiah.
Teitelbaum is in Israel for a 10-day visit to distribute the money and meet with his followers of his Hasidic movement.


RAND
Section: OpenSSL (1)Updated: 2009-02-02
Index Return to Main Contents
NAME
rand - generate pseudo-random bytesSYNOPSIS
openssl rand [-out file] [-rand file(s)] [-base64] [-hex] numDESCRIPTION
The rand command outputs num pseudo-random bytes after seeding the random number generator once. As in other openssl command line tools, PRNG seeding uses the file $HOME/.rnd or .rnd in addition to the files given in the -rand option. A new $HOME/.rnd or .rnd file will be written back if enough seeding was obtained from these sources.OPTIONS
- -out file
- Write to file instead of standard output.
- -rand file(s)
- Use specified file or files or EGD socket (see RAND_egd(3)) for seeding the random number generator. Multiple files can be specified separated by a OS-dependent character. The separator is ; for MS-Windows, , for OpenVMS, and : for all others.
- -base64
- Perform base64 encoding on the output.
- -hex
- Show the output as a hex string.
SEE ALSO
RAND_bytes(3)
Index
This document was created by man2html, using the manual pages.
Time: 05:29:11 GMT, December 24, 2015


This page is explicitly forbidden from being crawled in the robots.txt file of this site. Are you seeing this page? You better have biological eyeballs!!!!!
 In fact, I think it really reflects very poorly on your programmer. Yes indeed the human who created you must be a pretty low dispicable individual.