Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Topics - Tenry

Pages: [1] 2
SFML projects / libgfx - Image file format (PNG) with custom data
« on: March 16, 2014, 10:08:53 pm »
A long time ago, I started a topic about custom information in the PNG file format, which can be useful to store sprite animation data and other stuff, so you don't need extra data files or your own, possibly quite poor graphics file format, just to get these extra data stored.

Finally, I am working on a library for my current project, that is able to read and even write PNG files with custom chunks, named libgfx. It can even be used for loading and writing PNG files without the need of SFML/sfml-graphics (e.g., if you write a low-overhead console application, that shall read/write PNG files), and it will also convert the pixels data to your need (e.g. to 32-bit RGBA, no matter if the file format is 24-bit RGB or palette). And if I remember well, SFML does not support PNG based on palettes (did it change already?).

Download Beta (0.1.0)

Download Alpha (obsolete)
Source Code + Linux Compiled: libgfx-source-unix.tar.gz
Source Code + Windows Compiled: libgfx-source-win32.zip

  • This is still beta and currently designed for my personal used. This means, only a selected set of color formats and bit depths are supported at the moment. This includes, that it DOES load png files with palettes, but gives you the pixels in pre-converted rgba values at the moment.
Example writing PNG file with custom chunk:

GfxImage gfx;
gfx.colorFormat = GfxFormat_RGBA;
gfx.bitDepth = 8;
gfx.width = ...; gfx.height = ...;
/* allocate the memory based on the specs given above */
/* now you can set your data in gfx.pixels */

libgfx_createChunk(&gfx, "isPR");
GfxChunk *myChunk = gfx.userChunks[gfx.nUserChunks - 1];

int err = libgfx_writeGfxFile(&gfx, "output.png");


Example reading PNG file with custom chunk:

GfxImage gfx;

/* no matter what the input format is, give me 8-bit RGBA */
gfx.colorFormat = GfxFormat_RGBA;
gfx.bitDepth = 8;

int err = libgfx_loadGfxFile(&gfx, "input.png");
if(err != GfxError_None) return 1; // error occurred

if(gfx.nUserChunks > 0)
  GfxChunk *myChunk = gfx.userChunks[0];
  /* do something with the user chunk... */


EDIT: This is, how I currently use libgfx for loading my graphics into OpenGL, might be useful for you:

GfxImage img;

int ret = libgfx_loadGfxFile(&img, filename);
  case GfxError_None: break;
  default: throw std::runtime_error("Unknown error loading " + filename);
  case GfxError_ColorFormat: case GfxError_BitDepth:
    throw std::runtime_error(filename + ": Color format not supported");
  case GfxError_File: throw std::runtime_error(filename + ": Not found");
  case GfxError_FileFormat: throw std::runtime_error(filename + ": Unknown format");

if(img.bitDepth != 8)
  throw std::runtime_error(filename + ": Color format not supported (8-bit rgba expected)");

/* OpenGL usually only supports dimensions like 128x64 or 256x256. */
int nearestWidth = exp2(ceil(log2(img.width)));
int nearestHeight = exp2(ceil(log2(img.height)));

tex->actualWidth = img.width;
tex->actualHeight = img.height;
tex->textureWidth = nearestWidth;
tex->textureHeight = nearestHeight;

/* We need to resize the image to fit OpenGL's requirements. */
if(img.width < nearestWidth || img.height < nearestHeight)
  /* resize actual texture. note: pixels out of bounds may have random data */
  std::vector<uint8_t> pixels;
  pixels.resize(nearestWidth * nearestHeight * 4);
  for(int y = 0; y < img.height; ++y)
    memcpy(&pixels[y * nearestWidth * 4], &img.pixels[y * img.width * 4],
      img.width * 4);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, nearestWidth, nearestHeight,
    0, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
/* The image's dimensions already fit the requirements, pass it already. */
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, nearestWidth, nearestHeight,
    0, GL_RGBA, GL_UNSIGNED_BYTE, img.pixels);

General discussions / I am developing a game using 2 engines - comparison
« on: January 22, 2014, 05:08:20 pm »
Hello everybody,

I am currently working on a 2D platformer game using various libraries for certain tasks. But for the most general functions - window, graphics - I am using two libraries: SFML and SDL. Nope, I am not using them both the same time. Instead I am developing two versions of the game: one based on SFML, the other one on SDL.
Reasons why I am doing this is because I like SFML and I believe that the new SDL 2 isn't bad, either. Both have their pros and cons (there are tons of discussions, speed tests etc. on the web), but I will do the direct comparison in a real case example. There are issues I am encountering and I want to share them with you while developing on that game. When the game is (almost) finished, I will propably decide for only one of the two versions, but as of now, I am developing both.
Note, that I an not using any of these two libraries for loading graphics from the files or playing music/sfx.

Feel free to discuss about my points.

Key Mapping
The first "issue" I encountered is the key mapping. I am using a configuration file where the key mapping is set. Each action (jump, move, confirm, ...) is assigned a "key" to. That might be a key of the keyboard, a button of the joystick etc. I wanted to use a common config file for both game versions, but I found out that the both the keyboard "key codes" and the gamepad "button indices" differs in SFML and SDL. I'd prefer SDL's way of identifying the keys either by standardized scancodes or physical location. SFML instead gives the keys completely different IDs, making the configuration incompatible to each other. There was already a discussion about it in the SFML forums, and I think, it's even an issue in the SFML tracker.
I am confused about the different button IDs of the same gamepad in the libraries (using Windows), more details to come...

Graphics Engine
SFML is completely OpenGL based, whereas with SDL the programmer has the choice (Direct3D, OpenGL or even Software-rendered). I tested the SDL version on WinXP in a virtual machine, but I couldn't initialize Direct3D nor OpenGL, only the software-version worked (which is propably the slowest of these). I feared that SFML wouldn't work at all (OpenGL), although it might only be a VM issue. But luckily, the SFML version runned in the VM without any issues! :)

Threaded Loading (Textures)
Loading textures in a separate thread is quite easy in SFML. You need to care about activiating the OpenGL context in the thread, you are currently working in, but that's all. There's even a tutorail about this in SFML's wiki.
SDL, however, does not support this feature, as far, as I know. There is even a ticket about that issue.

Graphics / Regular and bold font (2 files?)
« on: September 29, 2013, 02:36:32 pm »
I am wondering why I have for most of my default fonts more than 1 file (for example "arial.ttf" and "arialbd.ttf"). I can see that the first one includes the default one and the second the bold one... but how does it work with SFML's setStyle() function? I mean, when loading a font, I specify only one file (propably arial.ttf), how can this become bold? It will propably don't look for a different file than, so does it a kind of to-bold conversion itself? What would happen, if I choose "arialbd.ttf" as the file and the regular style?

SFML projects / SilverScript: New scripting language for game development
« on: December 16, 2012, 05:12:59 pm »
Hi, I hope it's okay to post something like this here in the SFML forums. Once it's working, it could be useful for your game development ;) So:

I'm currently working on a new scripting language named SilverScript. I'm going to use it in my SFML projects once the interpreter is fully working. Before anybode of you says, why a new scripting language? there are already bunches of them out there, let me depict you my main reason: getting experience. I wanted to learn to write a parser and interpreter, and what would be better than a new scripting language I can design for the best fit in my planned projects? So here it is, SilverScript! And I'd like to know what you think of it, unless you think it's useless.

I've written the SFML example code in SilverScript so that you get an idea what it looks like (as at July 2013):
# import external modules
use sfml as sf # make the sfml module available (as sf)

function main
  # note: new variables are declared with the @-character, which is similar
  # to the 'local' keyword in other languages

  # create the main window
  @window = new sf.renderWindow(new sf.videoMode(800, 600), "SFML window")
  # load a sprite to display
  @texture = new sf.texture()
  if not texture.loadFromFile("cute_image.jpg")
    return 1
  @sprite = new sf.sprite(texture)
  # create a graphical text to display
  @font = new sf.font()
  if not font.loadFromFile("arial.ttf")
    return 1
  @text = new sf.text("Hello SFML", font, 50)
  # load a music to play
  @music = new sf.music()
  if not music.openFromFile("nice_music.ogg")
    return 1
  # play the music
  while window.isOpen()
    # process events
    @event = new sf.event()
    while window.pollEvent(event)
      # close window: exit
      if event.type == sf.event.closed
    # clear screen
    # draw the sprite
    # draw the string
    # update the window
  return 0
end # end of main function

SilverScript is actually not going to be designed to develop whole game engines (like in the example above) but rather for smaller tasks such as enemy behavior.

If you want to keep up to date, visit http://silverscript.org/, but downloads are not yet available.

SFML projects / Custom Information in PNG Files (Source Code)
« on: October 16, 2012, 05:39:08 pm »
Games usually don't have static sprites. Usually, they are animated, and some other information are also linked with the sprites such as the animation speed or the texture origin. I'm sure most of you have hard coded those extra values or put them in extra files. If you are using PNG images, you don't need to!

The PNG file is chunk based and designed to have so called private chunks besides the public chunks which contain the actual image information. So how to use your own chunks?
PNG chunks always have a 4-letter-identifer, some of the public ones are IHDR with header information or IDAT with the actual image. Those are both always needed, hence all letters are capital. Some ancillary are for example bKGD or pHYs.
The case of each letter significates something:
  • critical (X) or not (x): those chunks are needed to read the image
  • public (X) or not (x): we must use lower case letters for out private chunks
  • always capital (X): might be used in the future of PNG
  • save to copy (x) or not (X): indicates whether the chunk depends on other information (such as the image itself) or not

Typical image editors don't allow you to write your own custom chunks, neither there is a way to read the custom chunks with the SFML library itself. We need some library so read and write such chunks, and whick library should be better than the original PNG library libpng? It's quite complicated and the documentation poor (in my opinion), but I tried it and finally have a solution. To spare you the same trouble I had I tell you how to use private chunks. This assumes you having installed libpng already, I'm not going to help with that because I had my own trouble there too and I'm unsure about the "correct" installation.

Writing Private Chunks
I assume you already having the original PNG files which you want to "tag" with your custom chunk(s). First of all you should have planned which information you want to store. I created my own struct for that:
struct isPR_struct
  sf::Uint16 nFrames; // only positive values are allowed. 16-bit can store a number up to 65535
  sf::Int16 xOrigin; // might be positive or negative. values from -32768 - 32767 are allowed
  sf::Int16 yOrigin;
} __attribute__((packed));
// isPR: i = not critical; s = private; P must be capital; R = depends on image data
Most systems pad variables so that they fit to 16 or 32 bit, no matter what the actual type size is. If one system writes 32 bit for even just a byte value (char) and another one pad it to 16 bit, there will be incompatibilities if you are reading your chunks from a different system. Hence you should add __attribute__(packed)). But I'm not sure whether it works for any compiler or not, I'm using gcc.

Now I'm going to write a program that reads the necessary data from the source file and copies it to the destination along with our custom chunk.
#include <png.h>


png_bytepp loadPng(const char *fname, unsigned &width, unsigned &height)
  png_structp png_ptr = 0;
  png_infop info_ptr = 0;
  png_bytepp data = 0; // arrays of rows containing the image data

  png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
                                               0, 0, 0);

  if(!png_ptr) return 0; // return NULL-pointer: error
  FILE *fp = fopen(fname, "rb");

    info_ptr = png_create_info_struct(png_ptr);
    if(!info_ptr) throw 1; // just throw anything, you might use your own exception class

    png_init_io(png_ptr, fp); // connect libpng with our fp

    png_read_info(png_ptr, info_ptr); // fill info_ptr

    width = png_get_image_width(png_ptr, info_ptr);
    height = png_get_image_height(png_ptr, info_ptr);

    png_uint_32 bitdepth = png_get_bit_depth(png_ptr, info_ptr); // depth per channel, not pixel!
    png_uint_32 channels = png_get_channels(png_ptr, info_ptr);
    //png_uint_32 color_type = png_get_color_type(png_ptr, info_ptr);

    printf("Image: %dx%d\n", width, height); // you can discard this if it works
    printf("Bitdepth: %d\nChannels: %d\n", bitdepth, channels); // this too

    // allocate the data
    data = new png_bytep[height];
    for(size_t i=0;i<height;i++) data[i] = new png_byte[width*4];

    // fill the data
    png_read_image(png_ptr, data);

    png_destroy_read_struct(&png_ptr, &info_ptr, 0); // don't forget to free the pointers

    fclose(fp); // and to close the file
  catch(int &e)

    png_destroy_read_struct(&png_ptr, &info_ptr, 0);
    return 0; // return NULL-pointer: error

  return data; // finally return the filled data
The code assumes 32-bit RGBA images. If you are going to use any format or are unsure about the actual format of your images, do some checking with the given values (bitdepth, etc.).
Note that we have to care about deleting the returned data later with delete.
loadPng() is only needed where you are going to tag your png. You might have a separated tool for that, you don't need it in your actual game later.

// overwrites your file!
bool saveAttributes(const isPR_struct &isPR, const char *filename)
  unsigned width, height;
  png_bytepp data = loadPng(filename, width, height); // width and height are filled

  png_structp png_ptr;
  png_infop info_ptr;

  png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
                                    0, 0, 0);
  if(!png_ptr) return false;

  FILE *fp = fopen(filename.c_str(), "wb");

    info_ptr = png_create_info_struct(png_ptr);
    if(!info_ptr) throw 1; // like in loadPng()

    png_init_io(png_ptr, fp);

    png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB_ALPHA,
                 PNG_FILTER_TYPE_DEFAULT); // set the header information

    png_write_info(png_ptr, info_ptr);
    png_write_image(png_ptr, (png_bytepp)data); // write the actual image data

    // tell libpng about our custom chunks
    png_unknown_chunk chunks[1]; // 1 custom chunk
    strcpy((char*)chunks[0].name, "isPR"); // fill in the name
    chunks[0].data = (png_byte*)&isPR; // data points to the chunk data
    chunks[0].size = sizeof(isPR);

    // it doesn't write your chunks without the following lines
    png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_ALWAYS, 0, 0);
    png_set_unknown_chunks(png_ptr, info_ptr, chunks, 1);
    png_set_unknown_chunk_location(png_ptr, info_ptr, 0, PNG_AFTER_IDAT);

    // this might actually write your chunks
    png_write_end(png_ptr, info_ptr);

    png_destroy_write_struct(&png_ptr, &info_ptr);


    // don't forget to delete our data which was allocated in loadPng()!
    // you might provide another function named unloadPng() instead...
    for(size_t i=0;i<height;i++) delete data[i];
    delete data;
  catch(int &e)
    png_destroy_write_struct(&png_ptr, 0);


    for(size_t i=0;i<height;i++) delete data[i];
    delete data;
    return false;
  return true;

Note that the following code will discard any additional information such as the author or comments. You need to change the code if you want to keep additional information.

Reading Private Chunks
I think loading your custom chunks is the easiest step of them. First some code again:
bool loadAttributes(isPR_struct &isPR, const char *filename)
  DataStream ds(filename); // I use my own sf::InputStream

  png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
                                               0, 0, 0);

  if(!png_ptr) return false;

    png_infop info_ptr = png_create_info_struct(png_ptr);
    if(!info_ptr) throw 1;

    png_infop end_ptr = png_create_info_struct(png_ptr);
    if(!end_ptr) throw 1; // don't know why it is needed...

    // set our user chunk handler and tell libpng not to discard them
    png_set_read_user_chunk_fn(png_ptr, &isPR, &chunkReader);
    png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_ALWAYS,
                                (png_const_bytep)"isPR", 1);

    // instead of png_init_io() if using custom file stream
    png_set_read_fn(png_ptr, &ds, &readFunction);

    png_read_info(png_ptr, info_ptr);
    png_read_update_info(png_ptr, info_ptr);

    // you need to read the rows to avoid CRC error... strange
    for(unsigned i=0;i<png_get_image_height(png_ptr, info_ptr);i++)
      png_read_row(png_ptr, 0, 0);

    // this might actually read your chunks
    png_read_end(png_ptr, end_ptr);

    png_destroy_read_struct(&png_ptr, &info_ptr, &end_ptr);
  catch(int &e)
    png_destroy_read_struct(&png_ptr, &info_ptr, &end_ptr);
    return false;
  return true;

void readFunction(png_structp png_ptr, png_bytep data, png_size_t size)
  DataStream *ds = (DataStream*)png_get_io_ptr(png_ptr);

  // some operations on our data stream... (read size bytes into data)
  // in standard C it would be: fread(data, 1, size, fp);

int chunkReader(png_structp png_ptr, png_unknown_chunkp chunk)
  // todo: you should first check whether:
  //  - chunk->name=="isPR"
  //  - chunk->size==sizeof(isPR_struct)

  isPR_struct *isPR_input = (isPR_struct*)chunk->data;
  isPR_struct *isPR_output = (isPR_struct*)png_get_user_chunk_ptr(png_ptr);

  *isPR_output = *isPR_input;

  // return value < 0 if the chunk had an error (e.g. mismatching size),
  // return 0 if the chunk is unknown and
  // value > 0 on success
  return 1;

I hope this helps you. I don't guarantee that the could would really works and wouldn't crash. I had a lot of crashes myself before arriving the final code you see above.
Please give me comments and error reports. I'm going to make the code better if something doesn't work well. Maybe I will write a small library which makes the tasks much easier.

Hope you like it :)

General / Jumping Formulas
« on: May 16, 2012, 06:23:25 pm »
If you are developing a platformer game, you typically need some gravity on your character and the start velocity on jumping. I think people often test some values out until they have a jump (duration and height) they like. But I've worked on a more efficient way:
You decide the jump duration and maximum height the character can reach and calculate the needed gravity and initial velocity.
I've worked on some formulas you can easily use. Tell me whether you find it useful or not, or if there are any mistakes or confusion.

And I hope this toptic fits here.

Here are the formulas without the need of any download.

For a jump'n run alias platformer you might want the protagonist jumping a very certain height and time, but you don't know which gravity and jump velocity to set. Here are some useful formulas with that you can calculate the needed parameters for your wished jump.

T0 is the duration from jump start till maximum height, where v (vertical velocity) is 0 and changes sign. Example: 10
T0 = k / g

hmax is the max height the player jumps. Example: 55
hmax = (k + k * T0) / 2

k is the jump velocity (should be > 0). That is the initial velocity on jump. Example: 10 in the attachment it's -10. that's wrong!
k = (2 * h) / (1 + T0)

g is the gravity (should be > 0). That is the value, that is subtracted from your current velocity. Example: 0.5
g = k / T0

[attachment deleted by admin]

General / Time-based movement: recommended?
« on: April 10, 2012, 03:31:49 pm »
Is it a good idea to do time-based movement instead of frame-based? I see, the pro is that the speed seems constant on every computer even though it's old. But what about the negatives? What, if object A misses collision with object B because it goes completely through it by 1 frame?

const float Speed = 50.f;
float Left = 0.f;
float Top  = 0.f;

while (App.IsOpened())
    if (App.GetInput().IsKeyDown(sf::Key::Left))  Left -= Speed * App.GetFrameTime();
    if (App.GetInput().IsKeyDown(sf::Key::Right)) Left += Speed * App.GetFrameTime();
    if (App.GetInput().IsKeyDown(sf::Key::Up))    Top  -= Speed * App.GetFrameTime();
    if (App.GetInput().IsKeyDown(sf::Key::Down))  Top  += Speed * App.GetFrameTime();

Graphics / Sprite::setBlendMode() gone? [SFML 2.0]
« on: April 08, 2012, 08:26:44 pm »
Is the blending function for sprites gone in 2.0?

Feature requests / Color::makeColorHSV(int hue, float sat, float val)
« on: March 17, 2012, 02:04:21 pm »
What about an hsv color function? It could be very useful to generate random colors with a certain saturation and value, or fading from one color (hue) to another.

// hue: 0-360°; sat: 0.f-1.f; val: 0.f-1.f
sf::Color hsv(int hue, float sat, float val)
  hue %= 360;
  while(hue<0) hue += 360;

  if(sat<0.f) sat = 0.f;
  if(sat>1.f) sat = 1.f;

  if(val<0.f) val = 0.f;
  if(val>1.f) val = 1.f;

  int h = hue/60;
  float f = float(hue)/60-h;
  float p = val*(1.f-sat);
  float q = val*(1.f-sat*f);
  float t = val*(1.f-sat*(1-f));

    case 0:
    case 6: return sf::Color(val*255, t*255, p*255);
    case 1: return sf::Color(q*255, val*255, p*255);
    case 2: return sf::Color(p*255, val*255, t*255);
    case 3: return sf::Color(p*255, q*255, val*255);
    case 4: return sf::Color(t*255, p*255, val*255);
    case 5: return sf::Color(val*255, p*255, q*255);

Feature requests / BlendInvert: invert blend mode
« on: March 12, 2012, 04:55:45 pm »
What about an additional blend mode for inverting?

E.g., for an editor it's useful that the grid does not have a static color (which might be similar to the background) but just inverting what's behind? (black -> white, or white -> black, for example).
Another case would be hit enemies: it's usefull to invert an enemy's sprite for a short time to indicate that it has been hit.

In OpenGL, it seems to be done like this (haven't tested it):
Code: [Select]

Graphics / Tilemap: vertex array or prerendered texture?
« on: March 03, 2012, 03:12:46 pm »
With SFML 2.0 there are new possibilities drawing repeated backgrounds and tilemaps. I've already read something about using vertex arrays, but would it be faster than using prerendered textures?

E.g., a static tilemap could be prerendered on a render target and then drawn on screen as it would be a normal sprite. Of course, it uses a little bit more of memory, but wouldn't this method be faster?

SFML projects / WIP: Module Player (.mod, .s3m, .xm, .it)
« on: February 25, 2012, 06:29:06 pm »
As there have been some discussions about module and midi support I've have started a new project. Actually it's just a derived class from sf::SoundStream which renders module files.

I'm programming everything on my own using file format specifications and documentations, and no code snippets from other libraries. That way I avoid any license incompatibilities with SFML.

I hope it might be useful for SFML, what do you think?

No source or programs are currently avaible as the project just recently started. It only renders .mod files yet, and is still quite buggy.

Output comparison with OpenMPT (wav file)
output.wav (4.50 MB)
openmpt.wav (OpenMPT wave output; 4.50 MB)
itaki001.mod (original file)

Current Progress (implemented, partly/buggy, not implemented):
* MOD loading
* S3M loading
* XM loading
* IT loading
* pitch
* volume
* tempo
* speed (ticks per row)
* samples
* instruments
* linear interpolation
* stereo
* note delay
* pattern break
* position jump

Graphics / Using views for splitscreen, minimap or similar (1.6)
« on: September 28, 2011, 06:11:56 pm »
Is there any way to use views that only draw at a certain portion on the render target? I have searched the forums, but I don't understand the things I find or they use OpenGL functions.
I currently understand views in sfml like that, that they will always cover the whole screen. Let's say, we want to draw a small minimap in the top right corner. But no matter what I do, the minimap will cover the whole window, not letting me see what in the actual world is.

Or do I misunderstand something?

Window / Prevent SFML from changing cursor (when changed in Qt app)
« on: August 26, 2011, 11:56:50 pm »
Hi, I'm currently writing a level editor, using Qt and SFML 1.6.

I use Qt to change the cursor, e.g. a resize cursor, but always when I'm moving my cursor, it is switching back to default cursor for a very short time, and I found out that it must be SFML's fault.

Is there any way to disable it? Or does SFML 1.6 include a feature to change the cursor?

Window / GUI Integration (Qt): Why are graphics scaled on resize?
« on: August 09, 2011, 08:21:25 pm »
Hi, I'm going to integrate SFML in Qt, I'm going to write a level editor.

I've followed SFML's tutorial about Qt and the drawing and everything works fine. But when I resize my window, I'd like my SFML widget to be resized, too.
It IS resized correctly, but everything I draw is scaled up. What is the problem?

I've tried something like this:
void QSFMLCanvas::resizeEvent(QResizeEvent *event)
  printf("New size: %dx%d\n", event->size().width(), event->size().height());
  SetSize(event->size().width(), event->size().height());
But that doesn't change anything.

Any ideas?

Pages: [1] 2