Engine5.05
Another quick update
Bugs fixed in this release
==========================
none
Changes
============
InputManager
============
MouseDistance - added, property which gives you the distance the mouse moved since the last game input. This is required for cursor control in lightgun games
MouseReset() - added, method which lets you position the mouse, resetting the history of the mouse in the process. This is for centreing the mouse, so it will align with cursors properly.
Tuesday, 14 December 2010
Sunday, 5 December 2010
Engine5.04 released
Engine5.04
Another quikc bug fix release
Bugs fixed in this release
==========================
Limit001: Fixed a long (very) standing set of bugs with limit box bouncing, which caused sprites to grip limit boxes (slid along them).
Another quikc bug fix release
Bugs fixed in this release
==========================
Limit001: Fixed a long (very) standing set of bugs with limit box bouncing, which caused sprites to grip limit boxes (slid along them).
Monday, 29 November 2010
Engine 5.03 released
Engine5.03
Another bug fix release
Bugs fixed in this release
==========================
Fixed more animation bugs such as LastFromAndStop and LastFrameAndFirst, there will be more
Fixed KeyPressed and KeyReleased, which exhibitted the opposite behaviour (because I had old and new states the wrong way around and fixed that, not releasing I had bodge pressed and released - doh!), this fix may break your code, so you may need to switch them over as well!!!
Changes in this release
=======================
Continued the process of wrapping the debug output and metric code in #if DEBUG #endif directives so this code will be skipped in release builds of the engine. I will need to provide a release and debug build of the engine for this to be useful, so I have re-organised the folders where the versions of the engine are stored.
The structure is as follows:
Look inside Game Programming Resources -> XNA ENGINE VERSIONS
Inside this folder will be the different numbered version of the engine
5.01
5.02 etc...
Inside the version folder from 5.02 onwards you will find a Debug folder which contains the dll and the xml file you should normally use during development. You will also find a Release folder which contains just a dll which contains release version code. This will give a slight speed increase as eventually all debug code will be removed from it.
Another bug fix release
Bugs fixed in this release
==========================
Fixed more animation bugs such as LastFromAndStop and LastFrameAndFirst, there will be more
Fixed KeyPressed and KeyReleased, which exhibitted the opposite behaviour (because I had old and new states the wrong way around and fixed that, not releasing I had bodge pressed and released - doh!), this fix may break your code, so you may need to switch them over as well!!!
Changes in this release
=======================
Continued the process of wrapping the debug output and metric code in #if DEBUG #endif directives so this code will be skipped in release builds of the engine. I will need to provide a release and debug build of the engine for this to be useful, so I have re-organised the folders where the versions of the engine are stored.
The structure is as follows:
Look inside Game Programming Resources -> XNA ENGINE VERSIONS
Inside this folder will be the different numbered version of the engine
5.01
5.02 etc...
Inside the version folder from 5.02 onwards you will find a Debug folder which contains the dll and the xml file you should normally use during development. You will also find a Release folder which contains just a dll which contains release version code. This will give a slight speed increase as eventually all debug code will be removed from it.
Tuesday, 9 November 2010
Engine 5.02 released
Engine5.02
Just a bug fix release here
Bugs fixed in this release
==========================
Couple of stupid audio bugs fixed, one which was trying to assign debug metrics to audio effects that had ended and another one which was trying to manipulate killed audio effects.
Fixed some serious animation bugs that occured when performing manual animations using ShowNext() and ShowPrevious(), these have existed forever and only affect AnimationEndActions set to Repeat
Changes in this release
=======================
Started the process of wrapping the debug output and metric code in #if DEBUG #endif directives so this code will be skipped in release builds of the engine. I will need to provide a release and debug build of the engine for this to be useful, so I have re-organised the folders where the versions of the engine are stored.
The structure is as follows:
Look inside Game Programming Resources -> XNA ENGINE VERSIONS
Inside this folder will be the different numbered version of the engine
5.01
5.02 etc...
Inside the version folder from 5.02 onwards you will find a Debug folder which contains the dll and the xml file you should normally use during development. You will also find a Release folder which contains just a dll which contains release version code. This will give a slight speed increase as eventually all debug code will be removed from it.
Just a bug fix release here
Bugs fixed in this release
==========================
Couple of stupid audio bugs fixed, one which was trying to assign debug metrics to audio effects that had ended and another one which was trying to manipulate killed audio effects.
Fixed some serious animation bugs that occured when performing manual animations using ShowNext() and ShowPrevious(), these have existed forever and only affect AnimationEndActions set to Repeat
Changes in this release
=======================
Started the process of wrapping the debug output and metric code in #if DEBUG #endif directives so this code will be skipped in release builds of the engine. I will need to provide a release and debug build of the engine for this to be useful, so I have re-organised the folders where the versions of the engine are stored.
The structure is as follows:
Look inside Game Programming Resources -> XNA ENGINE VERSIONS
Inside this folder will be the different numbered version of the engine
5.01
5.02 etc...
Inside the version folder from 5.02 onwards you will find a Debug folder which contains the dll and the xml file you should normally use during development. You will also find a Release folder which contains just a dll which contains release version code. This will give a slight speed increase as eventually all debug code will be removed from it.
Friday, 16 April 2010
Engine4.08 released
Quick update to make some pre-loader stuff a little simpler.
Bugs fixed in this release
==========================
Changes in this release
=======================
PreLoader
---------
added - AddSong, allows you to simply add a song asset to the load list of the pre-loader
added - AddSoundEffect, allows you to simply add a song asset to the load lsit of the pre-loader
Bugs fixed in this release
==========================
Changes in this release
=======================
PreLoader
---------
added - AddSong, allows you to simply add a song asset to the load list of the pre-loader
added - AddSoundEffect, allows you to simply add a song asset to the load lsit of the pre-loader
Tuesday, 13 April 2010
Game Engine4.07 released
Skipped 4.06 as decided to disable multi-tasking for engine logic (other than pre-loader). Google docs have now removed the file extension limit so the latest version is now pinned to the top right of this blog, don't forget to grab the xml file as well.
Bugs fixed in this release
==========================
EngineManger016: Collisions are broken again!!
EngineManager017: Sprites are intermittingly flickering
These were due to issues regarding multi-threading, but were fixed before multi-threading was disabled. I will revist multi-threading with the next major version of the engine.
Changes in this release
=======================
AudioManager
------------
Finalised (I think) the general operation of the audio manager, stuff will go on the help blog
added - GetActiveEffectNames(), this will return a list of all active sound effect instance names, separated by the string given (use ~ to make a line break)
added - GetEffectNames(), this will return a list of all sound effects names currently loaded into the audio manager, separated by the string given (use ~ to make a line break)
added - GetSongNames(), this will return a list of all currently loaded song names, separated by the string given (use ~ to make a line break)
ColourHelper
------------
added - SetAlpha, lets you easily set the alpha value of a colour, this can be quite protracted to do yourself with a sprite
EventManager
------------
fixed a couple of inconsistencies with timing in line with changes made to sprite timing system
EngineManager
-------------
Disabled multithreading support. The more I look into this the more refactoring of the engine is required. There are massive implications when calling funerals and update handlers etc... when a separate thread was involved. Lot's of horrible list reset possibilities inside updates. I need to refactor the update system to enable sensible use of multi-threading. I probably also need a state manager to marshal state changes through.
PreLoader
---------
Now working in a background thread - There is an example of using the pre-loader on the help blog
added - LoadComplete, if true this means that the pre-loader has finished background loading all assets. This is used in the GameLoop to determine when we can move from the pre-loader state to start our game proper.
added - NumberLoaded, a value indicating how many assets have been loaded so far
added - AssetCount, a value indicating how many assets have been identified for loading.
Bugs fixed in this release
==========================
EngineManger016: Collisions are broken again!!
EngineManager017: Sprites are intermittingly flickering
These were due to issues regarding multi-threading, but were fixed before multi-threading was disabled. I will revist multi-threading with the next major version of the engine.
Changes in this release
=======================
AudioManager
------------
Finalised (I think) the general operation of the audio manager, stuff will go on the help blog
added - GetActiveEffectNames(), this will return a list of all active sound effect instance names, separated by the string given (use ~ to make a line break)
added - GetEffectNames(), this will return a list of all sound effects names currently loaded into the audio manager, separated by the string given (use ~ to make a line break)
added - GetSongNames(), this will return a list of all currently loaded song names, separated by the string given (use ~ to make a line break)
ColourHelper
------------
added - SetAlpha, lets you easily set the alpha value of a colour, this can be quite protracted to do yourself with a sprite
EventManager
------------
fixed a couple of inconsistencies with timing in line with changes made to sprite timing system
EngineManager
-------------
Disabled multithreading support. The more I look into this the more refactoring of the engine is required. There are massive implications when calling funerals and update handlers etc... when a separate thread was involved. Lot's of horrible list reset possibilities inside updates. I need to refactor the update system to enable sensible use of multi-threading. I probably also need a state manager to marshal state changes through.
PreLoader
---------
Now working in a background thread - There is an example of using the pre-loader on the help blog
added - LoadComplete, if true this means that the pre-loader has finished background loading all assets. This is used in the GameLoop to determine when we can move from the pre-loader state to start our game proper.
added - NumberLoaded, a value indicating how many assets have been loaded so far
added - AssetCount, a value indicating how many assets have been identified for loading.
Sunday, 28 March 2010
Engine4.05 released
Engine4.05
Massive update includes, Finished Audio Manager, new PreLoading system, and Multi-threading support for PC and XBOX360 making use of the 4 cores on XBOX360
I still need to put some samples up telling you how to use them.
Bugs fixed in this release
==========================
Timing001: Sorted out a long standing bug that was not apparent unless you did some crazy things (which I have been doing lately), anyway it should be fixed but knowing me I probably broke a whole load of other stuff.
Changes in this release
=======================
EngineManager
-------------
added - MultiThreaded, set this to True to tell the engine to make use of threads, by splitting jobs across as many cores as we have available, this may cause bomb outs, so set it to False if it's not stable as there are garbage collector issues. This has involved some major internal changes to update, collision and rendering logic. Please let me know if you have got issues, so I can quickly track them down.
This is a bit simple at the moment, I need to work out how to force the threads onto 360 cores (there are 4 I can use if I can work out how!). With some basic testing with 420 sprites bouncing round the screen (and some background scrolling) I saw a jump from 128fps unthreaded to 156fps threaded.
new PreLoader
-------------
new class added which handles loading game content for you over a period of time, so you do not get a large delay. This is currently running in the same thread as the main game loop so any animation work will stutter. I will in future versions hopefully get this to run in a separate thread (now that I have started work on multi-threading)
added - Start(), starts the pre-loading process, by specifying the delay to build in between each asset to be loaded and specifies the subroutine to run once the loading process is complete. This subroutine has to transfer the texture assets to your Texture2D variables.
added - End(), used to indicate the Pre-loader has finished and its memory assets can be scrapped.
added - AddAsset(), identifies an asset for the pre-loader to load up for you
added - GetLoadedAsset(), used to get the loaded textures
Sprite
------------
added - Velocity2D, gives the X and Y velocity of a sprite, like Position2D gives you the XY position of a sprite (I found myself needing this when I was doing the doppler work in the new audio manager)
AudioManager
------------
I am nearly at a point to show you how to use it.
effect variables
added - SpeedoFsound, sets the speed of sound for the sound effect this simulates how fast waves travel in a substance
added - Dopplersoft, softens the amount the pitch changes when doppler effects are active, this defaults to 10% (0.1f), it should range from 0 (no change to 1- full change). If the pitch changes to much you want be able to hear the sound anything like it was authored
added - Zignore, tells the sound effect manager to ignore the Z values when calculating distances between sprites and positions (or other sprites)
added - MaxVolume, sets a maximum volume for the sound effect
added - ZeroVolumeDistance, sets the maximum distance before total volume drop off occurs,
added - FullPanDistance, sets the distance a sound effect needs to be from the observer before it is played entirely through the left or right channel
sound effect methods
added - PlayEffect(), plays a fire and shoot effect (one that triggers and is forgotten), these cannot be looped or stopped, so don't have long sound effects
added - PlayEffectViewerAtViewPort(), plays a soundeffect associating it with a single sprite, this is automatically puts the viewer at the centre of the viewport (screen centre), effects are then related to this. If you don't supply appropriate audioeffects then the sound effect is played using PlayEffect().
added - PlayEffectViewerAtPosition(), plays a soundeffect associating it with a single sprite, this puts the viewer at the position given, effects are then related to this. If you don't supply appropriate audioeffects then the sound effect is played using PlayEffect().
added - PlayEffectViewerAtSprite(), plays a soundeffect associating it with a single sprite, this puts the viewer at the position given by the viewers sprite, effects are then related to this. If you don't supply appropriate audioeffects then the sound effect is played using PlayEffect().
added - GetManagedEffect(), this retrieves a currently active sound effect, you should not need to use this under normal circumstance
added - PauseManagedEffect(),
added - ResumeManagedEffect(),
added - StopManagedEffect(),
added - RemoveManagedEffect(),
added - RemoveAllManagedEffects(),
added - AddSoundEffect(), loads an effect into the audio manager, this is not required if you use the pre-loading system as it is done automatically
song methods
added - AddSong(), loads a song into the audio manager, this is not required if you use the pre-loading system as it is done automatically.
added - PlaySong(), plays a song (mp3/wma), you control the current song using MediaPlayer.Volume etc...
added - StopCurrentSong(), stops the currently playing song
added - VisualisationInitialise(), activates the production of Visualisation data (frequency and smaple information)
added - VisualisationOn(), turns on the production of the visualisation data (which is expensive)
added - VisualisationOff(), turns off the production of the visualisation data.
added - visData, contains the visualisation data that you requested for the currently playing song this consists of 256 pieces of frequency of sample information for the current time portion of the playing song. The frequency data goes from 0 to 1f and the sample data goes from -1f to 1f.
Massive update includes, Finished Audio Manager, new PreLoading system, and Multi-threading support for PC and XBOX360 making use of the 4 cores on XBOX360
I still need to put some samples up telling you how to use them.
Bugs fixed in this release
==========================
Timing001: Sorted out a long standing bug that was not apparent unless you did some crazy things (which I have been doing lately), anyway it should be fixed but knowing me I probably broke a whole load of other stuff.
Changes in this release
=======================
EngineManager
-------------
added - MultiThreaded, set this to True to tell the engine to make use of threads, by splitting jobs across as many cores as we have available, this may cause bomb outs, so set it to False if it's not stable as there are garbage collector issues. This has involved some major internal changes to update, collision and rendering logic. Please let me know if you have got issues, so I can quickly track them down.
This is a bit simple at the moment, I need to work out how to force the threads onto 360 cores (there are 4 I can use if I can work out how!). With some basic testing with 420 sprites bouncing round the screen (and some background scrolling) I saw a jump from 128fps unthreaded to 156fps threaded.
new PreLoader
-------------
new class added which handles loading game content for you over a period of time, so you do not get a large delay. This is currently running in the same thread as the main game loop so any animation work will stutter. I will in future versions hopefully get this to run in a separate thread (now that I have started work on multi-threading)
added - Start(), starts the pre-loading process, by specifying the delay to build in between each asset to be loaded and specifies the subroutine to run once the loading process is complete. This subroutine has to transfer the texture assets to your Texture2D variables.
added - End(), used to indicate the Pre-loader has finished and its memory assets can be scrapped.
added - AddAsset(), identifies an asset for the pre-loader to load up for you
added - GetLoadedAsset(), used to get the loaded textures
Sprite
------------
added - Velocity2D, gives the X and Y velocity of a sprite, like Position2D gives you the XY position of a sprite (I found myself needing this when I was doing the doppler work in the new audio manager)
AudioManager
------------
I am nearly at a point to show you how to use it.
effect variables
added - SpeedoFsound, sets the speed of sound for the sound effect this simulates how fast waves travel in a substance
added - Dopplersoft, softens the amount the pitch changes when doppler effects are active, this defaults to 10% (0.1f), it should range from 0 (no change to 1- full change). If the pitch changes to much you want be able to hear the sound anything like it was authored
added - Zignore, tells the sound effect manager to ignore the Z values when calculating distances between sprites and positions (or other sprites)
added - MaxVolume, sets a maximum volume for the sound effect
added - ZeroVolumeDistance, sets the maximum distance before total volume drop off occurs,
added - FullPanDistance, sets the distance a sound effect needs to be from the observer before it is played entirely through the left or right channel
sound effect methods
added - PlayEffect(), plays a fire and shoot effect (one that triggers and is forgotten), these cannot be looped or stopped, so don't have long sound effects
added - PlayEffectViewerAtViewPort(), plays a soundeffect associating it with a single sprite, this is automatically puts the viewer at the centre of the viewport (screen centre), effects are then related to this. If you don't supply appropriate audioeffects then the sound effect is played using PlayEffect().
added - PlayEffectViewerAtPosition(), plays a soundeffect associating it with a single sprite, this puts the viewer at the position given, effects are then related to this. If you don't supply appropriate audioeffects then the sound effect is played using PlayEffect().
added - PlayEffectViewerAtSprite(), plays a soundeffect associating it with a single sprite, this puts the viewer at the position given by the viewers sprite, effects are then related to this. If you don't supply appropriate audioeffects then the sound effect is played using PlayEffect().
added - GetManagedEffect(), this retrieves a currently active sound effect, you should not need to use this under normal circumstance
added - PauseManagedEffect(),
added - ResumeManagedEffect(),
added - StopManagedEffect(),
added - RemoveManagedEffect(),
added - RemoveAllManagedEffects(),
added - AddSoundEffect(), loads an effect into the audio manager, this is not required if you use the pre-loading system as it is done automatically
song methods
added - AddSong(), loads a song into the audio manager, this is not required if you use the pre-loading system as it is done automatically.
added - PlaySong(), plays a song (mp3/wma), you control the current song using MediaPlayer.Volume etc...
added - StopCurrentSong(), stops the currently playing song
added - VisualisationInitialise(), activates the production of Visualisation data (frequency and smaple information)
added - VisualisationOn(), turns on the production of the visualisation data (which is expensive)
added - VisualisationOff(), turns off the production of the visualisation data.
added - visData, contains the visualisation data that you requested for the currently playing song this consists of 256 pieces of frequency of sample information for the current time portion of the playing song. The frequency data goes from 0 to 1f and the sample data goes from -1f to 1f.
Tuesday, 23 March 2010
Engine4.04 released
Engine4.04
Bugs fixed in this release
==========================
TrackManager001: Was picking correct location on track and transferring this data back to user. The original intention was that the user then decide what to do with this information, but I have now set the track position automatically. I may need to create a separate method to give track data and not set.
Changes in this release
=======================
EngineManager
-------------
adjusted - TrackDisplayOn(), now uses the track ColorWash to colour the TrackMarker of the track, if you want no colouring (because you have a special sprite then set the track colorWash to color.White - the default)
TrackManager
------------
added - GetAPositionNear(), this returns the nearest track position to the given position on a given track, without affecting the current position and movement of sprite
Bugs fixed in this release
==========================
TrackManager001: Was picking correct location on track and transferring this data back to user. The original intention was that the user then decide what to do with this information, but I have now set the track position automatically. I may need to create a separate method to give track data and not set.
Changes in this release
=======================
EngineManager
-------------
adjusted - TrackDisplayOn(), now uses the track ColorWash to colour the TrackMarker of the track, if you want no colouring (because you have a special sprite then set the track colorWash to color.White - the default)
TrackManager
------------
added - GetAPositionNear(), this returns the nearest track position to the given position on a given track, without affecting the current position and movement of sprite
Sunday, 21 March 2010
Engine4.03 released
Engine4.03
Bugs fixed in this release
==========================
Menu003: after investigation this was a bug with the Shooter menu system and not internally with the game engine
Engine015: temporary solution before final re-write, I altered how sprites were being added to the collisions bins, unfortunately this meant that collision check happened before all sprites had entered the bins doh!, meaning not all sprites were collision visible. if you want a more detailed explanation see me in lesson time. If there are any issues (and there might be) please let me know and revert back to a previous version of the engine which was stable for you.
Changes in this release
=======================
AudioManager
------------
This is a brand new class I have started (decided to do it Sunday afternoon) that implements correctly the new audio features in XNA 3.1 (and hopefully in XNA 4.0), it will eventually replace the SoundManager although they will work side by side. It's gonna have bugs which will need to weedled out but the main reason for doing it is that we don't need XACT anymore (and that is good cause it don't work on my win7 laptop!) we can just have a bunch of WAV's and mp3's.
added - AddSong(), this allows you add an mp3 track to the audio manager. The great thing about this is you can easily control the volume but you also get access to Frequency and sample information (I've got it working - but I have disabled it for now - see this video for a simple test) which could be used to generate music related gameplay ala Sega's REZ.
One thing to mention there is a slight delay when you first contact the MediaPlayer (even to set volume!)
It is not activated by default and requires a little jigging to attach to your projects but it works pretty good, here is the feature list (so far :) )
added - AddSoundEffect(), these work like sound effects in the old sound manager fire and forget, but the new audio manager can also independantly set the volume and more excitingly change the pitch and pan of each version of the same sound effect independantly
added - PlayEffect(), shoots off a sound effect that will play once, you can set the volume, pitch or pan of the effect
added - PlayManagedEffect(), triggers a sound effect, but leaves it managable, which means it can be paused, looped and its various settings changed.
added - PauseManagedEffect(), pauses a currently managed effect.
added - ResumeManagedEffect(), resumse a previously paused effect.
added - StopManagedEffect(), stops a previously playing effect.
added - PlaySong(), plays an mp3 track - be aware there is a slight lag
added - RemoveManagedEffect(), removes an instance of a sound effect
added - RemoveAllManagedEffects(), removes all sound effect instances.
added - StopCurrentSong(), stops media player playing music tracks (you can do MediaPlayer.Stop)
TextManager
-----------
added - pointHandler now part of list of attributes applicable to Text when using DrawAsSprites()
TrackManager
------------
added - TrackPositionNear(), attempts to find the position along the current track that is the closest to the given position. This could be used to allow a sprite to jump from one track to another close by. Not tested this fully (lets face it I haven't tested this at all!) so consider it a ALPHA
added - Remove(), which Removes a track at the given position. The position is the order in which the tracks were added. The first track added is at position 0. If the track removed is being followed by the sprite then it is detached from this track and the end track handler is called if enabled, this may also break your code as it needs extensive testing.
added - CurrentTrackData, this returns a Track containing all the information about the current used track and links back to the base TrackDefinition in use
EngineManager and Sprite
========================
Various - lots of internal changes in preparation for plugging in new collision systems
Adjusted - made the collision checks and collision comparisons keep track of their Maximum values
Bugs fixed in this release
==========================
Menu003: after investigation this was a bug with the Shooter menu system and not internally with the game engine
Engine015: temporary solution before final re-write, I altered how sprites were being added to the collisions bins, unfortunately this meant that collision check happened before all sprites had entered the bins doh!, meaning not all sprites were collision visible. if you want a more detailed explanation see me in lesson time. If there are any issues (and there might be) please let me know and revert back to a previous version of the engine which was stable for you.
Changes in this release
=======================
AudioManager
------------
This is a brand new class I have started (decided to do it Sunday afternoon) that implements correctly the new audio features in XNA 3.1 (and hopefully in XNA 4.0), it will eventually replace the SoundManager although they will work side by side. It's gonna have bugs which will need to weedled out but the main reason for doing it is that we don't need XACT anymore (and that is good cause it don't work on my win7 laptop!) we can just have a bunch of WAV's and mp3's.
added - AddSong(), this allows you add an mp3 track to the audio manager. The great thing about this is you can easily control the volume but you also get access to Frequency and sample information (I've got it working - but I have disabled it for now - see this video for a simple test) which could be used to generate music related gameplay ala Sega's REZ.
One thing to mention there is a slight delay when you first contact the MediaPlayer (even to set volume!)
It is not activated by default and requires a little jigging to attach to your projects but it works pretty good, here is the feature list (so far :) )
added - AddSoundEffect(), these work like sound effects in the old sound manager fire and forget, but the new audio manager can also independantly set the volume and more excitingly change the pitch and pan of each version of the same sound effect independantly
added - PlayEffect(), shoots off a sound effect that will play once, you can set the volume, pitch or pan of the effect
added - PlayManagedEffect(), triggers a sound effect, but leaves it managable, which means it can be paused, looped and its various settings changed.
added - PauseManagedEffect(), pauses a currently managed effect.
added - ResumeManagedEffect(), resumse a previously paused effect.
added - StopManagedEffect(), stops a previously playing effect.
added - PlaySong(), plays an mp3 track - be aware there is a slight lag
added - RemoveManagedEffect(), removes an instance of a sound effect
added - RemoveAllManagedEffects(), removes all sound effect instances.
added - StopCurrentSong(), stops media player playing music tracks (you can do MediaPlayer.Stop)
TextManager
-----------
added - pointHandler now part of list of attributes applicable to Text when using DrawAsSprites()
TrackManager
------------
added - TrackPositionNear(), attempts to find the position along the current track that is the closest to the given position. This could be used to allow a sprite to jump from one track to another close by. Not tested this fully (lets face it I haven't tested this at all!) so consider it a ALPHA
added - Remove(), which Removes a track at the given position. The position is the order in which the tracks were added. The first track added is at position 0. If the track removed is being followed by the sprite then it is detached from this track and the end track handler is called if enabled, this may also break your code as it needs extensive testing.
added - CurrentTrackData, this returns a Track containing all the information about the current used track and links back to the base TrackDefinition in use
EngineManager and Sprite
========================
Various - lots of internal changes in preparation for plugging in new collision systems
Adjusted - made the collision checks and collision comparisons keep track of their Maximum values
Wednesday, 17 March 2010
Engine4.02 released
Bugs fixed in this release
==========================
Changes in this release
=======================
EngineManager and Sprite
========================
Various - lots of internal changes in preparation for plugging in new collision systems
regressed - AddSprite(), was assigning an automatic Z value to stop flickering issues, but this impacted on too many students code. So doesn't do this now.
==========================
Changes in this release
=======================
EngineManager and Sprite
========================
Various - lots of internal changes in preparation for plugging in new collision systems
regressed - AddSprite(), was assigning an automatic Z value to stop flickering issues, but this impacted on too many students code. So doesn't do this now.
Monday, 8 March 2010
Engine4.01 released
Collision system coming forward, fixed some bugs introduced with the start of the new collision changes.
Bugs fixed in this release
==========================
TextManager001: Fixed this bug, it was a doosy, such as deep swine involving multiple sprite references which were not being re-wired to the new text sprite.
EngineManager014: Fixed this, bug due to change in collision preparation code. The engine was not marking sprites as moving when they were. The collision engine was detecting collisions but because all sprites were incorrectly marked as not moving no bounce logic was applied.
Changes in this release
=======================
CollisionHelper
---------------
added - PadAndBounce (used by collisionAction.movingBounce replacing AlignAndBounce) doesn't attempt to align a sprite but applies padding and reflects moving sprite, this may cause further problems, which may be countered by altering the sprites Padding value (which defaults to 1 pixel)
EngineManager and Sprite
========================
Various - lots of internal changes in preparation for plugging in new collision systems
Bugs fixed in this release
==========================
TextManager001: Fixed this bug, it was a doosy, such as deep swine involving multiple sprite references which were not being re-wired to the new text sprite.
EngineManager014: Fixed this, bug due to change in collision preparation code. The engine was not marking sprites as moving when they were. The collision engine was detecting collisions but because all sprites were incorrectly marked as not moving no bounce logic was applied.
Changes in this release
=======================
CollisionHelper
---------------
added - PadAndBounce (used by collisionAction.movingBounce replacing AlignAndBounce) doesn't attempt to align a sprite but applies padding and reflects moving sprite, this may cause further problems, which may be countered by altering the sprites Padding value (which defaults to 1 pixel)
EngineManager and Sprite
========================
Various - lots of internal changes in preparation for plugging in new collision systems
Friday, 5 March 2010
Engine4.00 released
Collision system coming forward, but needed to release this due to some big interesting improvements.
One note of interest ScaleFactors, for tileSheets and sprite layers cannot be scaled further that 2.0f, I need to investigate this a lot further.
Bugs fixed in this release
==========================
none
Changes in this release
=======================
Bin (internal object)
---
altered - simplified bin management so should see a significant speed up (I noticed testing code go from 30fps to 45fps with 1000 large rotating sprites all collision enabled)
EngineManager
-------------
added - BinResolution, this allows you to change the collision detection bin grid size, under the correct conditions changing this value may significantly speed up or slow down the collision system.
altered - OnScreen() internal methods, now take into account sprites layer scaling when determining visibilty.
added - more comprehensive debug output for layers and spritelayers and better organisation of this information. also added some control combinations for dynamically scrolling the display output.
SHIFT and - (not the numpad ones) to scroll the display upwards (so you can see more)
SHIFT and + (not the numpad ones) to scroll the display downwards (so you can move back to the top)
SHIFT and < to scroll the display Left. SHIFT and > to scroll the display Right
LayerManager
------------
added - GetLayers(), returns the list of all the TileSheets currently being managed by the LayerManager, these can then be looped through for any special processing you want to do.
Sprite
------
Lot's of work in preparation for dynamic collision engine, now tracking rotated sprites properly (collision not active properly for them yet)
re-written - Update(), made some significant speed ups and removed lots of uneccesary code ready for new collision system.
Some refactoring work done, to remove some parameter passing for some speed ups
added - Manual(), marks a sprite as static, so no movement logic, animation, history and timeractions are applied
added - ManualWithUpdates(), marks a sprite as static so no movement logic is applied, animation history and timeractions are still applied
added - Automatic(), marks a sprite as a normal updating sprite.
TileSheet
---------
added - Wrap, when set to true (the default) the tile sheet will start drawing tiles from the left or top if we run out of tiles on the bottom or right. This will effect scrolling giving you just the tile sheet as you defined it. The default operates as it did before.
One note of interest ScaleFactors, for tileSheets and sprite layers cannot be scaled further that 2.0f, I need to investigate this a lot further.
Bugs fixed in this release
==========================
none
Changes in this release
=======================
Bin (internal object)
---
altered - simplified bin management so should see a significant speed up (I noticed testing code go from 30fps to 45fps with 1000 large rotating sprites all collision enabled)
EngineManager
-------------
added - BinResolution, this allows you to change the collision detection bin grid size, under the correct conditions changing this value may significantly speed up or slow down the collision system.
altered - OnScreen() internal methods, now take into account sprites layer scaling when determining visibilty.
added - more comprehensive debug output for layers and spritelayers and better organisation of this information. also added some control combinations for dynamically scrolling the display output.
SHIFT and - (not the numpad ones) to scroll the display upwards (so you can see more)
SHIFT and + (not the numpad ones) to scroll the display downwards (so you can move back to the top)
SHIFT and < to scroll the display Left. SHIFT and > to scroll the display Right
LayerManager
------------
added - GetLayers(), returns the list of all the TileSheets currently being managed by the LayerManager, these can then be looped through for any special processing you want to do.
Sprite
------
Lot's of work in preparation for dynamic collision engine, now tracking rotated sprites properly (collision not active properly for them yet)
re-written - Update(), made some significant speed ups and removed lots of uneccesary code ready for new collision system.
Some refactoring work done, to remove some parameter passing for some speed ups
added - Manual(), marks a sprite as static, so no movement logic, animation, history and timeractions are applied
added - ManualWithUpdates(), marks a sprite as static so no movement logic is applied, animation history and timeractions are still applied
added - Automatic(), marks a sprite as a normal updating sprite.
TileSheet
---------
added - Wrap, when set to true (the default) the tile sheet will start drawing tiles from the left or top if we run out of tiles on the bottom or right. This will effect scrolling giving you just the tile sheet as you defined it. The default operates as it did before.
Thursday, 25 February 2010
BAD NEWS
It would appear that the XBOX has suffered a bit of a problem. The power supply is reporting a fault when the XBOX is powered up (RED LIGHT COMES ON).
This is a pain as I was in the middle of testing Dan Barratt's game with the XBOX, now it's started faulting.
I'll need to leave it with IT see if they can get it sorted (I have not got time to mess about with it).
This is a pain as I was in the middle of testing Dan Barratt's game with the XBOX, now it's started faulting.
I'll need to leave it with IT see if they can get it sorted (I have not got time to mess about with it).
Saturday, 20 February 2010
Engine3.20 released
This is the last release before I do the changes to the collision system only one change (until I decided to add the sprite layer stuff) but important for all those doing shooting (lightgun) style games. Hopefully when I do the collision update I won't completely bork the engine but its a possibility as the entire sprite update code is going to have to change. I've produced a totally new engine project just in case it goes wrong.
Bugs fixed in this release
==========================
none
Changes in this release
=======================
EngineManager
------------
added - PointInFirstSprite(), a further method added (3 in total now) that checks against a range of sprite types, in case you need to check against multiple types.
adjusted - AddSprite(), so it incrementally sets a Z value for each new sprite added (resets when ClearAllSprites called), override by setting a Z position.
added - spriteLayerProperties(), a method for accessing the properties of a specific sprite layer (as detailed below). This is for special effects only collision detection and other systems will not take account (yet!) of the matrices for each of the sprite layers
Here is a quick video showing some square sprites all the squAres are actually the same size but the layers are scaled (Yes I know its a crap example but it's taken from code I was using to test the PointInFirstSprite() code so it was there. I'll do another video to illustrate this better).
SpriteLayerProperties
---------------------
New class added which can globally affect all sprites or text on a specific layer using the following properties. This involved a lot of refactoring which may have introduced some bugs that I haven't picked up (i think I updated all references). This may cause some weird actions (particularly the rotation stuff)
added ScaleFactor - Specifies the scaling effect for the sprite/text layer (float)
added RotationAngle - specifies the rotation angle for the sprite/text layer (float in radians not degrees)
added RotationCentre - Specifies the centre of rotation for the sprite layer (Vector 3)
added DrawMatrix - default matrix which does nothing (as its an identity matrix - look it up)
added CreateMatrix - if true (default is false) creates a transformation matrix for the Sprite/text layer based on the scaleFactor, rotationAngle, rotationCentre values, otherwise the DrawMatrix is used (which defaults to Identity - which does nothing)
access the spriteLayerProperties as follows:
//settings for sprite layer0
//make engine generate matrix
engineM.SpriteLayerProperties(SpriteLayer.layer0).CreateMatrix = true;
//set rotation centre to centre of screen (screen in this case is 800x600)
engineM.SpriteLayerProperties(SpriteLayer.layer0).RotationCentre = new Vector3(400, 300, 0);
//in GameLoop() you can constantly rotate the sprite layer0 at 90 degrees/second:
engineM.SpriteLayerProperties(SpriteLayer.layer0).RotationAngle +=
MathHelper.ToRadians(eventM.ReturnValueForFrame(90));
I've tested this a bit and found a problem with the drawnText (this is where normal text ends up) layer and scaling, scale values over 1.0f stop displaying, I don't know why yet haven't investigated.
Bugs fixed in this release
==========================
none
Changes in this release
=======================
EngineManager
------------
added - PointInFirstSprite(), a further method added (3 in total now) that checks against a range of sprite types, in case you need to check against multiple types.
adjusted - AddSprite(), so it incrementally sets a Z value for each new sprite added (resets when ClearAllSprites called), override by setting a Z position.
added - spriteLayerProperties(), a method for accessing the properties of a specific sprite layer (as detailed below). This is for special effects only collision detection and other systems will not take account (yet!) of the matrices for each of the sprite layers
Here is a quick video showing some square sprites all the squAres are actually the same size but the layers are scaled (Yes I know its a crap example but it's taken from code I was using to test the PointInFirstSprite() code so it was there. I'll do another video to illustrate this better).
SpriteLayerProperties
---------------------
New class added which can globally affect all sprites or text on a specific layer using the following properties. This involved a lot of refactoring which may have introduced some bugs that I haven't picked up (i think I updated all references). This may cause some weird actions (particularly the rotation stuff)
added ScaleFactor - Specifies the scaling effect for the sprite/text layer (float)
added RotationAngle - specifies the rotation angle for the sprite/text layer (float in radians not degrees)
added RotationCentre - Specifies the centre of rotation for the sprite layer (Vector 3)
added DrawMatrix - default matrix which does nothing (as its an identity matrix - look it up)
added CreateMatrix - if true (default is false) creates a transformation matrix for the Sprite/text layer based on the scaleFactor, rotationAngle, rotationCentre values, otherwise the DrawMatrix is used (which defaults to Identity - which does nothing)
access the spriteLayerProperties as follows:
//settings for sprite layer0
//make engine generate matrix
engineM.SpriteLayerProperties(SpriteLayer.layer0).CreateMatrix = true;
//set rotation centre to centre of screen (screen in this case is 800x600)
engineM.SpriteLayerProperties(SpriteLayer.layer0).RotationCentre = new Vector3(400, 300, 0);
//in GameLoop() you can constantly rotate the sprite layer0 at 90 degrees/second:
engineM.SpriteLayerProperties(SpriteLayer.layer0).RotationAngle +=
MathHelper.ToRadians(eventM.ReturnValueForFrame(90));
I've tested this a bit and found a problem with the drawnText (this is where normal text ends up) layer and scaling, scale values over 1.0f stop displaying, I don't know why yet haven't investigated.
Wednesday, 10 February 2010
XBOX360 work
I'm currently testing with the help of Dan Barratt getting your projects working on the XBOX. This will require altering your project so it builds for PC and XBOX and also using a different version of the game engine specifically designed to work on the XBOX (all the same commands and features exist).
This will involve me now producing incremental changes for both PC and XBOX engines (requiring double updates). This is only something you will need to do if you actually want to get your system working on the XBOX.
On the student shared I will be placing the XBOX version of the engine in a folder called XBOXEngine, please do not get this confused with the stock PC one which you already use.
I'll give more information out when I get a system to make this work as easily as possible.
More information in a future post, and I'll post the changes you'll need to make to your project on the help blog at some point in the near future.
This will involve me now producing incremental changes for both PC and XBOX engines (requiring double updates). This is only something you will need to do if you actually want to get your system working on the XBOX.
On the student shared I will be placing the XBOX version of the engine in a folder called XBOXEngine, please do not get this confused with the stock PC one which you already use.
I'll give more information out when I get a system to make this work as easily as possible.
More information in a future post, and I'll post the changes you'll need to make to your project on the help blog at some point in the near future.
Engine3.19 released
Bugs fixed in this release
==========================
EngineManager013: GetFirstSpriteOfType() suffered same problem as EngineManager012, now fixed
Changes in this release
=======================
InputManager
------------
added - PadStatePrevious(), gives you the previously tested status of the selected pad
altered - xml description of PadState(), it wrongly said it updated the status when in fact it does not, it just retrieves the status for you.
The following two keyboard methods are provided to make accessing common keyboardstate information more straightforward.
added - KeyDown(), lets you test to see if a key is currently being pressed
added - KeyUp(), lets you test to see if a key is currently not being pressed
The following five game pad methods are provided to make accessing common game pad information more straightforward.
added - ButtonDown(), lets you test to see if a button is currently being pressed on the request pad
added - ButtonUp(), lets you test to see if a button is currently not being pressed on the request pad
added - PadConnected(), lets you test to see if a particular pad is connected, this is useful if you want to display either keyboard or game pad controls
added - Triggers(), retrieves the current trigger state for the selected pad (use inputM.Triggers(1).Left to get the amount of left trigger)
added - TriggersPrevious(), retreives the previous trigger state for the selected pad, useful if you want to determine any difference in pressure on triggers
added - ThumbSticks(), retrieves the current thumbstick state for the selected pad (use inputM.ThumbStick(1).Left.X to get the amount of horizontal movement of the left thumbstick)
added - ThumbSticksPrevious(), retrieves the previous thumstick state for the selected pad.
==========================
EngineManager013: GetFirstSpriteOfType() suffered same problem as EngineManager012, now fixed
Changes in this release
=======================
InputManager
------------
added - PadStatePrevious(), gives you the previously tested status of the selected pad
altered - xml description of PadState(), it wrongly said it updated the status when in fact it does not, it just retrieves the status for you.
The following two keyboard methods are provided to make accessing common keyboardstate information more straightforward.
added - KeyDown(), lets you test to see if a key is currently being pressed
added - KeyUp(), lets you test to see if a key is currently not being pressed
The following five game pad methods are provided to make accessing common game pad information more straightforward.
added - ButtonDown(), lets you test to see if a button is currently being pressed on the request pad
added - ButtonUp(), lets you test to see if a button is currently not being pressed on the request pad
added - PadConnected(), lets you test to see if a particular pad is connected, this is useful if you want to display either keyboard or game pad controls
added - Triggers(), retrieves the current trigger state for the selected pad (use inputM.Triggers(1).Left to get the amount of left trigger)
added - TriggersPrevious(), retreives the previous trigger state for the selected pad, useful if you want to determine any difference in pressure on triggers
added - ThumbSticks(), retrieves the current thumbstick state for the selected pad (use inputM.ThumbStick(1).Left.X to get the amount of horizontal movement of the left thumbstick)
added - ThumbSticksPrevious(), retrieves the previous thumstick state for the selected pad.
Engine3.18 released
Just a quick update to activate the Highscore stuff
Bugs fixed in this release
==========================
None
Changes in this release
=======================
HighScore
----------
Enabled - this part of the engine had been disabled, now active in this version, see help blog for details
Bugs fixed in this release
==========================
None
Changes in this release
=======================
HighScore
----------
Enabled - this part of the engine had been disabled, now active in this version, see help blog for details
Thursday, 4 February 2010
Engine3.17 released
Bugs fixed in this release
==========================
TrackHelper001: Points() now generates correctly the number of points you want across spans of points, fixed PointsForceZ() in same manner.
EngineManager012: RemoveFirstSpriteOfThisType now works, fixed KillFirstSpriteOfThisType() as it sufferred the same flawed logic.
Changes in this release
=======================
EngineManager
-------------
Adjusted - LayerDebug output to include DrawOffset (DrawOff) and DrawPosition (DrawPos) as these were not included
Can't remember why I have both offset and position (as they do the same thing), may need to remove one in near future to avoid confusion.
==========================
TrackHelper001: Points() now generates correctly the number of points you want across spans of points, fixed PointsForceZ() in same manner.
EngineManager012: RemoveFirstSpriteOfThisType now works, fixed KillFirstSpriteOfThisType() as it sufferred the same flawed logic.
Changes in this release
=======================
EngineManager
-------------
Adjusted - LayerDebug output to include DrawOffset (DrawOff) and DrawPosition (DrawPos) as these were not included
Can't remember why I have both offset and position (as they do the same thing), may need to remove one in near future to avoid confusion.
Friday, 22 January 2010
Engine3.16 released
Bugs fixed in this release
==========================
EngineManager010 - killed sprites now removed from bins properly upon removal.
EngineManager011 - hopefully fixed the SpriteBatch.End() crash that is occuring when you drag window between screens. I don't seem to be able to re-create it anymore on my teacher desk machine. Need some people to test it. After testing with Patrick's code I've tracked down the culprit but not the reason, I have a fix that should stop it crashing in future, but I need to look at the reason it actually occurs.
EventManager005 - Events repeatedly raised using RaisedUntil() now re-initialise
Changes in this release
=======================
EngineManager
-------------
cleanup - Draw(), cleaned some of the code to reduce number of new objects created during draw cycle
Limit
-----
added - turnOffGravityBottomOnly, this turns gravity off only when you hit the bottom of a limit box all other edges are ignored.
added - killPastXStopY, kills a sprite if it goes past the left/right boundaries and stops sprites vertical movement if it touches top/bottom
added - killPastYStopX, kills a sprite if it goes past top/bottom boundaries and stops sprites horizontal movement if it touches left/right
Timing (TimerActions)
------
added - OnTimingDone(), lets you set an internal sprite event, which automatically runs an Update subroutine when the timer elapses
TimingDone can be called at the end of
ShowAfter(), ShowAfterFlash(), StopAfter(), ImpulseStopAfter(), FlashAfter(), ShowAfterKillAfter(), once sprite is shown, StartAfterStopAfter() (called when it starts and again when it stops use GetPhase to determine which state its in), FlashAfterKillAfter() (once flashing starts)
For instance, you may want the player to be invicible to start with and indicate with flashing, Using StopAfter() to flash the sprite for a while (set sprite CollisionDisable() when you create the sprite). Set the OnTimingDone which will be called when the flashing stops, to turn on CollisionEnable() the sprite.
added - RemoveOnTiming(), lets you remove the update handler associated with timer actions
added - FireEvent(), lets you specify an update handler that runs repeatidly after a certain amount of time
added - FireEventOnce(), lets you specify an update handler that runs once after a certain amount of time
adjusted - Timing updates to take account of partial time overlaps, this should make the timer actions more regular
==========================
EngineManager010 - killed sprites now removed from bins properly upon removal.
EngineManager011 - hopefully fixed the SpriteBatch.End() crash that is occuring when you drag window between screens. I don't seem to be able to re-create it anymore on my teacher desk machine. Need some people to test it. After testing with Patrick's code I've tracked down the culprit but not the reason, I have a fix that should stop it crashing in future, but I need to look at the reason it actually occurs.
EventManager005 - Events repeatedly raised using RaisedUntil() now re-initialise
Changes in this release
=======================
EngineManager
-------------
cleanup - Draw(), cleaned some of the code to reduce number of new objects created during draw cycle
Limit
-----
added - turnOffGravityBottomOnly, this turns gravity off only when you hit the bottom of a limit box all other edges are ignored.
added - killPastXStopY, kills a sprite if it goes past the left/right boundaries and stops sprites vertical movement if it touches top/bottom
added - killPastYStopX, kills a sprite if it goes past top/bottom boundaries and stops sprites horizontal movement if it touches left/right
Timing (TimerActions)
------
added - OnTimingDone(), lets you set an internal sprite event, which automatically runs an Update subroutine when the timer elapses
TimingDone can be called at the end of
ShowAfter(), ShowAfterFlash(), StopAfter(), ImpulseStopAfter(), FlashAfter(), ShowAfterKillAfter(), once sprite is shown, StartAfterStopAfter() (called when it starts and again when it stops use GetPhase to determine which state its in), FlashAfterKillAfter() (once flashing starts)
For instance, you may want the player to be invicible to start with and indicate with flashing, Using StopAfter() to flash the sprite for a while (set sprite CollisionDisable() when you create the sprite). Set the OnTimingDone which will be called when the flashing stops, to turn on CollisionEnable() the sprite.
added - RemoveOnTiming(), lets you remove the update handler associated with timer actions
added - FireEvent(), lets you specify an update handler that runs repeatidly after a certain amount of time
added - FireEventOnce(), lets you specify an update handler that runs once after a certain amount of time
adjusted - Timing updates to take account of partial time overlaps, this should make the timer actions more regular
Monday, 4 January 2010
Engine3.15 released
This is the last release before I updated the collision engine, I will try to make it work with the same setup of CollisionChecks, but this may not be possible. I am currently developing a two player asteroids game and this has given me a chance to bug fix a tweak many aspects of the engine, including adding useful functions.
Bugs fixed in this release
==========================
Changes in this release
=======================
Sprite
------
added - Position2D, this returns the position of the sprite as a 2D result (ignoring the Z value), this is useful for distance calculations.
SpriteHelper
------------
added - RotateFacingPosition(), this lets you make a sprite face a given position (for perfect tracking systems)
added - VelocityToGetHereInThisTime(), this let's you easily specify a position to move towards in a certain specified time
Timing (TimerActions)
------
added - OnTimingDone(), lets you specify a sprite update routine to call when timing finishes for actions that don't involve Kill (you could use a funeral for these).
TimingDone can be called at the end of
ShowAfter(), ShowAfterFlash(), StopAfter(), ImpulseStopAfter(), FlashAfter(), ShowAfterKillAfter(), once sprite is shown, StartAfterStopAfter() (called when it starts and again when it stops use GetPhase to determine which state its in), FlashAfterKillAfter() (once flashing starts)
For instance, you may want the player to be invicible to start with and indicate with flashing, Using StopAfter() to flash the sprite for a while (set sprite CollisionDisable() when you create the sprite). Set the OnTimingDone which will be called when the flashing stops, to turn on CollisionEnable() the sprite.
added - RemoveOnTimingDone(), removes any specified TimingDone handler
added - GetPhase, this gives you the phase of multipart actions such as StartAfterStopAfter()
Bugs fixed in this release
==========================
Changes in this release
=======================
Sprite
------
added - Position2D, this returns the position of the sprite as a 2D result (ignoring the Z value), this is useful for distance calculations.
SpriteHelper
------------
added - RotateFacingPosition(), this lets you make a sprite face a given position (for perfect tracking systems)
added - VelocityToGetHereInThisTime(), this let's you easily specify a position to move towards in a certain specified time
Timing (TimerActions)
------
added - OnTimingDone(), lets you specify a sprite update routine to call when timing finishes for actions that don't involve Kill (you could use a funeral for these).
TimingDone can be called at the end of
ShowAfter(), ShowAfterFlash(), StopAfter(), ImpulseStopAfter(), FlashAfter(), ShowAfterKillAfter(), once sprite is shown, StartAfterStopAfter() (called when it starts and again when it stops use GetPhase to determine which state its in), FlashAfterKillAfter() (once flashing starts)
For instance, you may want the player to be invicible to start with and indicate with flashing, Using StopAfter() to flash the sprite for a while (set sprite CollisionDisable() when you create the sprite). Set the OnTimingDone which will be called when the flashing stops, to turn on CollisionEnable() the sprite.
added - RemoveOnTimingDone(), removes any specified TimingDone handler
added - GetPhase, this gives you the phase of multipart actions such as StartAfterStopAfter()
Subscribe to:
Posts (Atom)