Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Menu

Mostrar Mensajes

Esta sección te permite ver todos los posts escritos por este usuario. Ten en cuenta que sólo puedes ver los posts escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menu

Temas - ethernet

#81
Código de la Semana / Infovid - Zaelsius
18 de Octubre de 2003, 01:29:35 PM
 
     InfoVid  


    Es una clase que permite enumerar los adaptadores gráficos
    y modos de video soportados por éstos de una manera sencilla.

    Tambien recupera información acerca de drivers. En el caso
    de nVidia, se recupera la versión de sus drivers Detonator.

    Se requiere el SDK de DirectX 9.0 para compilar el código fuente,
    aunque he incluido un binario de demostración.

    Para ejecutar el binario se requiere DirectX9.0, of course.
    (No sé si la versión 9.0b será necesaria, ya que es la versión que
    he utilizado para compilar).


//  InfoVid.h;
--------------------------------------------------------------------


#include "d3dx9.h";

#define VENDORID_NVIDIA 0x000010de

namespace
ivid
{

   struct
sVideoMode
   {

       UINT    uWidth;
       UINT    uHeight;
       UINT    uRefreshRate;
       UINT    uFormat;
       char
   szModeDesc[32];
   };


   struct
sVideoAdapter
   {

       char
szDescription[MAX_DEVICE_IDENTIFIER_STRING];
       char
szDriverName[MAX_DEVICE_IDENTIFIER_STRING];
       DWORD dwDriverVersionLo;
       DWORD dwDriverVersionHi;
       UINT uModeCount;
       sVideoMode* pModes;
   };


   class
InfoVid
   {

   public
:

       int
                       Init();
       int
                       GetAdapterCount() const;
       const
sVideoAdapter*    GetAdapterInfo() const;

                               InfoVid();
                               ~
InfoVid();
   private
:

       virtual
void            FormatMode(sVideoMode* pMode);

       UINT                    m_uAdapterCount;
       sVideoAdapter*            m_pInfo;
   };
}

//--------------------------------------------------------------------




La función miembro FormatMode() se encarga de crear una cadena describiendo
cada modo de vídeo, p.ej. "800x600, 32bpp, 85hz".

FormatMode() crea las cadenas de una manera por defecto, pero podeis cambiar
el formato predefinido derivando de InfoVid...


// InfoVid.cpp
--------------------------------------------------------------------

#include "InfoVid.h"
#include "Safe.h"
#include "d3dx9.h";
#include "cstdio";

#pragma comment(lib,"d3d9.lib")


using namespace
ivid;

InfoVid::InfoVid()
:
m_uAdapterCount(0),m_pInfo(0)
{

}


int
InfoVid::Init()
{

   HMODULE D3DLibrary = LoadLibrary("d3d9.dll");
   IDirect3D9 *pID3D;

   if
(!D3DLibrary)
   {

       OutputDebugString("Error, could not load D3D9.DLL");
       return
0;
   }


   typedef
IDirect3D9 * (__stdcall *D3DCREATETYPE)(UINT);
   D3DCREATETYPE d3dCreate = (D3DCREATETYPE) GetProcAddress(D3DLibrary, "Direct3DCreate9");

   if
(!d3dCreate)
   {

       OutputDebugString("Error, could not get proc adress of Direct3DCreate9");
       FreeLibrary(D3DLibrary);
       return
0;
   }


   // Like pID3D = Direct3DCreate9(D3D_SDK_VERSION);
   pID3D = (*d3dCreate)(D3D_SDK_VERSION);

   if
(!pID3D)
   {

       OutputDebugString("Error initializing D3D.");
       FreeLibrary(D3DLibrary);
       return
0;
   }


   //Return number of available devices
   m_uAdapterCount = pID3D->GetAdapterCount();


   D3DADAPTER_IDENTIFIER9* pAdapterId=0;

   m_pInfo = new sVideoAdapter[m_uAdapterCount];

   pAdapterId = new D3DADAPTER_IDENTIFIER9[m_uAdapterCount];

   for
(UINT i=0; i < m_uAdapterCount ; i++)
   {

       pID3D->GetAdapterIdentifier(i,0,&pAdapterId[i]);
       strcpy(m_pInfo[i].szDescription,pAdapterId[i].Description);
       strcpy(m_pInfo[i].szDriverName,pAdapterId[i].Driver);
       m_pInfo[i].dwDriverVersionHi = pAdapterId[i].DriverVersion.HighPart;
       m_pInfo[i].dwDriverVersionLo = pAdapterId[i].DriverVersion.LowPart;

       // Si es NVIDIA sabemos sacar los números de versión
       if(pAdapterId[i].VendorId == VENDORID_NVIDIA)
       {

           int
iNVversion = m_pInfo[i].dwDriverVersionLo & 0x0000FFFF;
           m_pInfo[i].dwDriverVersionHi = iNVversion/100;
           m_pInfo[i].dwDriverVersionLo = iNVversion - (iNVversion/100)*100;
       }

   }


   SafeDeleteArray(pAdapterId);

   // Allowed formats in DX9 are:
   D3DFORMAT lstFormat[]= { D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, D3DFMT_A2B10G10R10,
       D3DFMT_X1R5G5B5, D3DFMT_A1R5G5B5, D3DFMT_R5G6B5};


   D3DDISPLAYMODE mode;

   for
(UINT i=0; i < m_uAdapterCount ; i++)
   {

       UINT uTotalModes = 0;
       for
(UINT h=0; h < 6; h++)
       {

           uTotalModes += pID3D->GetAdapterModeCount(i,lstFormat[h]);
       }


       m_pInfo[i].uModeCount = uTotalModes;
       m_pInfo[i].pModes = new sVideoMode[uTotalModes];

       UINT k=0;

       for
(UINT h=0; h < 6; h++)
       {

           UINT uModeCount = pID3D->GetAdapterModeCount(i,lstFormat[h]);

           for
(UINT j=0;j<uModeCount;j++)
           {

               pID3D->EnumAdapterModes(i,lstFormat[h],j,&mode);
               m_pInfo[i].pModes[k].uWidth = mode.Width;
               m_pInfo[i].pModes[k].uHeight = mode.Height;
               m_pInfo[i].pModes[k].uRefreshRate = mode.RefreshRate;
               m_pInfo[i].pModes[k].uFormat = (UINT)lstFormat[h];
               FormatMode(&(m_pInfo[i].pModes[k]));

               k++;
           }
       }
   }


   pID3D->Release();

   FreeLibrary(D3DLibrary);


   return
m_uAdapterCount ;
}


InfoVid::~InfoVid()
{

   if
(m_pInfo)
   {

       for
(UINT i=0;i<m_uAdapterCount;i++)
       {

           for
(UINT k=0;k<m_pInfo[i].uModeCount;k++)
           {

               SafeDeleteArray(m_pInfo[i].pModes);
           }
       }


       SafeDeleteArray(m_pInfo);
   }

}


int
InfoVid::GetAdapterCount() const
{

   return
m_uAdapterCount;
}


const
sVideoAdapter* InfoVid::GetAdapterInfo() const
{

   return
(const sVideoAdapter*)m_pInfo;
}


void
InfoVid::FormatMode(sVideoMode* pMode)
{

   sprintf((char*)&(pMode->szModeDesc),"%dx%d %dhz",
       pMode->uWidth,pMode->uHeight,pMode->uRefreshRate);
}

--------------------------------------------------------------------



Y Ahora un ejemplo de utilización:


--------------------------------------------------------------------

#include "iostream.h"
#include "InfoVid.h"
#include "d3dx9.h";

using namespace
ivid;

int
main(int argc, char* argv[])
{

   InfoVid iv;

   int
iAdapters = iv.Init();

   if
(iAdapters)
   {

       const
sVideoAdapter* pInfo = iv.GetAdapterInfo();

       // Recorremos tarjetas gráficas instaladas
       for(UINT i=0;i< iAdapters; i++)
       {

           cout << pInfo[i].szDescription << endl
               <<
pInfo[i].szDriverName << " \nDriver version: "
               <<
pInfo[i].dwDriverVersionHi << "."
               <<
pInfo[i].dwDriverVersionLo << endl;

           cout << "Pulsa una tecla para ver los modos...\n";
           cin.get();


           // Recorremos modos de vídeo disponibles
           for(UINT k=0; k<pInfo[i].uModeCount;k++)
           {

               cout << pInfo[i].pModes[k].uFormat << " "
                    <<
pInfo[i].pModes[k].szModeDesc << endl;
           }

       }
   }

   else

       cerr << "No se pudo obtener la informacion de video\n";

   cout << "Pulsa una tecla para salir...\n";
   cin.get();

   return
0;
}



Autor: Julio Gorgé, a.k.a. Zaelsius
Web: http://www.zsgames.tk

Código: http://www.alu.ua.es/j/jgf8/code/InfoVid.zip


Si quieres enviar tu propio código hazlo a eth_cotd@lycos.es

[/list]

#82
Off-topic / Bones ^^u
22 de Agosto de 2003, 09:55:19 AM
#83
Off-topic / Dominios Gratuitos
21 de Agosto de 2003, 11:18:01 AM
 Estoy buscando un dominio gratuito que permita linkar imagenes -u otros archivos- desde otro servidor, como por ejemplo un foro. Seguro que alguno de vosotros -sobretodo grafos- que posteais imagenes sabeis alguno. (marsy confio en ti)

saludos
#84
Código de la Semana / Vector Con Ocaml - Samsaga2
30 de Julio de 2003, 01:12:24 PM
 


  Vector con OCAML
Aprovechando que he estado mirandome el lenguaje ocaml he creado un modulo de vectores 3d para este lenguaje.

Para los que desconozcan este lenguaje decir que la lluvia es Sevilla es una pura maravilla , es una mezcla entre lenguaje funcional (c, c++, etc...) y lenguaje imperativo (lisp, fortran, etc...), con recolector de basura y mil y una cosas, en fin una verdadera maravilla. Para los que duden de la velocidad de ejecucion de este tipo de lenguajes saber que va casi tan rapido que el c y mas rapido que el c++ en la mayoria de casos (estoy seguro que la mayoria de gente piensa que el c++ es igual de rapido que el c, usar clases tiene mucha sobrecarga de codigo).

Mi opinion es que el c se ha quedado pequeño para aplicaciones de cierto nivel y que el c++ es un verdadero bodrio hecho a base de parches sobre el c (exagerar es mi forma de vida). Cosas que no me gustan del c/c++:

- Templates
- El casi nulo soporte de RTTI en los compiladores
- Los punteros (de aqui provienen la mayoria de bugs, por no hablar de los stack overflow)
- La gestion de memoria
- Los destructores de clases (se deberian llamar destructores de la humanidad  )
- Tener que ir declarandolo todos dos veces e incluso tener que declarar de que tipos son las variables cuando del contexto se puede sacar claramente de que tipo es
- y un sinfin mas de cosas.

La unica ventaja que le veo al c/c++ respecto al ocaml es la gran cantidad de gente que hay haciendo cosas para ese lenguaje (eso es algo que debemos cambiar nosotros).

Pagina oficial - http://www.ocaml.org/
OCAML SDL - http://ocamlsdl.sourceforge.net/
Algunos cutre-juegos hechos en ocaml - http://ropas.kaist.ac.kr/caml/humps/caml_Games.html
Google: c++ sucks - http://www.google.com/search?q=c%2B%2B+suc...a+en+Google&lr=

Por cierto, no penseis que estoy haciendo apologia nazi en contra del c++ solo quiero que la gente se de cuenta de que la vida no acaba en ese lenguaje. Teneis que daros cuenta de que un programa hecho en ocaml requiere menos tiempo de produccion que si se hubiera hecho en c++.

Si quereis ya os ire dando mas la bara con el rollo este que os he metido  sobre el ocaml

Código:

(* Vector tolerance for vector comparision *)
let tolerance = 0.001

(* Vector class *)
class vector3 x_init y_init z_init =
object(self)
  (* Vector props *)
  val mutable x = x_init
  val mutable y = y_init
  val mutable z = z_init

  (* Get vector properties *)
  method get_x = x
  method get_y = y
  method get_z = z

  (* Set vector properties *)
  method set_x xs = x <- xs
  method set_y ys = y <- ys
  method set_z zs = z <- zs

  method set xs ys zs =
      x <- xs;
      y <- ys;
      z <- zs

  method move xoffset yoffset zoffset =
      x <- x +. xoffset;
      y <- y +. yoffset;
      z <- z +. zoffset

  (* Calc length of the vector *)
  method magnitude () =
      sqrt x*.x +. y*.y +. z*.z

  (* Normalize the vector *)
  method normalize () =
      let length = 1. /. self#magnitude () in
      x <- x *. length;
      y <- y *. length;
      z <- z *. length
end

(* Create a 3d vector *)
let create ?(x = 0.) ?(y = 0.) ?(z = 0.) () =
  new vector3 x y z

(* Sum of vector *)
let (+) v1 v2 =
  create
      ~x:(v1#x +. v2#x)
      ~y:(v1#y +. v2#y)
      ~z:(v1#z +. v2#z)

(* Sub of vectors *)
let (-) v1 v2 =
  create
      ~x:(v1#x -. v2#x)
      ~y:(v1#y -. v2#y)
      ~z:(v1#z -. v2#z)

(* Vector product *)
let ( * ) v1 number =
  create
      ~x:(v1#x *. number)
      ~y:(v1#y *. number)
      ~z:(v1#z *. number)

let ( * ) v1 v2 =
  create
      ~x:(v1#x *. v2#x)
      ~y:(v1#y *. v2#y)
      ~z:(v1#z *. v2#z)

(* Vector div *)
let (/) v1 number =
  create
      ~x:(v1#x /. number)
      ~y:(v1#y /. number)
      ~z:(v1#z /. number)

let (/) v1 v2 =
  create
      ~x:(v1#x /. v2#x)
      ~y:(v1#y /. v2#y)
      ~z:(v1#z /. v2#z)

(* Vector eq *)
let (=) v1 v2 =
  if tolerance = 0. then
      v1#x = v2#x &&
      v1#y = v2#y &&
      v1#z = v2#z
  else
      abs_float (v1#x -. v2#x) <= tolerance &&
      abs_float (v1#y -. v2#y) <= tolerance &&
      abs_float (v1#z -. v2#z) <= tolerance

(* Vector neq *)
let (<>) v1 v2 =
  not (v1 = v2)

(* Return the dot between two vectors *)
let dot v1 v2 =
  v1#x *. v2#x +.
  v1#y *. v2#y +.
  v1#z *. v2#z

(* Return the cross vector of two vectors *)
let cross v1 v2 =
  create
      ~x:(v1#y *. v2#z -. v1#z *. v2#y)
      ~y:(v1#z *. v2#x -. v1#x *. v2#z)
      ~z:(v1#x *. v2#y -. v1#y *. v2#x)

(* Return the minimum vector of two vectors *)
let minimum v1 v2 =
  create
      ~x:(if v1#x < v2#x then v1#x else v2#x)
      ~y:(if v1#y < v2#y then v1#y else v2#y)
      ~z:(if v1#z < v2#z then v1#z else v2#z)

(* Return the maximum vector of two vectors *)
let maximum v1 v2 =
  create
      ~x:(if v1#x > v2#x then v1#x else v2#x)
      ~y:(if v1#y > v2#y then v1#y else v2#y)
      ~z:(if v1#z > v2#z then v1#z else v2#z)



Daos cuenta de que en ningun sitio he declarado el tipo de las variables, pero el compilador automaticamente se da cuenta de que son floats.

Estadisticas:
- ocaml 129 lineas
- este mismo objeto en c++:
53 lineas la cabecera
204 lineas el fuente
total 257 lineas justo el doble menos uno


Si quieres enviar tu propio código hazlo a eth_cotd@lycos.es . También puedes hacerlo a través de un mensaje privado por el foro si el código es corto.

[/list]
#85
Código de la Semana / Rle Array - Mchiz
20 de Julio de 2003, 05:20:46 PM
 
     RLE Array  

    Espero que el código que aquí envío sea de tanta ayuda para muchos de vosotros como lo fue para mi en su momento. Se trata de un... 'manager' sobre el manejo de la compresion RLE en general. Lo chulo que tiene ( creo ) es que puedes tener en memoria un array RLE y acceder a ella como si fuese un array normal. Sacrificas un poco de tiempo de ejecución, pero puedes ahorrar muchísima memoria.
    Personalmente me vi impulsado a hacer esto programando un algoritmo de busqueda de caminos. Desde un punto del mapa se podian ir a un montonazo, pero siempre tenias que pasar por uno de los X vecinos que tuvieses en ese momento, que suelen ser pocos ( en mi caso 3 como mucho ). Utilizaba una tabla de enrutamiento. Bien, sin comprimir la puñetera tabla me ocupaba algo así como 500 megas de memoria. Al pasarle el RLE consegui que se quedara en medio mega!! Al ver esto me di cuenta que no debía guardarmelo para mi solo :)
    No utilicé exactamente los algoritmos que he puesto aquí, porque aquél código está un poco hecho polvo y sólo servía para comprimir valores numéricos. Ahora lo he hecho un poco más general y sirve para cualquier tipo de dato ( vivan los templates! ). No sé si me ha quedado intuitivo o no; yo pienso que sí, pero si alguien tiene mejoras, ya sabéis :)
    Un saludote a todos!!

    Un ejemplo de como se usan es el siguiente

//--------------------------------------------------------------------------------------------------------------------
// Programa ejemplo de las clases RLE.
//--------------------------------------------------------------------------------------------------------------------
#include
#include

#include "RLEArray.h"

void
main( ) {
   // Array en crudo para comprimir
   int rawArray[ ] = {
      1
, 10, 10, 10, 10, 10, 10, 5, 5, 5, 5, 23, 23, 23

   };


   // Comprimimos 'rawArray'. El resultado esta en rleArray
   NSRLE::Array< int > *rleArray = NSRLE::compress< int >( rawArray, sizeof( rawArray ) / sizeof( rawArray[ 0 ] ) );

   printf( "\nArray comprimido con exito" );

   // Comprobamos por si no se ha podido reservar memoria para el array
   assert( rleArray );

   // Elementos REALES del array RLE
   printf( "\nElementsCount: %d", rleArray->getElementsCount( ) );
   
   // Imprimimos los valores de cada uno...

   for( unsigned int i = 0; i < rleArray->getElementsCount( ); ++i )
      printf( "\nArray[ %d ]: %d", i, rleArray->getElement( i ) );

   // Informacion acerca de la memoria ocupada...
   printf( "\nDatos ocupados NO comprimidos: %d bytes",
      sizeof
( NSRLE::Bucket< int > ) // Tamaño de un bucket ( dato )

      *
      rleArray->getElementsCount( ) // Numero REAL de buckets ( en este caso 4 + 2 + 2 + 58 )
   );
   printf( "\nDatos ocupados comprimidos: %d bytes",
      sizeof
( NSRLE::Bucket< int > ) // Tamaño de un bucket ( dato )

      *
      rleArray->getBucketsCount( ) // Numero de buckets comprimidos ( en este caso 4 )
   );

   // Descomprimimos el array RLE. El resultado esta en decompressedArray
   int *decompressedArray = NSRLE::decompress< int >( rleArray );

   // Comparamos todos los elementos del array RLE con el array acabado de descomprimir. Asi veremos si ha habido algun error
   for( unsigned int i = 0; i < rleArray->getElementsCount( ); ++i )

      assert( decompressedArray[ i ] == rleArray->getElement( i ) );

   printf( "\nArray RLE descomprimido con exito" );

   getch( );

   delete
rleArray;

   rleArray = NULL;

   delete
[ ]decompressedArray;
   decompressedArray = NULL;
}




Puedes descargarte el código de la siguiente dirección:

http://www.stratos-ad.com/codigosemana/rlearray.zip

Si quieres enviar tu propio código solo tienes que hacerlo a eth_cotd@lycos.es

[/list]
#86
Off-topic / Html
19 de Julio de 2003, 02:18:39 PM
 Se puede postear con contenido HTML ?

estaría bien para el código de la semana



saludos
#87
Off-topic / Donde Esta Lord Trancos ?
16 de Julio de 2003, 02:20:47 PM
 pos eso, donde estas ?
#88
Código de la Semana / Ejemplo Vertex Shader - Ak47
05 de Julio de 2003, 06:03:47 PM
 
    Ejemplo Vertex Shader


    Después de una temporada parado por falta de tiempo y vagueza de un servidor presento el cotw de AK47. Es un ejemplo de como usar vertex shader con DX9. En el zip viene un html explicando todo con lo cual os remito a el para enteraros en profundidad de su funcionamiento :)



    http://www.stratos-ad.com/codigosemana/ejemplovs.zip


    Si quiere enviar tu propio código hazlo a eth_cotd@lycos.es

    [/list]
    #89
    Off-topic / shell
    07 de Junio de 2003, 12:57:07 AM
    LLevo trabajando en linux algunos meses y ahora me gusta tener siempre una o varias consolas abiertas, pero normalmente trabajo en win y no he encontrado nada similar a konsole (por ejemplo) que permite tener varias instacias en una ventana con una barra de tareas (tipo mirc). Conoceis alguno para windows?

    saludos
    #90
    Off-topic / foros
    07 de Junio de 2003, 12:19:08 AM
    Soy humano y por lo tanto curioso y esa curiosidad ahora me esta presionando y me obliga a preguntaros que otros foros soleis visitar. Ya se sabe que en internet descubres las mejores cosas por recomendacion de alguien.

    Bueno, yo visito estos (:))) y a veces los de quakesrc.org y opengl.org que supongo q todos conocereis.

    Un saludo
    #91
    Código de la Semana / FilePacker -Zaelsius
    25 de Mayo de 2003, 06:45:25 PM


      Aquí está (por fin) el código del packer enviado por Zaelsius. El código esta perfectamente comentado y además ha enviado un documento (que he decidido no ponerlo aqui para que no perdiera su formato original) por lo cual os remito a ese documento y al código para enteraros como funciona ;). Lo puedes descargar de la siguiente dirección:

      Documento:   http://www.stratos-ad.com/codigosemana/zspack-1.zip
      Código fuente:  http://www.alu.ua.es/j/jgf8/code/zspack-1-0.rar   (incluye el documento anterior)

      Autor:   Julio Gorgé, a.k.a. Zaelsius
      Web:   http://zsgames.tk





          Éste código fue enviado por Zaelsius
          Si quieres enviar tu propio código hazlo a  
      eth_cotd@lycos.es
      #92
      Código de la Semana / Singleton - CordayUK & otros
      27 de Abril de 2003, 05:32:27 PM


        Este es un código de la semana diferente, CordayUK me envio el codigo que pondre a continuacion como ejemplo de singleton, sin embargo leyendo un poco acerca de esa implemetacion en los foros de gamedev y otros sites no me parecio la adecuada por razones que espero podamos discutir en próximos días. Por ello he decidido postear otra implementación de singleton que se discutió en el irc y que espero podamos sacar conclusiones aquí también.

        Si teneis alguna implementación de Singleton que creais que podemos comentar o simplemente diferente a las planteadas no dudeis en postearlas.


        Esta es la implementación que me envió CordayUK


        /*

        CSingleton.h   (basado en el Game Programming Gems I)



        Define una clase singleton. Deriva tus clases a partir de esta y podras llamarlas desde cualquier punto de tu juego.



        ejemplo:



        en tu clase CJuego tienes un objeto CTimer, el cual esta implementado en CTimer.h asi:



          Class CTimer : public CSingleton <CTimer>



        desde cualquier otra parte de tu juego que incluya CTimer.h puedes llamar a CTimer::GetSingletonPtr () y obtener un

        puntero al Timer. Por supuesto solo puedes tener un objeto CTimer en todo el juego.



        */







        #pragma once

        #pragma warning( disable : 4311 4312 )   //4311,4312 : unsafe cast from int to class pointer





        #include <cassert>





        #define SINGLETON_ERROR_MSG   "Algo va mal con el singleton!! :("



        template <typename T> class CSingleton

        {



          //puntero al singleton

          static T* ms_ptr;                                    



        public:



          CSingleton (void)

          {

             assert (!ms_ptr && SINGLETON_ERROR_MSG);



             //averigua la direccion relativa de la instancia derivada

             spI offset = (spI)(T*)1-(spI)(spSingleton <T>*)(T*)1;



             //graba el resultado en el puntero del singleton

             ms_ptr = (T*)((int)this+offset);                    

          }



          virtual ~CSingleton (void)

          {

             assert(ms_ptr && SINGLETON_ERROR_MSG);

             ms_ptr = 0;

          }



          //devuelve la referencia al singleton

          inline static T& GetSingleton (void)

          {

             assert (ms_ptr && SINGLETON_ERROR_MSG);

             return (*ms_ptr);

          }



          inline static T* GetSingletonPtr (void)

          {

             spAssert (ms_ptr && SINGLETON_ERROR_MSG);

             return (ms_ptr);

          }

        };



        //inicializa el puntero a nulo

        template <typename T> T* CSingleton <T>::ms_ptr = 0;





        Esta es la implementación que yo propongo





        template <class T> class Singleton : public T

        {

        private:



            Singleton() {     }

            Singleton(const Singleton& fact) {     }

            Singleton& operator = (const Singleton& fact) {     }

        public:

            ~Singleton() {     }

        public:

            static Singleton& Instance() {

                static Singleton s_instance;

                return s_instance;

            }

        };





        Como veis el destructor esta como public, teóricamente se debería poner como private pero  para mantener la implementación original , que esta así debido a un bug del msvc++, he decidido no cambiarla.

        Espero que el autor no se me enfade por postearla sin su permiso ;P

        #93


          La versión 9 de DirectX trae una utilidad llamada D3DSpy que intercepta las  llamadas a D3D9 que realizan los programas. Similar a la conocida utilidad OGLTrace para OpenGL.

          El código que presento muestra una de las muchas formas de implementar este  tipo de programas interceptores.

          La ídea basicamente consiste en crear una DLL llamada d3d9.dll que exporte una función Direct3DCreate9, y colocarla en el mismo directorio que el ejecutable  que queremos monitorizar. De forma que cuando el ejecutable llame a Direct3DCreate9, no llamará a la DLL de DirectX sino a nuestra DLL. Nuestra Direct3DCreate9 retornará un puntero a una clase especializada (que hereda) de IDirect3D9 para que podamos modificar su comportamiento:





        //

        // Implementación de Direct3DCreate9

        //

        IDirect3D9 * WINAPI Direct3DCreate9(UINT SDKVersion)

        {

           HINSTANCE l_hModule = LoadLibrary("c:windowssystem32d3d9.dll");

           if (NULL == l_hModule){

                return(NULL);

               }



           DXPROC l_pfnFunction = (DXPROC)GetProcAddress(l_hModule,



        "Direct3DCreate9");

           if (NULL == l_pfnFunction){

                return(NULL);

               }



           IDirect3D9 * l_pD3D9 = l_pfnFunction(SDKVersion);

           if (NULL == l_pD3D9){

                return(NULL);

               }



           return( new D3D9Trace::CD3D9Trace(l_pD3D9) );

        }




        Nota: El path y nombre de la DLL está hard-code, pero sería fácil leerla de un .INI para poder cambiar su ubicación o nombre, por ejemplo para cargar la DLL  de depuración (d3d9d.dll).

        La clase CD3D9Trace hereda de IDirect3D9 e implementa todos los métodos de la misma. Veámosla resumida:





        class CD3D9Trace : public IDirect3D9

        {

        public:

           CD3D9Trace::CD3D9Trace(IDirect3D9 * const pv_pInterface)

               : m_pInterface(pv_pInterface)

           {

           }

        ...

        //

        // IUnknow

        //

        private:

           HRESULT STDMETHODCALLTYPE CD3D9Trace::QueryInterface(REFIID riid, void**



        ppvObj);

           ULONG   STDMETHODCALLTYPE CD3D9Trace::AddRef(void);

           ULONG   STDMETHODCALLTYPE CD3D9Trace::Release(void);

        //

        // IDirect3D9

        //

        private:

           HRESULT  STDMETHODCALLTYPE CD3D9Trace::CheckDepthStencilMatch(UINT



        Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT



        RenderTargetFormat, D3DFORMAT DepthStencilFormat);

        ...

           CD3D9Trace::RegisterSoftwareDevice(void *pInitializeFunction);

        //

        // Miembros

        //

        private:

           IDirect3D9 * m_pInterface;

        };





        De esta forma, cada vez que el programa llame a un método de IDirect3D9 en realidad lo hará a través de nuestra clase. Por ejemplo:





        HMONITOR STDMETHODCALLTYPE CD3D9Trace::GetAdapterMonitor(UINT Adapter)

        {

           _ASSERTE(NULL != GetInterface() );



           return( GetInterface()->GetAdapterMonitor(Adapter) );

        }





        Esto da la oportunidad de realizar algún tipo de pre-proceso o post-proceso en cada llamada.

        Entre los posibles usos, está el típico de añadir trazas de depuración (para    
        ver el orden de las llamadas y el tiempo que tarda en ejecutarse cada una de ellas), realizar pruebas simulando fallos en llamadas a funciones (¿como se comportaría nuestro programa si una llamada a CreateVertexBuffer devolviera D3DERR_OUTOFVIDEOMEMORY?), poner pausas activas para simular comportamientos en hardware más lentos al nuestro, monitorizar el código cuando no tenemos los fuentes (¡ejem!), hacer pruebas de stress simulando fallos en la adquisiciónde recursos, ...

        La principal ventaja es que el código de depuración y prueba está separado del código de producción. De forma que se pueden hacer pruebas sin modificar el  código. Y sin "empantanarlo" con macros, mensajes de trazas, o condiciones de prueba.

        En el .zip se distribuye un proyecto en Visual C++ 6 con el código de la DLL y un ejecutable de ejemplo. En la DLL se ha modificado GetDeviceCaps() para que simule que el tamaño de las dimensiones máximas de una textura soportados por la tarjeta es 256x256.

        Como posibles mejoras estaría implementar clases que hereden del resto de interfases expuestas por D3D. Por ejemplo, sobrecargando el método
        CreateDevice para que retorne una clase especializada de IDirect3DDevice9.

        Puedes bajarte el codigo de:

        http://www.stratos-ad.com/codigosemana/d3d9trace.zip


        Saludos, Juan Mellado

        Éste código fue enviado por Juan Mellado, si quiere enviar tu propio código hazlo a eth_cotd@lycos.es

          #94


            Este es un código en apariencia sencillo, pero muy util. Es una función
            que sirve para realizar incrementos a una variable que almacena un
            ángulo. Se establecen dos topes para los valores válidos de ese ángulo,
            de tal manera que nunca podrá ser menor que un mínimo ni mayor que un
            máximo establecido.

            El código es muy versatil, ya que no funciona restringiendo los valores
            de ángulos no válidos, sino comprobando el valor original y el valor
            después del incremento.

            Por ejemplo, poniendo un valor mínimo de -1 y un valor máximo de 1, el
            ángulo solo tendrá un arco de giro de 2 grados; pero poniendo los
            límites a la inversa, mínimo 1 y máximo -1, el arco de giro será de 358

            grados.

            Un ejemplo típico de su uso es el de la cámara de un FPS, donde el giro
            en el eje X está limitado a -90º (mirar hacia abajo) y 90º (mirar hacia
            arriba).

            Parece una tonteria de función, pero tiene su cosa para que funcione con
            CUALQUIER límite de ángulos. Por lo menos yo me estuve machacando la
            cabeza muchas horas hasta que conseguí esta solución tan sencilla. Si a
            alguien le parece que sobra algo o que falta algo que lo diga en voz alta....

            un saludo
            fiero





          //Devuelve un valor entre -180.0 y 180.0

          float negAng(float angulo)

          {

          angulo=fmod(angulo,360);

          if(angulo>180) angulo-=360;

          if(angulo<-180) angulo+=360;

          return(angulo);

          }



          //Devuelve un valor entre 0.0 y 360.0

          float posAng(float angulo)

          {

          angulo=fmod(angulo,360);

          if(angulo<0) angulo+=360;

          return(angulo);

          }



          //Suma un incremento a un angulo y devuelve un valor entre 0.0 y 360.0

          //dentro de los límites

          bool sumarAngulo(float *angulo,float incremento,float topemin,float topemax)

          {

          bool encontradoTope=0

          float ang,topeMAX,topeMIN;



          topeMAX=negAng(topemax);

          topeMIN=negAng(topemin);

          ang=negAng(*angulo);

          if(incremento>0)

          {

           if(ang>topeMAX) ang-=360;

           ang+=incremento;

           if(ang>topeMAX)

           {

            ang=topemax;

            encontradoTope=1;

           }

           *angulo=posAng(ang);

          }

          else if(incremento<0)

          {

           if(ang<topeMIN) ang+=360;

           ang+=incremento;

           if(ang<topeMIN)

           {

            ang=topemin;

            encontradoTope=1;

           }

           *angulo=posAng(ang);

          }

          return encontradoTope;

          }





          //Ejemplo de uso



          float rotacionCamaraX=0;

          float limiteAbajo=-50;

          float limiteArriba=60;



          sumarAngulo(&rotacionCamaraX,-10,limiteAbajo,limiteArriba);








            Éste código fue enviado por  fiero
            Si quieres enviar tu propio código hazlo a  
          eth_cotd@lycos.es
            #95


              La clase que presento sirve para cargar valores de configuración usando el lenguaje de script LUA (www.lua.org). La ventaja de usar un lenguaje de script en el archivo de configuración es que permite incluir cierta lógica en el mismo. Por ejemplo, el fichero de configuración siguiente, impide que se cometa un error al declarar el ancho y el alto de la pantalla ( no se me ocurrió un ejemplo mejor :P )




            --funcion tonta para ver que se puede incluir



            -- mas significado a un fichero de configuracion



            function pantalla(an,al)



               al = 480 / 640 * an



               return an, al



            end







            ancho, alto = pantalla(800,480)



            otro = ancho / alto



            nombre = "tholatmundontttAdiostmundo"





            Y a continuación como leeríamos los valores de ancho, alto, otro y nombre desde el programa





               ConfigFile mi_conf("configura.lua");







               double val;



               mi_conf.DaValor(val, "ancho");



               printf("valor de ancho = %fn",val);



               mi_conf.DaValor(val, "alto");



               printf("valor de alto = %fn",val);



               char *nombre=0;



               mi_conf.DaValor(nombre, "nombre");



               printf("valor de nombre = %sn",nombre);



               mi_conf.DaValor(val, "otro");



            printf("valor de otro = %fn",val);






            La ventaja de usar este tipo de archivos de configuración es la potencia que tienen y a la vez la simplicidad de uso. Otra ventaja en el caso de LUA es que el archivo de configuración puede compilarse a un archivo binario, sin necesidad de tocar el programa propio.



            A continuación pongo el código de la clase. Comentar lo siguiente. El constructor ejecuta el fichero de configuración y si ocurre algún error lo marca en una variable booleana, esto permite impedir que se llame erróneamente a funciones de Lua en el resto de la clase. Las funciones que comienzan con 'lua_' son del interfaz de LUA. Para ejecutar el programa se necesita 'lua.dll'.




            extern "C"{



            .#include "lua.h"



            };







            class ConfigFile{



            public:



               ConfigFile(const char *file);



               ~ConfigFile();







               bool DaValor(double &val, const char *nom);



               bool DaValor(const char *(&val),const char *nom);







            private:



               lua_State *m_lua;



               bool mb_error;



            };







            ConfigFile::ConfigFile(const char *file){



               m_lua = lua_open(100);



               mb_error = (0 != lua_dofile(m_lua, file));



            }







            ConfigFile::~ConfigFile(){



               if( mb_error ) return;



               lua_close(m_lua);



            }







            bool ConfigFile::DaValor(double &val, const char *nom){



               if( mb_error ) return false;



               // meter en la pila el valor de nom



               lua_getglobal(m_lua, nom);



               int indice = lua_gettop(m_lua);







               bool retorno = false;



               // si nom es un nombre



               if( lua_isnumber(m_lua, indice) ){



                   // obtener el valor de nom



                   val=lua_tonumber(m_lua, indice);



                   retorno = true;



               }







               // restaurar la pila



               lua_pop(m_lua, 1);



               return retorno;



            }







            bool ConfigFile::DaValor(const char *(&val),const char *nom){



               if( mb_error ) return false;



               // meter en la pila el valor de nom



               lua_getglobal(m_lua, nom);



               int indice = lua_gettop(m_lua);







               bool retorno = false;



               // si nom es un string



               if( lua_isstring(m_lua, indice) ){



                   // obtener el valor de nom



                   val = lua_tostring(m_lua, indice);



                   retorno = true;



               }







               // restaurar la pila



               lua_pop(m_lua, 1);



               return retorno;



            }





            Puedes bajar el codigo de:

                    http://www26.brinkster.com/zhen4/config.zip


            Un saludo, Luis Cabellos

            Web: http://www.zhenstudio.net

            Éste código fue enviado por Luis Cabellos  el  1 de marzo del 2003 zhen@iespana.es

            Si quieres enviar tu propio código hazlo a  eth_cotd@lycos.es
              #96
              Código de la Semana / madbomber - feclare
              02 de Marzo de 2003, 04:47:47 PM
              #97
              Código de la Semana / Parser hexadecimal - CordayUK
              23 de Febrero de 2003, 05:28:07 PM
                Parser hexadecimal


                A ver si animamos un poco el Codigo de la Semana que esta muy aburido ultimamente

                mando este trozo de codigo que estuve escribiendo el otro dia, del cual no estoy muy contento porque estoy seguro que se puede hacer mejor... si alguien se anima que me de su version mejorada y se lo agradecere enormemente con mujeres y vino XDDD

                la idea es convertir una cadena que representa un DWORD en una variable DWORD propiamente dicha.
                Esto es muy util cuando tienes un fichero de ascii con valores que quieres introducir en tu juego, digamos un fichero INI, XML o lo que sea...

                FOG_COLOR = FFAAAA11

                al leer el fichero obtenemos una cadena "FFAAAA11" pero queremos meter este valor en un DWORD para pasarselo a DX por ejemplo.





              typedef unsigned long DW;   //es lo mismo que el DWORD definido en windows.h



              inline unsigned char __CHAR2BYTE (unsigned char c)

              {

                switch (c)

                {

                   case '0': return 0x0;

                   case '1': return 0x1;

                   case '2': return 0x2;

                   case '3': return 0x3;

                   case '4': return 0x4;

                   case '5': return 0x5;

                   case '6': return 0x6;

                   case '7': return 0x7;

                   case '8': return 0x8;

                   case '9': return 0x9;

                   case 'A': return 0xA;

                   case 'B': return 0xB;

                   case 'C': return 0xC;

                   case 'D': return 0xD;

                   case 'E': return 0xE;

                   case 'F': return 0xF;

                }

                return 0x0;

              }



              DW GetValueDW (char* pszValue)

              {

              DW dw = 0x00000000;





                //comprobar cadena

                if (!pszValue || strlen (pszValue)<8) return dw;



                //meter en el dword cada char de la cadena

                for (short int i=0; i<8; i++)

                   dw = dw | (0x00000000 | __CHAR2BYTE (*(pszValue+i))<< (28-(i*4)));



                return dw;

              }








                Éste código fue enviaro por CordayUK.
                Si quieres enviar tu propio código puedes hacerlo a
              eth_cotw@lycos.es
                #98
                Código de la Semana / Clase para manejo de ini - Julio Gorgé
                16 de Febrero de 2003, 05:04:59 PM


                  Autor:  Julio Gorgé
                  Web:           http://zsgames.cjb.net
                  Código fuente: http://www.alu.ua.es/j/jgf8/code/inifile.zip

                    Este COTW es una clase para trabajar con ficheros .ini. Permite consultar y modificar su contenido, siguiendo siempre el estándar de los ficheros de Windows:



                             [seccion]

                             clave=valor

                             clave2=valor2



                             [seccion2]

                             clave=valor

                             ...



                  Los ficheros .ini son útiles en la programación de juegos porque pueden ser modificados por personas sin conocimientos de programación con un editor de textos cualquiera. Unreal Tournament 2003 y NFS:Hot Pursuit 2 son dos de los juegos más recientes que usan este tipo de archivos para su configuración.



                  La API de Windows proporciona funciones como GetPrivateProfileString o WriteProfileString, que simplifican el manejo de ficheros .ini. La clase que he creado utiliza internamente estas funciones, pero ahorra código a la hora de acceder a numerosas claves.



                  En el ejemplo que se incluye junto con el código fuente de la clase, podeis ver qué fácil es usar la clase IniFile:




                  #include <windows.h>



                  #include "inifile.h"











                  void main()



                  {



                        IniFile* pIni = new IniFile("settings.ini");



                       



                        if(pIni)



                        {



                               // Get [graphics]



                               //            mode=...



                             



                               char szGraphicMode[32];



                             



                               pIni->GetKey((char*)szGraphicMode,"graphics","mode");



                               MessageBox(NULL,szGraphicMode,"Selected mode",MB_OK);



                             



                               // Set [graphics]



                               //            bpp=16



                             



                               pIni->SetKey("16","graphics","bpp");



                             



                               // Check [sound]



                               //            3d=true



                             



                               if(pIni->IsKeyTrue("sound","3d"))



                                      MessageBox(NULL,"3d sound enabled","Status",MB_OK);



                             



                             



                               delete pIni;



                        }



                       



                  }





                  Aquí hemos supuesto que tenemos un fichero de texto en el mismo directorio del programa llamado "settings.ini" donde tenemos guardada la configuración de nuestro juego.



                  Primero consultamos una clave, luego modificamos una, y finalmente comprobamos que una de las claves tiene como valor "true". Hacer todo esto sin la ayuda de una clase genera mucho código.



                  Si probais a dar valor a una clave que no existe, comprobaréis que automáticamente se crea la sección necesaria(si no existía ya) y la clave con el nombre adecuado.



                  Ahora os toca a vosotros enviar los bugs que encontréis(que los tiene) y proponer posibles mejoras.



                  Julio Gorgé, ZS Games

                  Éste código fue enviado por Julio Gorgé aka ZaelsiuS el 6 de febrero del 2003

                  Si quieres enviar tu propio código hazlo a  eth_cotd@lycos.es
                  #99
                  Código de la Semana / Video driver - mICrO
                  07 de Febrero de 2003, 10:18:25 PM


                       Basicamente es para que la gente vea como hacer un sistema de drivers para su motor/juego, etc.

                       Este es un ejemplo de como conseguir cargar la implementacion de una clase de una dll de esta manera con muy pocos cambios conseguir por ejemplo renderizar con OpenGL Direct3d o cualquier otra API sin tener que cambiar ni una linea de codigo.

                       Aunque aqui se muestra como ejemplo un driver de video se puede aplicar a otros sistemas como AI, sonido...

                       Si quieres ver implementaciones de este tipo en el codigo fuente del quake o del unreal puedes ver como se usa este sistema.






                  //////////////////////////////////////////////////////////////////////

                  // Video.h: interface for Video DLLs

                  // Common Use

                  //////////////////////////////////////////////////////////////////////



                  #if !defined(TVideoDriver__INCLUDED_)

                  #define TVideoDriver__INCLUDED_



                  // this is actually our interface, i added only a few functions

                  struct TVideoDriver

                  {

                  // get driver name

                  virtual void getName(char* strOut);



                  // init the driver

                  virtual BOOL initialize(HWND window);



                  // finish the driver

                  virtual BOOL finalize();



                  // setup the driver

                  virtual BOOL setup();



                  // begin a frame

                  virtual BOOL beginFrame();



                  // end a frame

                  virtual BOOL endFrame();



                  // open the driver for rendering

                  virtual BOOL openVideo(HWND renderWindow);



                  // close the driver for rendering

                  virtual BOOL closeVideo();

                  };



                  // the only function that a driver must export

                  typedef TVideoDriver*(*ptrFuncGetVideoDriver)();



                  #endif // !defined(TVideoDriver__INCLUDED_)



                  //////////////////////////////////////////////////////////////////////

                  // main.cpp: dll main

                  // This in CustomDriver.Dll

                  //////////////////////////////////////////////////////////////////////



                  // just the driver object

                  CCustomVideoDriver driver;



                  // return a cast to the interface

                  extern "C" __declspec(dllexport) TVideoDriver* getVideoDriver()

                  {

                  return (TYakVideoDriver*) &

                  }





                  //////////////////////////////////////////////////////////////////////

                  // CustomVideoDriver.h: Declaration of our driver

                  // This in CustomDriver.Dll

                  //////////////////////////////////////////////////////////////////////

                  class CCustomVideoDriver : public TYakVideoDriver

                  {

                  public:



                  // driver interfaces



                  void getName(char* strOut);



                  BOOL initialize(HWND window);  

                  BOOL finalize();



                  BOOL setup();





                  BOOL beginFrame();

                  BOOL endFrame();



                  BOOL openVideo(HWND renderWindow);

                  BOOL closeVideo();



                  // custom data, just a posible example

                  private:



                  D3D9TextureManager* pManager;

                  }





                  //////////////////////////////////////////////////////////////////////

                  // CustomVideoDriver.cpp: Code of our driver (just example)

                  // This in CustomDriver.Dll

                  //////////////////////////////////////////////////////////////////////

                  BOOL CCustomVideoDriver::initialize(HWND window)

                  {

                  return initD3D9(); // and so on

                  }







                  //////////////////////////////////////////////////////////////////////

                  // DriverManager.h: Manage the drivers

                  // This in our game.exe

                  //////////////////////////////////////////////////////////////////////

                  class CVideoManager

                  {

                  public :



                  BOOL loadDriver(char* fileName);

                  BOOL unloaDriver();

                  inline TYakVideoDriver* getDriver(){return driver;}

                  private :



                  HMODULE libraryHandle;

                  TYakVideoDriver* driver;

                  }



                  //////////////////////////////////////////////////////////////////////

                  // DriverManager.cpp: Manage the drivers

                  // This in our game.exe

                  //////////////////////////////////////////////////////////////////////

                  BOOL CVideoManager::loadDriver(char* fileName)

                  {

                  BOOL result = TRUE;



                  libraryHandle = LoadLibrary(fileName);



                  if (libraryHandle != NULL)

                  {

                   ptrFuncGetVideoDriver funcGetDriver =(ptrFuncGetVideoDriver)

                    GetProcAddress(libraryHandle, "getVideoDriver");

                   

                   if (funcGetDriver != NULL)

                    driver = funcGetDriver();

                   else

                    result = FALSE;

                  }

                  else

                  {

                   result = FALSE

                   driver = NULL;

                  }



                  return result;

                  }





                  //////////////////////////////////////////////////////////////////////

                  // game.cpp: Some code to see how we could use it

                  // This in our game.exe

                  //////////////////////////////////////////////////////////////////////



                  void game()

                  {

                  videoManager.getDriver()->OpenVideo(mainWindow);

                  }








                    Éste código fue enviado por mICrO.

                    Si quieres enviar tu propio código hazlo a  
                  eth_cotd@lycos.es
                    #100
                    General Programadores / fuentes del unreal
                    21 de Enero de 2003, 06:01:37 PM
                    Os habeis echado una ojeada a las fuentes del unreal (las q dejan publicas) ?. q os parecen ? os funciona el driver de opengl? os parece bueno el diseño?

                    saludos





                    Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
                    Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
                    Muchísimas gracias.