Not logged in, Join Here! or Log In Below:  
 
News Articles Search    
 


Submitted by Rui Martins, posted on January 03, 2005




Image Description, by Rui Martins



These are images from "Magnetic Fields", a Puzzle/Action game I'm developing in my spare time.

The Game Concept revolves around basic "Electro" Magnetic Principles, hence the name. However, I'm inclined to change it, since Magnetic Fields was the name of a Software Publisher from the times of the Sinclair Spectrum, which I believe are still active, although there site seems to be down at the moment. Suggestions for a catchy name are welcome.

Magnetism has a few interesting properties:
  • At least two poles are required for interaction to occur.
  • Magnetism Power fades exponentially with distance.
  • Similar signed (+/+ or -/-) poles repel each other
  • Opposite signed (+/-) poles attract each other.
  • These properties are the basis of game play in this game.

    Game Play: Each level is composed of particles (poles), goals(objectives) and Energy.
  • Particles can have, transfer and receive energy(charge).
  • Goals are the level objectives and have particles as completion targets.
  • Energy is available on each level to change the Particles Charge.
  • Your mission is to place the targeted particles in their objectives (goals), using the available energy to influence their properties and indirectly their dynamic physical behaviour. To finish a level, you have to complete all the goals. A goal is considered complete as soon as its targeted particle touches it.

    Positive and negative Energy(Charge) are color coded, RED and BLUE (CYAN) respectively.

    The Game uses OpenGl(graphics), OpenAL(Audio) and GLUT (as OS abstraction layer).

    For the ones that don't read README files:
  • Use Cursor keys in Menus( mouse doesn't work there yet).
  • Yellow and Red arrows are a particles Speed and Net Force, respectivelly.
  • Goals are represented by Bluish round areas.
  • Hovering the mouse over any particle will seleect it automatically (green aura will appear).
  • Left and Right Mouse Buttons apply (zap) Energy into the currently selected particle.
  • Hovering the mouse over a Goal, shows the targeted particle (rotating blue star over it) by that specific Goal (if nothing is shown, any particle will complete it).
  • If you fail a level press "R" for "Retry/Reset".
  • First few levels (10) of the 22 available serve as a tutorial to get you up to speed in the game.

    TIP: Level Titles may give useful insight on level solution. Any comments on game play are very welcome.

    Download the Game here: http://RuiMartins.Net/software/download/Magnetic_0.07Release.zip

    NOTE: You need an OpenGL driver, OpenAL and GLUT. Unzip the following file inside "Magnetic" Folder if you don't have these files installed in your system (OpenGL is Not Included, Only OpenAL and GLUT). http://RuiMartins.Net/software/download/Required_Files.zip

    Final Note: This is an early Alpha Release of the Game, so bugs may creep up, and Debug messages are visible on the console window. For example, when game window is resized, Energy Bars aren't reset to the proper place (they may disappear or stay in the middle of the screen), "Retry/Reset" the Level will solve the problem.


    [prev]
    Image of the Day Gallery
    www.flipcode.com

    [next]

     
    Message Center / Reader Comments: ( To Participate in the Discussion, Join the Community )
     
    Archive Notice: This thread is old and no longer active. It is here for reference purposes. This thread was created on an older version of the flipcode forums, before the site closed in 2005. Please keep that in mind as you view this thread, as many of the topics and opinions may be outdated.
     
    Chris

    January 03, 2005, 12:39 PM

    WOW, super cool. Starting with the "inner turn" level I got really interested, and now this is highly addictive.

    Polish the graphics a bit (it's hard, I know). And I'd like to run it in fullscreen.

    Given another 50 levels I'd likely spend a day playing it w/o eating. Really great work.

    The "orbiting is a balance" level solves itself if you wait some minutes. Is this by intention ?

    I'm particularly interested in the maths, did you build an ODE solver ? Which methods did you use ? What about stability over time ?

     
    ReaperUnreal

    January 03, 2005, 12:40 PM

    Looks like a cool game, I think I've played a gravity game that was slightly similar. There's just something wrong with your game. You mention + and - charges, but only electricity has + and - charges, magnetism has N and S poles. Also, you can never have a N without a S pole. So really, you should be talking about electrostatic charge, not magnetism. Other than that, looks like great fun! Also, electrostatic charge fades with 1/r^2 not e^-r. So it should be inversely quadratic, not inverse exponential.

     
    Chris

    January 03, 2005, 12:44 PM

    And there are definitively some numerical stability issues when the spheres come close. I noticed this in the "bi-stable orbits" level.

     
    Daggett

    January 03, 2005, 12:59 PM

    That's a lot of fun, very addicting! It just needs a bit of polishing here and there, that's all.

     
    timm

    January 03, 2005, 01:58 PM

    isn't it 1/d^3??

     
    Rui Martins

    January 03, 2005, 02:21 PM

    ... I'd like to run it in fullscreen.


    Then just Select full screen with the Right Mouse Button when in the Menu Screen. It's Glut full Screen, which basicly means, it is a resized window to cover the entire desktop. I have to use Game Glut for correct full screen.

    Some alignment problems will be obvious in the Menu Screeen once you resize the Window.

    Given another 50 levels I'd likely spend a day playing it w/o eating. Really great work.

    If you want, you can make some levels, currently the level structure is very simple, and it's a text file.

    The "orbiting is a balance" level solves itself if you wait some minutes. Is this by intention ?
    The Levels are supposed to have specific time to complete them, if not you fail it, and have to retry. Not implemented yet. But the Orbiting is not perfectly balanced, that is why the Particles tend to reach further away from each other on each interaction.
    ...did you build an ODE solver ? Which methods did you use ? What about stability over time ?
    All the physics (integrator) and collision were made by me and sometimes gave me some hard time to get right. Didn't notice any stability problems, unless in the situations that I don't handle yet, like multiple simultaneous collisions.

     
    Rui Martins

    January 03, 2005, 02:23 PM

    Can you be more specific about it.
    Thanks.

    P.S.
    Are you sure it isn't a multiple collision problem ?
    (the one not yet handled?)

     
    Rui Martins

    January 03, 2005, 02:25 PM

    Please be more specific, it helps a lot.

    I have a todo list already, but earing other people (developers/players) comments always helps a lot.

    Maybe there is something I have missed on my list. 8)

     
    Rui Martins

    January 03, 2005, 02:29 PM

    According to my reference it's 1/d^2.
    And it seems to work ok with this setting.
    I'm actually using the real Magnetism constant K (9.0E-9), no cheating here.

     
    BrainMaster

    January 03, 2005, 04:03 PM

    It's nice to see people who went to the same university in which I'm studying posting an IOTD here :) Somehow, it doesn't seem to exist many portuguese people interested in developing games. I wonder why...

     
    Rui Martins

    January 03, 2005, 04:14 PM

    Actually it's my second IOTD here, but only for lack of time. Like with most fellow flipcoders, real life kicks in and we have to do this stuff in the hours we should be sleapping, and all for the love of "The Sport".

    I know a few Portuguese that like to develop games, but unfortunatly Portugal has a too small market to be attractive for small developers, but internet globalization may change that.

    But it's very difficult (closer to impossible) to live from it as an independent developer.

     
    Rui Martins

    January 03, 2005, 04:26 PM

    ... You mention + and - charges, but only electricity has + and - charges, magnetism has N and S poles. Also, you can never have a N without a S pole.


    I know what you mean, but there are two reasons for it.
    First, the concept of the game is easier to understand when related with magnetism, since everyone knows what a magnet is and how it works.
    Second, it actually is correct to call it magnetism, since we are talking about "Particles", it all depends on how close to the atom are you looking at it. However I have abused the language, when talking about Poles, but it was in the interest of a better understanding of the concept.

    And you are right, Magnetism only works with DiPoles (N/S), that is why the first level is called "MAGNETISM TAKES TWO".

    ... electrostatic charge fades with 1/r^2 not e^-r. So it should be inversely quadratic, not inverse exponential.

    Well, here I can only say that my english betrayed me, it's not my mother tong. I actually use the 1/r^2 ratio since it's part of the correct magnetism expression.

     
    Chris

    January 03, 2005, 05:12 PM

    It is multiple collision, or at least the time delta is so small that I cannot tell the two collisions apart. I managed to bump all three particles into each other, and they were catapulted off into weird directions.

    If you don't handle it, all is ok, I think.

    What ODE integrator method do you use ?

     
    Rui Martins

    January 03, 2005, 05:23 PM

    Some extra info:

    I use a fixed refresh rate of 120hz for the physics simulation. Frame Rate is free to vary at will.

    This is fundamental for a good and stable simulation and also for a feature that I have planned from the beginning "Replay".
    I'm also planning a subfeature of replay, if the levels get too difficult, which is to replay your last attempt, until you interfere in the replay by zapping one of the particles (i.e. taking action), signaling the end of the replay and the start of the interactive part. However this can make some levels too easy.

    Once timming is implemented, one can make a highscore where a replay of the best play could be shown.
    This is also usefull to animate previous completed levels on the background of the Menu Screen.

    The collision detection is continuous, i.e. it is not possible to miss a collision, even when the particles (spheres) speeds are very hi, since a sphere translation volume (similar to a "cylinder") is used to check for collisions. Once a collision is detected, the exact timing of the occurrence is calculated, so that the trajectory of both spheres can be correctly calculated. Finally the remaining time in the time-step is applyed to both spheres, using the new velocity vector.

    This is where the multiple collisions fail, since this should be recursive, and currently I only scan each possible particle pair once.

    the correct way would be to determine the collision that happens first in each simulation step, and then simulate that, then find if there are any more collisions ahead in this simulation step, if there are, find the first one, and so on until you can get to the end of the time step.

    There is also the possibility of more than 2 Spheres colliding at the exact same time and this kind of special cases are the hardest nuts to crack.

    I also intend to provide some FIXED particles, i.e. particles that don't move but have all the Magnetic properties. This may be required, to improve the game play of more complex levels, since as soon as the number of particles starts to grow, the complexity of the system (degrees of freedom) also increases, expecially for the user, which will have a hard time to predict what will happen. However, the power fading with distance property of magnetism helps a lot here, which currently balances the game very well.

    Another improvement that I'm considering is to have generators, i.e. Fixed Particles, which will force their charge/energy to specific value. This is important when the particles collide, since they add up the charge and split it equally by them.

    The final twist I'm thinking to implement/experiment is long fixed cylindrical particles, which could be a way to accelerate other particles through a tunnel, similar to the effect witnessed in the level "Tunnel Squash".

    The initial levels are too simple or easy, but I found them to be required, after testing the game with a few players. They provide a less steep learning curve which is essential to coatch the player and preventing him to quit too soon, due to inability to compreend the game play mechanics. I was a bad judge of this problem, since for me, the designer and tester of the game, it seamed too natural either by knowing it from the inside out or by knowing the mechanics behind it too well, due to excess play testing 8).
    But sometimes even I discover new ways to play the game, which I then use to make new levels hopping to pass that knowledge onto others playing these levels.

    This post is already too long, so I will end by making a question:
    Did you guys experience any sudden increase in difficulty between any of the levels ?

    I'm very pleased to know that you guys also like the game, that is why we make these things isn't it!?

     
    Rui Martins

    January 03, 2005, 06:47 PM

    What ODE integrator method do you use ?


    Well, I use a simple Euler integrator, mainly because I had to make some voodoo on the collision response code, since the current implementation doesn't make it easy to handle the collisions early in the time step, meanning that I have to predict what the Integrator will do, so that I can compensate for it when a collision occurs, so that the final result ends up correct.

    I could use an RK4 (Runge Kutta 4th order) integrator, but with my current implementation this would be a real pain. First I have to refactor my code to handle multiple collisions, and once that is correctly implemented, than I can easily change to a RK4 integrator.

    Apart from improved accuracy, I don't see any major benefit on the simulation in it's current state.
    This game doesn't suffer from precision as much as others, since the simulation is self contained, and soon will be time limited, so the error accumulation doesn't make any visible damage, it doesn't have time to 8).

    Improving the accuracy will have an impact on the current levels setup, which will need to be adjusted to maintain the same game play as before.

     
    Rui Martins

    January 03, 2005, 07:18 PM

    I realised that the level format is not in the Zip file, so here it is for the ones who want to try build some levels.

    A Level filename must follow the following format:
    Level_xxx.MGN

    Where xxx is the level number. Levels should not have gaps between them, i.e. after Level_022.MGN, should be Level_023.MGN
    If you keep adding levels, they game will continue to play, as long as there are levels available (until 999).


    LEVEL FORMAT

    Each line (terminated with a LF/CR) is a record.

    Records have their fields separated with white space (Spaces or Tabs), except in the "Title" Record

    Each record first field represents it's type:

    Title Record format:

    1. T       title-text-that-can-have-white-space-inside
    NOTE 1: Titles should not exceed a maximum of 32 chars, including spaces, or the Title will overflow the screen area in smaller resolutions.
    NOTE 2: Title characters MUST be all UPPERCASE.

    Config Record format:
    1. C       level-negative-energy-available level-positive-energy-available
    NOTE: Energy bars are capped at 100000 energy units


    Particle Record format:
    1. P       XPos  YPos  ZPos        XVel  YVel  ZVel        initial-charge
    NOTE 1: Although the level is 3D, the game play currently works on the XZ plane with Y=0. So don't set the Y values to anything other than 0.00
    NOTE 2: Look at the provided levels, for reference values.
    NOTE 3: The first particle defined on the level becomes the default selected particle. To change the default selected particle, reorder the particles definitions, but don't forget to update the Goals target-particle indexes


    Goal Record format:
    1. G       XPos  YPos  ZPos        goal-radius  targeted-particle-index
    NOTE 1: targeted-particle-index, is the index of the particle that will complete the Goal. If this value is set to 0, any particle will complete the goal.
    NOTE 2: Particles are numbered starting from one (1), in the order they are defined in the file.


    FINAL NOTES
    You should have in a level at least:
    - two particles
    - one goal

    You can have as many Particles and Goals as required.

     
    Victor Widell

    January 04, 2005, 04:44 AM

    Cool. You need a FastForward button, though. Some levels are very slow at the end.

     
    Rui Martins

    January 04, 2005, 05:16 AM

    ... You need a FastForward button, though. Some levels are very slow at the end.

    This is evidence that you need to practice more 8)
    The problem is that you didn't spent your energy in an optimum way (wiselly), but still can barelly make it through the level.

    A typical example, is to Zap a Particle with too much (+) energy, which later you need to undo, by zapping it with (-) energy, leaving you very few energy to be able to impose some speed on the final run.

    If you learn to use well what I call "orbital slingshot", you will improve the "game speed".
    After a few tries, you get better at it, and the particles pick up speed.

    You can also use "Attract and Bump" to propel a particle at hi speeds, but it's alot harder to master, because it highly depends on the collision angle.

     
    Daggett

    January 04, 2005, 05:31 AM

    Ok, just a few things i noticed:
    *A save option to save your progress
    *A tutorial or walkthrough to get you started
    *Contact sounds
    *Replays
    *The three/four way particle interactions look odd, it might be correct though, i don't know :)

     
    Rui Martins

    January 04, 2005, 05:42 AM

    *A save option to save your progress *A tutorial or walkthrough to get you started *Replays


    These are already on my TO DO list.
    However, how to make the tutorial is still in the open.

    *Contact sounds

    Need to find a good FX for that.
    Should it be a "CLING" metallic sound or a kind of "ZEEBTSH" Energy transfer like sound ?

    Should the soundFX Volume be proportional to the colliding speed ?
    I think it would be best, but currently is difficult to implement it given my current code structure, which controls Sound from the Main Application, which handles the System glue, including sound.

    *The three/four way particle interactions look odd, it might be correct though, i don't know :)

    Currrently, multiple simultaneous (as in the same time-step) collisions aren't supported correctly yet.

    Thanks for your input.

     
    Danny Chapman

    January 04, 2005, 07:53 AM

    Very fun to play (thanks for entertaining me this lunchtime :) You ought to change the terminology though - magnetic monopoles don't exist and will annoy anyone with a basic background in physics!

     
    MatthiasLange

    January 04, 2005, 10:28 AM

    I can't see the goals and the arrows. :-(

    http://img57.exs.cx/img57/7615/moep3ep.png
    Is that picture normal? ;)

    The game might be funny, but I never knew why the levels ended and I don't know what to do at INNER TURN. I guess that's because I can't see the goals.

     
    Rui Martins

    January 04, 2005, 10:49 AM

    No! The picture is NOT normal.

    Aparently you have a problem related with not showing any elements that are blended, this is partially transparent.
    This could be an OpengL Driver problem, or some weird setting you made on the driver.
    It can also be a problem on my code, but you are the first to have this problem, or at least the first to tell me about it, and it works well on every computer I personally tried it on.

    What are your computer specs, specially, your graphics card and current driver.

    If you have a fast CPU (1GHz+), you can try using the Microsoft OpenGL Software implementation. It should work OK, since I have developed part of it using it, and the game isn't graphics intensive.

    NOTE: If you can't find OpenGL (OpenGL32.DLL) on Microsoft WebSite, I can send you a copy by EMail.

    Thanks for report.
    P.S.
    Can you send me a Copy&Paste of all the text in the console window (Black Window with text on it), as soon as you start up the game, Thanks.

     
    MatthiasLange

    January 04, 2005, 04:20 PM

    I just tried an other OpenGL game and I could see the alphablended stuff.

    Here's the console text:
    [GL INFO]
    GL_VENDOR : 'ATI Technologies Inc.'
    GL_RENDERER : 'RAGE 128 x86/SSE'
    GL_VERSION : '1.2.1652 Win2000 Release'
    GL_EXTENSIONS: 'GL_ARB_multitexture GL_ARB_texture_border_clamp GL_ARB_texture_e
    nv_add GL_EXT_texture_env_add GL_ARB_transpose_matrix GL_ARB_vertex_blend GL_ATI
    _texture_mirror_once GL_ATI_vertex_shader GL_ATI_vertex_streams GL_ATIX_vertex_s
    hader_output_point_size GL_EXT_abgr GL_EXT_bgra GL_EXT_clip_volume_hint GL_EXT_c
    ompiled_vertex_array GL_EXT_draw_range_elements GL_EXT_fog_coord GL_EXT_packed_p
    ixels GL_EXT_rescale_normal GL_EXT_secondary_color GL_EXT_separate_specular_colo
    r GL_EXT_stencil_wrap GL_EXT_texgen_reflection GL_EXT_texture3D GL_EXT_texture_e
    dge_clamp GL_EXT_texture_env_combine GL_EXT_texture_object GL_EXT_vertex_array G
    L_KTX_buffer_region GL_ARB_window_pos GL_NV_texgen_reflection GL_SGI_texture_edg
    e_clamp GL_SGIS_texture_border_clamp GL_SGIS_texture_lod GL_SGIS_multitexture GL
    _WIN_swap_hint WGL_EXT_extensions_string WGL_EXT_swap_control '
    Program Path [C:Documents and SettingsMatthias LangeDesktopmagnetic] and Fil
    ename [Magnetic_0.07Alpha_Release.exe]
    Using device 'DirectSound'.
    [AL INFO]
    AL_VENDOR :Creative Labs Inc.
    AL_RENDERER :Software
    AL_VERSION :OpenAL 1.0
    AL_EXTENSIONS:EAX 2.0, EAX 3.0, EAX Unified, and EAX-AC3
    Loading Sound "C:Documents and SettingsMatthias LangeDesktopmagnetic/Data/So
    und/Selection0.wav"
    Loading Sound "C:Documents and SettingsMatthias LangeDesktopmagnetic/Data/So
    und/ZAP.wav"
    Loading Sound "C:Documents and SettingsMatthias LangeDesktopmagnetic/Data/So
    und/Zapping.wav"
    Loading Sound "C:Documents and SettingsMatthias LangeDesktopmagnetic/Data/So
    und/Empty01.wav"
    Loading Sound "C:Documents and SettingsMatthias LangeDesktopmagnetic/Data/So
    und/MenuFlip.wav"
    Loading Sound "C:Documents and SettingsMatthias LangeDesktopmagnetic/Data/So
    und/MenuActive.wav"
    Loading Field "C:Documents and SettingsMatthias LangeDesktopmagnetic/Data/Ma
    p/Level002_08.tga" (0)
    Loading Font "C:Documents and SettingsMatthias LangeDesktopmagnetic/Data/Fon
    t/MAGNETIC.tga" (0)
    Loading Header "C:Documents and SettingsMatthias LangeDesktopmagnetic/Data/M
    agneticFields.tga" (0)
    Loading SkyDome "C:Documents and SettingsMatthias LangeDesktopmagnetic/Data/
    Skydome/Nebula" *
    Loading Level "C:Documents and SettingsMatthias LangeDesktopmagnetic/Data/Le
    vel/Level_000.MGN"
    Level Loading [Start]
    Title [T] MAGNETISM TAKES TWO
    Config [C] +20000.000 +20000.000
    Dynamic [P] -4.000 +0.000 +0.000 +0.000 +0.000 +0.000 +0.00
    Dynamic [P] +4.000 +0.000 +0.000 +0.000 +0.000 +0.000 +0.00
    Goal [G] +0.000 +0.000 +0.000 +1.00 0
    Level Loading[ End ]

     
    Rui Martins

    January 04, 2005, 07:58 PM

    Thanks for the info.

    Is this the latest driver from ATI for your card?
    It's a somewhat old card, so maybe there is a more recent driver available.

    Did you test the Microsoft software implementation of OpenGl ?

    About Alpha blending
    You actually can see alpha blended TEXTURED Quads, that is what I use to draw the font in the Menus and level Title, and it seems to be working ok.

    However, the missing parts in your case are just colored (non-textured) polys, with an alpha < 1.0 (and with lighting disabled), so it's a different code path in the driver. Also Enabling and Disabling lighting frequently might be a problem if not handled correctly by the driver.

    Last but not least, most games today don't use untextured polys, i.e. all polys are always textured, one way or the other, so it's probable that this part of the driver didn't receive much testing.

    However, I'll check my code.

    Mean while you might want to test each of the following:
    -Press " " (space) key to check once for OpenGL Errors, and watch the Console.
    Period (dot) = OK, else Error code message.

    -Press "'" (single quote) key, to toogle continous OpenGL DEBUG (check for errors), and watch the Console.

    -Press "~" (tilde) key, (you may need to press space key after, depending on your language setting), and the items should change to Flat Shading, and maybe then you will see something. Just a wild guess at the problem.

    P.S.
    I'm very curious about the Menu, does it work as shown in the IOTD image ? A light blue round box on each item, with an animated yelowish lightning ray on the selected option. Because it's drawn in the exact same way!

     
    MatthiasLange

    January 05, 2005, 09:49 AM

    Yes, i have the latest driver.

    There were no error messages, when I pressed space.

    After setting the keyboard-layout to english(~ is alt-+ on german keyboards... that didn't work) I *think* I activated flat-shading(at least everything looked a little wierd ;)), but I still couldn't see the goals.

    The lightning in the menu works.

    I've also tried it on another computer this morning(at work ;)). Same problem. It has also a very old graphics card.

    I havn't tried the Microsoft OpenGL software implementation yet.

    Maybe you are just using some extensions that older cards don't support?

     
    Rui Martins

    January 05, 2005, 10:37 AM

    ... Same problem. It has also a very old graphics card.
    Can you say which one ? Thanks
    Now it's geeting to me, 2 (different?) boards with the same problem, yakes!

    Maybe you are just using some extensions that older cards don't support?
    No extensions !
    Plain OpenGL 1.1

    It can also be related with GL_DEPTH_MASK, since I disable depth buffer writing when drawing the in game transparent stuff .

    But if it works on the Main Menu, that may provide a clue, by comparison.
    Can you post an image of the Main Menu, Thanks

    I have to find someone that lives near me that has an ATI Rage 128.
    Is it one of those Mobility chipsets, like the ones used in laptops ?

    Thanks for the trouble.

     
    MatthiasLange

    January 05, 2005, 03:56 PM

    "Can you say which one ?"
    I'm not sure, but I think it was a TNT2 or so...

    http://img69.exs.cx/img69/7413/mainmenu0bc.png

    "Is it one of those Mobility chipsets, like the ones used in laptops ?"
    Err... no.(? ;))

     
    Matthias Lange

    January 06, 2005, 09:54 AM

    Wierd... seems like I can't edit my old post. Maybe it's because I finally added a space to my name. ;)

    The graphics card at work is an ATI Rage Fury...

     
    Rui Martins

    January 06, 2005, 10:05 AM

    To edit a post, you have to do it, before some timeout occurs, something like 15 minutes or so, after that you can't edit it anymore.

    ATI Rage Fury ?
    Hum, another Ati Rage!

    The problem seem to be the Depth Masking, but I can only be sure once you test a new version, where I'll try to avoid these Specific Cards problem by not using the feature.
    In the mean while I started adding some stuff (pollishing the game) and once I finish these changes I'll send you a new EXE by EMail, if you don't mind testing it.

    Thanks

     
    This thread contains 31 messages.
    First Previous ( To view more messages, select a page: 0 1 ... out of 1) Next Last
     
     
    Hosting by Solid Eight Studios, maker of PhotoTangler Collage Maker.