//*******************************************************************
/*
Solution: NerdkillPocket
Project: NerdkillPocket
File: Resourcerer.cs
Copyright 2003, 2004, Raphael MOLL.
This file is part of NerdkillPocket.
NerdkillPocket is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
NerdkillPocket is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with NerdkillPocket; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//*******************************************************************
using System;
using System.IO;
using System.Drawing;
using System.Reflection;
using System.Collections;
using Alfray.Nerdkill.Engine;
//*************************************
namespace Alfray.Nerdkill.Resources
{
//**************************************
/// <summary>
/// Summary description for Resourcerer.
/// </summary>
//**************************************
public class Resourcerer: IEngineResources
{
//-------------------------------------------
//----------- Public Constants --------------
//-------------------------------------------
//-------------------------------------------
//----------- Public Properties -------------
//-------------------------------------------
//-------------------------------------------
//----------- Public Methods ----------------
//-------------------------------------------
//******************
public Resourcerer()
{
mSpriteTable = new Hashtable();
mSoundTable = new Hashtable();
}
//********************************************
public bool SetContext(IEngineContext context)
{
mContext = context;
return true;
}
#region IEngineResources Members
//*******************
/// <summary>
/// Inherited from IDisposable
/// </summary>
//*******************
public void Dispose()
{
clearSprites();
clearSounds();
}
//************************************
public Icon LoadIcon(string leaf_name)
{
// leaf_name is the leaf base name (no extension)
// will try with extension .icon
string [] ext_list = { ".ico" };
// try to find a file within the resources
try
{
System.Type st = this.GetType();
if (st != null)
{
Assembly assembly = st.Assembly;
// get a list of all resources names (note: these are FULL names, which
// include the namespace of this class, a period and the filename)
string [] names = assembly.GetManifestResourceNames();
string ns_period = st.Namespace + ".";
foreach(string ext in ext_list)
{
try
{
string filename = ns_period + leaf_name + ext;
foreach(string name in names)
{
if (name == filename)
{
// Bitmap bmp = new Bitmap(this.GetType(), filename);
Icon ico = new Icon(assembly.GetManifestResourceStream(filename));
if (ico != null)
return ico;
}
}
}
catch(Exception ex)
{
System.Diagnostics.Debug.Write(ex.Message, "\nLoadIcon [rsrc " + leaf_name + ext + "]");
}
}
}
}
catch(Exception ex)
{
System.Diagnostics.Debug.Write(ex.Message, "\nLoadIcon [rsrc " + leaf_name + "]");
}
System.Diagnostics.Trace.Assert(false, "Can't find icon '" + leaf_name + "' in resources!");
return null;
}
//****************************************
public Bitmap LoadBitmap(string leaf_name)
{
// leaf_name is the leaf base name (no extension)
// will try with extensions .png, .jpg and .gif
string [] ext_list = { ".png", ".jpg", ".gif" };
// try to find a file within the resources
try
{
System.Type st = this.GetType();
if (st != null)
{
Assembly assembly = st.Assembly;
// get a list of all resources names (note: these are FULL names, which
// include the namespace of this class, a period and the filename)
string [] names = assembly.GetManifestResourceNames();
string ns_period = st.Namespace + ".";
foreach(string ext in ext_list)
{
try
{
string filename = ns_period + leaf_name + ext;
foreach(string name in names)
{
if (name == filename)
{
// Bitmap bmp = new Bitmap(this.GetType(), filename);
Bitmap bmp = new Bitmap(assembly.GetManifestResourceStream(filename));
if (bmp != null)
return bmp;
}
}
}
catch(Exception ex)
{
System.Diagnostics.Debug.Write(ex.Message, "\nLoadBitmap [rsrc " + leaf_name + ext + "]");
}
}
}
}
catch(Exception ex)
{
System.Diagnostics.Debug.Write(ex.Message, "\nLoadBitmap [rsrc " + leaf_name + "]");
}
System.Diagnostics.Trace.Assert(false, "Can't find bitmap '" + leaf_name + "' in resources!");
return null;
}
//**********************
public bool LoadSounds()
{
int i;
// -- discard existing sounds --
clearSounds();
// -- load all sounds --
for(i = 0; i < RConstants.NbSoundFun; i++)
insertSound(String.Format("nerdfun{0}.wav", i+1), RConstants.SoundId.FunVariant, false, i);
for(i = 0; i < RConstants.NbSoundDeadAh; i++)
insertSound(String.Format("n_ah{0}.wav", i+1), RConstants.SoundId.DeadAhVariant, false, i);
insertSound("nerd_in.wav", RConstants.SoundId.NerdIn, false, 0);
insertSound("nerd_out.wav", RConstants.SoundId.NerdOut, false, 0);
insertSound("n_elec1.wav", RConstants.SoundId.Elec, false, 0);
insertSound("n_explos.wav", RConstants.SoundId.Explode, false, 0);
insertSound("n_gun1.wav", RConstants.SoundId.Gun, false, 0);
insertSound("n_mine.wav", RConstants.SoundId.Mine, false, 0);
insertSound("n_roul2.wav", RConstants.SoundId.Bull, false, 0);
insertSound("n_select.wav", RConstants.SoundId.Select, false, 0);
insertSound("n_gun2.wav", RConstants.SoundId.UziRepeat, true, 0);
insertSound("n_roul1.wav", RConstants.SoundId.BullRepeat, true, 0);
return true;
}
//***********************
public bool LoadSprites()
{
Bitmap bmp;
int i;
// -- discard existing sprites --
clearSprites();
// -- process splashscreen --
/*
bmp = LoadBitmap("splashscreen");
insertSprite(bmp, RConstants.SpriteId.SplashScreen, 0, 0, 0, 240, 272, false, 1);
bmp.Dispose(); // RM 20040516 fix dispose bitmaps
*/
// -- process background --
bmp = LoadBitmap("background");
insertSprite(bmp, RConstants.SpriteId.MainBackground, 0, 0, 0, 480, 268, false, 1);
bmp.Dispose(); // RM 20040516 fix dispose bitmaps
// -- menu/weapons panel --
bmp = LoadBitmap("board256");
insertSprite(bmp, RConstants.SpriteId.MenuBackground, 0, 0,0, 240, 48, false, 1);
bmp.Dispose(); // RM 20040516 fix dispose bitmaps
// -- process sprites --
bmp = LoadBitmap("sprites256");
for(i=0; i<2; i++)
{
// nerd fix, right, top, left, bottom
insertSprite(bmp, RConstants.SpriteId.NerdFix, i, i+0,0, 1,1, true);
insertSprite(bmp, RConstants.SpriteId.NerdMovRight, i, i+2,0, 1,1, true);
insertSprite(bmp, RConstants.SpriteId.NerdMovUp, i, i+0,2, 1,1, true);
insertSprite(bmp, RConstants.SpriteId.NerdMovLeft, i, i+2,1, 1,1, true);
insertSprite(bmp, RConstants.SpriteId.NerdMovDown, i, i+0,1, 1,1, true);
// nerd electrocuted
insertSprite(bmp, RConstants.SpriteId.NerdElec, i, i+4,0, 1,1, true);
// bulldozer
insertSprite(bmp, RConstants.SpriteId.Bulldozer, i, i*2,3, 2,2, true);
// coke
insertSprite(bmp, RConstants.SpriteId.CokeCan, i, i*2+4,3, 2,2, true);
}
// painfully dead
insertSprite(bmp, RConstants.SpriteId.NerdDeadNormal, 0, 4,1, 1,1, true);
insertSprite(bmp, RConstants.SpriteId.NerdDeadExploded, 0, 5,1, 1,1, true);
insertSprite(bmp, RConstants.SpriteId.NerdDeadShade, 0, 6,1, 1,1, true);
// dead electrocuted
insertSprite(bmp, RConstants.SpriteId.NerdDeadElec, 0, 6,0, 1,1, true);
// shoot target
insertSprite(bmp, RConstants.SpriteId.ShootImpact, 0, 7,0, 1,1, true);
// mines
insertSprite(bmp, RConstants.SpriteId.MineNormal, 0, 4,2, 1,1, true);
insertSprite(bmp, RConstants.SpriteId.MineExploding, 0, 5,2, 1,1, true);
// the one-dot nerd finder point
insertSprite(bmp, RConstants.SpriteId.NerdFinderPoint, 0, 7*kBlockSize,1*kBlockSize, 1, 1, false, 1);
insertSprite(bmp, RConstants.SpriteId.NerdFinderBack, 0, 7*kBlockSize,2*kBlockSize, 12, 7, false, 1);
bmp.Dispose(); // RM 20040516 fix dispose bitmaps
// inactive + active menu/weapons
bmp = LoadBitmap("weapons24");
for(i=0; i<2; i++)
{
insertSprite(bmp, RConstants.SpriteId.WeaponGun, i, 0+i*4,0, 1,1, true, 24);
insertSprite(bmp, RConstants.SpriteId.WeaponUzi, i, 1+i*4,0, 1,1, true, 24);
insertSprite(bmp, RConstants.SpriteId.WeaponMine, i, 2+i*4,0, 1,1, true, 24);
insertSprite(bmp, RConstants.SpriteId.WeaponElec, i, 3+i*4,0, 1,1, true, 24);
insertSprite(bmp, RConstants.SpriteId.WeaponBull, i, 0+i*4,1, 1,1, true, 24);
insertSprite(bmp, RConstants.SpriteId.WeaponCoke, i, 1+i*4,1, 1,1, true, 24);
insertSprite(bmp, RConstants.SpriteId.WeaponDynamite, i, 2+i*4,1, 1,1, true, 24);
insertSprite(bmp, RConstants.SpriteId.WeaponFlag, i, 3+i*4,1, 1,1, true, 24);
}
bmp.Dispose(); // RM 20040516 fix dispose bitmaps
return true;
}
//**************************************************
public RSprite GetSprite(RConstants.SpriteId sprite)
{
return GetSprite(sprite, 0);
}
//*************************************************************
public RSprite GetSprite(RConstants.SpriteId sprite, int frame)
{
// get the sprite for 'frame'
// if there's no such frame, take any existing lower frame
for(; frame >= 0; frame--)
{
SSpriteKey key;
key.mId = sprite;
key.mFrame = frame;
RSprite sp = (RSprite) mSpriteTable[key];
if (sp != null)
return sp;
}
return null;
}
//**********************************************
public RSound GetSound(RConstants.SoundId sound)
{
return GetSound(sound, 0);
}
//*************************************************************
public RSound GetSound(RConstants.SoundId sound, int variation)
{
// fail if there's no sound device
if (!mContext.Sound.HasSound)
return null;
// get the sound for 'variation'
// if there's no such variation, take any existing lower variation
for(; variation >= 0; variation--)
{
SSoundKey key;
key.mId = sound;
key.mVariation = variation;
RSound snd = (RSound) mSoundTable[key];
if (snd != null)
return snd;
}
return null;
}
#endregion
//-------------------------------------------
//----------- Private Methods ---------------
//-------------------------------------------
//*****************
void clearSprites()
{
if (mSpriteTable == null)
return;
foreach(RSprite sp in mSpriteTable.Values)
{
mContext.Render2D.DisposeBuffer(sp.SpriteData);
}
mSpriteTable.Clear();
}
//****************
void clearSounds()
{
if (mSoundTable == null)
return;
foreach(RSound sd in mSoundTable.Values)
{
mContext.Sound.DisposeBuffer(sd.SoundData);
}
mSoundTable.Clear();
}
//****************************************************
bool insertSprite(Bitmap source,
RConstants.SpriteId id, int frame,
int x, int y, int width, int height,
bool transparent)
{
return insertSprite(source, id, frame, x, y, width, height, transparent, kBlockSize);
}
//****************************************************
bool insertSprite(Bitmap source,
RConstants.SpriteId id, int frame,
int x, int y, int width, int height,
bool transparent, int size_coef)
{
// sx/sy and width/height are expressed in multiples of 32 pixels
x *= size_coef;
y *= size_coef;
width *= size_coef;
height *= size_coef;
// extract the requested portion of the source bitmap
// use the same pixel format
// .Net Compact does not have Bitmap.Clone nor Bitmap.PixelFormat
// create the sprite data
Rectangle area = new Rectangle(x, y, width, height);
Object data = mContext.Render2D.CreateBuffer(source, area, transparent);
// create the sprite info
RSprite sprite = new RSprite(id, /*new Point(x, y),*/ new Size(width, height), transparent, data);
// create the hash table key
SSpriteKey key = new SSpriteKey();
key.mId = id;
key.mFrame = frame;
// insert in the hash table
mSpriteTable.Add(key, sprite);
return true;
}
//*************************************
bool insertSound(string filename,
RConstants.SoundId id,
bool auto_repeat,
int variation)
{
// fail if there's no sound device
if (!mContext.Sound.HasSound)
return false;
try
{
Assembly assembly = Assembly.GetCallingAssembly();
Stream stream = assembly.GetManifestResourceStream(this.GetType(), filename);
System.Diagnostics.Debug.Assert(stream != null);
// getting the stream failed... how odd!
if (stream == null)
return false;
// create the sound buffer
Object data = mContext.Sound.CreateBuffer(stream);
System.Diagnostics.Debug.Assert(data != null);
// this is unlikely...
if (data == null)
return false;
// create the sound
RSound sound = new RSound(id, auto_repeat, data);
// create the hash table key
SSoundKey key = new SSoundKey();
key.mId = id;
key.mVariation = variation;
// insert in the hash table
mSoundTable.Add(key, sound);
return true;
}
catch(Exception ex)
{
System.Diagnostics.Debug.Write(ex.ToString());
// RM 20040512 .Net Compact does not have Trace.Fail
System.Diagnostics.Trace.Assert(false, "Sound " + filename + " failed to load!", ex.Message);
}
return false;
}
//-------------------------------------------
//----------- Private Types -----------------
//-------------------------------------------
//-----------------------
private struct SSpriteKey
{
public RConstants.SpriteId mId;
public int mFrame;
public override int GetHashCode()
{
return ((int)mId) * 4 + mFrame;
}
}
//----------------------
private struct SSoundKey
{
public RConstants.SoundId mId;
public int mVariation;
public override int GetHashCode()
{
return ((int)mId) * 256 + mVariation;
}
}
//-------------------------------------------
//----------- Private Attributes ------------
//-------------------------------------------
private const int kBlockSize = 16;
private IEngineContext mContext;
private Hashtable mSpriteTable;
private Hashtable mSoundTable;
} // class Resourcerer
} // namespace Alfray.Nerdkill.Resources
//---------------------------------------------------------------
//
// $Log: Resourcerer.cs,v $
// Revision 1.3 2004/05/27 17:25:06 ralf
// Scroll event for directional keys
//
// Revision 1.2 2004/05/26 08:49:18 ralf
// Polishing.
//
// Revision 1.1.1.1 2004/05/24 14:21:58 ralf
// Stable port to PockerPC/.Net Compact Framework.
// Uses .Net/GDI+ for graghic. Uses WinCE's SoundPlay for sound.
//
//---------------------------------------------------------------