• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.

DrMol

Members
  • Content count

    134
  • Joined

  • Last visited

Community Reputation

122 Neutral

About DrMol

  • Rank
    Member
  1. std::list Is that an actualy linked list template or do you mean one of the many available, like std::vector or something. I have not used any of Microsoft's templates very much (It is a template, right) so maybe I'll check it out on msdn. DrMol
  2. Thanks for the help guys! Can't wait to take a look at that source. Dan
  3. In my quest to create the greatest RPG of all time ;) I wanted to code a GUI. Well, maybe it isn't for the superRPG, I really am taking this on as a learning experience. I have gotten to a point where I can compile this bad boy and get pretty much want I wanted to get, but with memory leaks (I assume) everywhere, problems left and right, i am sure, and so on...as I said, a learning experience. So I have deceided to put this up, especially since I need to hear that I am doing something right (I hope) to keep my morale up. I figure who to show this to but people who know what they are doing and want to help someone learn. I apologize for the size, basically these windows are, in order: Main GUI Interface class interface Main GUI Interface class implementation Drawing class interface Drawing class implementation Button object interface Button object implementation The homemade linked list I whipped up to keep track of all the children. I would be BEYOND grateful, near enough to pledge my firstborn (not quite though...maybe when someone reviews my 3-d super dooper engine). Seriously, I would be so helpful if someone could take a little time and give me a bit of guidance on what I do wrong, what I do right. I think the code is understandable...I hope it is anyways. Also, I zipped up the whole damn thing and stuck it on my school site... I hope my only html skills still are up to par... GUI.zip One thing, I am by no means asking anyone to debug my stuff or tell me how to program. This thing does work. I get a button a moving mouse, static text and an update of the mouse location. I just really am asking if someone can take a look and tell me where I am moving in the right direction and where I am moving in the wrong direction. Thanks again! Much Obliged DrMol The Main GUI interface class CWindow_GUI { public: ////////////// //Boring stuff ////////////// CWindow_GUI(); virtual ~CWindow_GUI(); virtual void Init( ); void SetDXSystem( CDXDraw *DXControl ); //static CDXDraw* //CDXDraw *GetDXSystem( ); ////////////////////// //Subwindows and stuff ////////////////////// CWindow_GUI *GetParentWindow( ); bool AddWindow( CWindow_GUI *window ); void DeleteWindow( CWindow_GUI *window ); void SetParentWindow( CWindow_GUI *window ); void BringToTop( ); bool CleanUp( ); // void SetText( CTextGrinder cTG ); ///////////// //Visibility ///////////// void SetVisible( bool vis = true ); bool GetVisible( ) const; void SetActive( bool Act = true ); void GetActive( ); ///////////// //Positioning //////////// void SetPos( long x, long y ); void SetSize( long Width, long Height ); bool ClickInside( int x, int y); int MouseWindow( int MouseX, int MouseY, short button, short prevstate ); //Call this is mouse polling indicates a change of state int MouseStateChange( int MouseX, int MouseY, short button, short prevstate ); // int VirtXPixel( int virtx ); // int VirtYPixel( int virty ); virtual void Test( int a ); ///////////////////////////////////// //Window creation //////////////////////////////////// int RenderAll( ); virtual int RenderWindow( ); //////////////////////////////////// //Messaging, mechanics //////////////////////////////////// virtual void GM_MOUSEACTION( int MouseX, int MouseY, short Btn, short LastBtnState ); virtual void GM_CHILDCLICKED( );// const; //////////////////////////////////// //Messaging, user defined //////////////////////////////////// virtual void GM_USERACTION_MOUSE( int Btn ); // virtual void GM_ACTIVATED( ); ConvertXToMS( int X ); ConvertYToMS( int Y ); private: bool GUIWindowVisible; bool Visible; int index; CWindow_GUI *winParent; ArrayPtrCtrl< CWindow_GUI* > subWins; //the array of pointers to subwindows bool Act; protected: // CTextGrinder cText; CDXDraw *DXControl; SWindowCoord sCoord; bool TWindow; int ele; bool CTE( ); }; The Main class implementation CWindow_GUI::CWindow_GUI() { TWindow = false; winParent = NULL; index = 0; sCoord.Height = 300; sCoord.Width = 300; sCoord.pos.top = 0; sCoord.pos.left = 0; } CWindow_GUI::~CWindow_GUI() { winParent = NULL; //no parent. subWins.~ArrayPtrCtrl( );//Delete all subwindows } CWindow_GUI *CWindow_GUI::GetParentWindow( ) { return winParent; }; bool CWindow_GUI::AddWindow( CWindow_GUI *window ) { //Make sure window is valid if ( window == NULL ) return false; subWins.Add( window );//subWins window->SetParentWindow( this ); if ( subWins.IsEmpty( ) == true ) return false; return true; } void CWindow_GUI::SetParentWindow( CWindow_GUI *window) { winParent = window; } void CWindow_GUI::DeleteWindow( CWindow_GUI *window ) { subWins.Delete( window ); window->SetParentWindow( NULL ); }; ////////////////////// void CWindow_GUI::SetVisible( bool vis ) { Visible = vis; }; bool CWindow_GUI::GetVisible( ) const { return Visible; }; ///////////////////////// void CWindow_GUI::SetSize( long Width, long Height ) { sCoord.Width = Width; sCoord.Height = Height; sCoord.pos.right = Width + sCoord.pos.left; sCoord.pos.bottom = Height + sCoord.pos.top; CWindow_GUI *cGW = NULL; cGW = GetParentWindow( ); /* if( cGW != NULL ) { if( cGW->sCoord.pos.bottom < sCoord.pos.bottom ) { sCoord.pos.top = cGW->sCoord.pos.bottom - sCoord.Height; //translate up sCoord.pos.bottom = cGW->sCoord.pos.bottom; } if( cGW->sCoord.pos.right < sCoord.pos.right ) { sCoord.pos.left = cGW->sCoord.pos.right - sCoord.Width; //translate left sCoord.pos.right = cGW->sCoord.pos.right; } }; */ } void CWindow_GUI::SetPos( long x, long y ) { sCoord.pos.left = x; sCoord.pos.top = y; CWindow_GUI *cGW = NULL; cGW = GetParentWindow( ); /*if( cGW != NULL ) { if( cGW->sCoord.pos.left > sCoord.pos.left ) sCoord.pos.left = cGW->sCoord.pos.left; if( cGW->sCoord.pos.top > sCoord.pos.top ) sCoord.pos.top = cGW->sCoord.pos.top; };*/ sCoord.pos.right = sCoord.Width + sCoord.pos.left; sCoord.pos.bottom = sCoord.Height + sCoord.pos.top; } ////////////////////////////////////////// void CWindow_GUI::BringToTop( ) { winParent->DeleteWindow( this ); winParent->AddWindow( this ); } /* int CWindow_GUI::VirtXPixel( int virtx ) { // int width = (cWindow_Parent) ? cWindow_Parent->getpos().getwidth() : getscreendims().getwidth(); // return((int)((double)virtx*(double)width/GUI_SCALEX)); } */ void CWindow_GUI::Init( ) { // Font = "Arial"; // Point = 12; // index = 0; } int CWindow_GUI::RenderWindow( ) { return 0; } int CWindow_GUI::RenderAll( ) { RenderWindow( ); int ind = subWins.GetCount( ); //Creates a starting spot for tree CWindow_GUI *cPtr; //Create a basic window pointer if( subWins.GetCount( ) < 0 ) return false; //error if( ind == 0 ) //No more children { return 0; }; while ( ind >= 0 ) //Go through rest of children { cPtr = subWins.GetDataBW( ind ); cPtr->RenderAll( ); ind--; }; return -1; }; void CWindow_GUI::SetDXSystem( CDXDraw *cDXDraw ) { DXControl = cDXDraw; }; /* CDXDraw *CWindow_GUI::GetDXSystem( ) { return DXControl; } */ int CWindow_GUI::MouseWindow( int MouseX, int MouseY, short button, short prevstate ) { int ind = subWins.GetCount( ); //Creates a starting sport for tree CWindow_GUI *cPtr; //Create a basic window pointer if( subWins.GetCount( ) < 0 ) return false; //error if( subWins.GetCount( ) == 0 ) //No more children { GM_MOUSEACTION( MouseX, MouseY, button, prevstate ); return 0; }; while ( ind > 0 ) //Go through rest of children { cPtr = subWins.GetDataBW( ind ); cPtr->MouseWindow( MouseX, MouseY, button, prevstate ); ind--; }; return true; } bool CWindow_GUI::ClickInside( int x, int y ) { bool xVal, yVal; xVal = yVal = false; if( x >= sCoord.pos.left && x <= sCoord.pos.right ) xVal = true; if( y >=sCoord.pos.top && y <= sCoord.pos.bottom ) yVal = true; if( xVal == true && yVal == true ) return true; return false; }; void CWindow_GUI::GM_CHILDCLICKED( ) //const { BringToTop( ); }; int CWindow_GUI::MouseStateChange( int MouseX, int MouseY, short button, short prevstate ) { //Something has happened with the mouse //if ( button is up ) and move = true, let windows handle it //else, a button state has changed //Get the window that it happened in, recusion here MouseWindow( MouseX, MouseY, button, prevstate ); //Let that window know that it has been clicked and pass all mouse info, button, last button state etc, hand the problem off return 0; }; bool CWindow_GUI::CleanUp( ) { CWindow_GUI *cPtr = NULL; //Number of elements in the list // MessageBox( hWnd, "Start Debug", "CLEANUP", MB_OK ); // if( index > subWins.GetCount( ) ) //error // return false; index++; //bump the thing if ( subWins.IsValid( index - 1 ) == true && subWins.IsEmpty( ) == false )//this window has children { //get the pointer to the last element //Bump the count since we dont start with index = 0 cPtr = subWins.GetData( index - 1 ); cPtr->CleanUp( ); } else if ( subWins.IsEmpty( ) == false && subWins.IsValid( index -1 ) == false ) { subWins.DeleteAll( ); cPtr = winParent; if ( cPtr == NULL ) //this window has no parent { index = 0; //So reset the counter return false; //End the function }; // cPtr = winParent; } else //no children { cPtr = winParent; // return 0; if ( cPtr == NULL ) //this window has no parent { index = 0; //So reset the counter return false; //End the function }; }; cPtr->CleanUp( ); //Continue the parents render function return true; } void CWindow_GUI::GM_MOUSEACTION( int MouseX, int MouseY, short Btn, short LastBtnState ) { //Do nothing } void CWindow_GUI::Test( int a ) { } void CWindow_GUI::GM_USERACTION_MOUSE( int Btn ) { } The Drawing class interface, draws all the objects. Wrapped not inplemented seperatley class CDXDraw { friend class CWindow; public: CDXDraw( ); virtual ~CDXDraw(); bool Init( IDirect3DDevice8 *GraphicSystem, HWND h_Wnd ); bool PrepareToDraw( ); /////////////////////////////////////////////// //Window Drawing functions ////////////////////////////////////////////// bool DrawWindow( RECT Coord, struct SWinImages ); bool DrawStatic( RECT Coord, STxtInf sTextInf, char *Text ); bool DrawButton( RECT Coord, SButtonInf sBI ); int ScaleX( int x ); int ScaleY( int y ); void ScaleRect( RECT &r ); /* bool DrawButton( RECT winRect, SButtonInf sBI, LPDIRECTDRAWSURFACE7 lpDDS ); bool ButtonBlit( RECT winRect, LPDIRECTDRAWSURFACE7 lpDDS ); */ private: /////////////////////////////////////////////// //Window Drawing functions ////////////////////////////////////////////// IDirect3DDevice8 *DXDevice; ID3DXFont *DXFont; LOGFONT lf; HWND hWnd; CD3DFont *hFont; bool Init2D( ); bool DrawButtonAuto( RECT Coord, SButtonInf sBI ); bool DrawBorderedBox( RECT Coord, SButtonInf sBI, bool NoBox = false ); int SysWidth, SysHeight; RECT windowSize; }; The Drawing class implementation, this needs the most work, i guess CDXDraw::CDXDraw( ) { SysWidth=800; SysHeight =600; DXFont = NULL; } CDXDraw::~CDXDraw() { if( hFont ) { hFont->DeleteDeviceObjects( ); delete hFont; hFont = NULL; } DXDevice->Release( ); } bool CDXDraw::Init( IDirect3DDevice8 *GraphicsSystem, HWND h_Wnd ) { if( ( DXDevice = GraphicsSystem ) == NULL ) return false; hWnd = h_Wnd; return true; } bool CDXDraw::DrawWindow( RECT Coord, SWinImages sWI) { bool BGFill = false; LPDIRECT3DTEXTURE8 Tex = NULL; //ERROR CHECKING if( Coord.right < Coord.left ) return false; if( Coord.bottom < Coord.top ) return false; if( DXDevice == NULL ) return false; SButtonInf sBI; //DRAW THE BORDERS if( sWI.BordersOn == true ) { sBI.BorderWidth = 3; sBI.DrawUp = true; DrawBorderedBox( Coord, sBI, true ); } else sBI.BorderWidth = 0; Coord.bottom -= sBI.BorderWidth; Coord.top += sBI.BorderWidth; Coord.left += 2 * sBI.BorderWidth; Coord.right -= sBI.BorderWidth; //SEE IF WE ARE USING A BG COLOR OR AN IMAGE if( sWI.BG == NULL ) BGFill = TRUE; if( BGFill == FALSE ) { if( FAILED ( D3DXCreateTextureFromFileEx( DXDevice, sWI.BG, 0, 0, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &Tex ) ) ) BGFill = TRUE; } //SET THIS THING UP AS A BILLBOARD D3DXMATRIX Mtrx2D; D3DXMATRIX Identity; D3DXMatrixOrthoLH( &Mtrx2D, (float) SysWidth, (float) SysHeight, 0.0f, 1.0f ); D3DXMatrixIdentity( &Identity ); DXDevice->SetTransform( D3DTS_PROJECTION, &Mtrx2D ); DXDevice->SetTransform( D3DTS_WORLD, &Identity ); DXDevice->SetTransform( D3DTS_VIEW, &Identity ); LPDIRECT3DVERTEXBUFFER8 Vertices = NULL; //WORK OUT THE SIZES float Width = (float) ( Coord.right ) - (float) ( Coord.left ); float Height = (float) ( Coord.bottom )- (float) ( Coord.top ); ScaleRect( Coord ); //SEND THE VERTICES TO THE BUFFER AND SET UP THE INFO DXDevice->CreateVertexBuffer( 8 * sizeof( PARAMETERS ), D3DUSAGE_WRITEONLY, FVF_WINDOWVERTEX, D3DPOOL_MANAGED, &Vertices ); PARAMETERS *pVertices = NULL; Vertices->Lock (0, 0, (BYTE**) &pVertices, 0 ); pVertices[0].color = pVertices[1].color = pVertices[2].color = pVertices[3].color = sWI.color; pVertices[0].x = pVertices[3].x = -Width / 2.0f; pVertices[1].x = pVertices[2].x = Width/2.0f ; pVertices[0].y = pVertices[1].y = Height/2.0f; pVertices[2].y = pVertices[3].y = -Height/2.0f; pVertices[0].z = pVertices[1].z = pVertices[2].z = pVertices[3].z = 0.0f; pVertices[1].u = pVertices[2].u = 1.0f; pVertices[0].u = pVertices[3].u = 0.0f; pVertices[0].v = pVertices[1].v = 0.0f; pVertices[2].v = pVertices[3].v = 1.0f; /////////////////////////////////////////////////////// pVertices[4].x = pVertices[7].x = -Width / 2.0f ; pVertices[5].x = pVertices[6].x = Width / 2.0f; pVertices[4].y = pVertices[5].y = ( Height * .1 ) / 2 + ( Height / 2 ) - ( ( Height * .1) / 2 ); pVertices[6].y = pVertices[7].y = -( Height * .1 ) / 2 + ( Height / 2 ) - ( (Height * .1) / 2 ); pVertices[4].z = pVertices[5].z = pVertices[6].z = pVertices[7].z = 0.0f; pVertices[4].color = pVertices[5].color = pVertices[6].color = pVertices[7].color = sWI.TitleColor; Vertices->Unlock( ); //TODO: put lock and unlock only once in rendering sequence //MOVE IT BASED ON ENTERED COORDS D3DXMATRIX Position; D3DXMatrixTranslation( &Position, -( ( SysWidth / 2.0f ) - ( Width/2.0f ) ) + Coord.left, ( SysHeight / 2.0f ) - ( Height/2.0f ) - Coord.top , 0.0f ); DXDevice->SetTransform( D3DTS_WORLD, &Position ); //RENDER IT TO THE BACK BUFFER if( BGFill == FALSE ) DXDevice->SetTexture( 0, Tex ); DXDevice->SetRenderState( D3DRS_LIGHTING, FALSE ); DXDevice->SetVertexShader( FVF_WINDOWVERTEX ); DXDevice->SetStreamSource( 0, Vertices, sizeof( PARAMETERS ) ); DXDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 ); if( BGFill == TRUE ) { DXDevice->SetTexture( 0, NULL ); if( Tex != NULL ) Tex->Release( ); } ////////////////////////////////////////////////////////////// if( sWI.TitleBar == true ) { if( sWI.TitleLoc != NULL ) { D3DXCreateTextureFromFileEx( DXDevice, sWI.TitleLoc, 0, 0, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &Tex ); DXDevice->SetTexture( 0, Tex ); }; DXDevice->SetStreamSource( 0, Vertices, sizeof( PARAMETERS ) ); DXDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 4, 2 ); sWI.TitleText = "Hello World"; if( sWI.TitleText != NULL ) { STxtInf sTextInf; sTextInf.Color = 0xff000000; sTextInf.Font = "Arial"; //TODO:Make variable sTextInf.Point = ( ( (int)( Height * .1 ) % 2 ) ? Height : ( Height - 1 ) ); sTextInf.Bold = 0; sTextInf.Italic = false; sTextInf.Underline = false; sTextInf.Center = FALSE; sTextInf.VCenter = FALSE; Coord.left = Coord.left / 2; //+3 is a buffer from left Coord.top = Coord.top / 2 + 11;// + ( 6 + 2 * sBI.BorderWidth ); sTextInf.Point = 12; DrawStatic( Coord, sTextInf, sWI.TitleText ); }; } return true; } bool CDXDraw::DrawStatic( RECT Coord, STxtInf sTextInf, char *Text ) { DWORD Flag = 0L; if( sTextInf.Bold == true ) Flag = 0x0001; hFont = new CD3DFont( sTextInf.Font, sTextInf.Point, Flag ); hFont->InitDeviceObjects( DXDevice ); hFont->RestoreDeviceObjects( ); ScaleRect( Coord ); SIZE fExt; hFont->GetTextExtent( Text, &fExt ); Coord.top += (Coord.bottom - Coord.top - fExt.cy )/2; Coord.left += ( Coord.right - Coord.left - fExt.cx )/2 ; hFont->DrawText( Coord.left, Coord.top, sTextInf.Color, Text ); return true; } bool CDXDraw::DrawButton( RECT Coord, SButtonInf sBI ) { SWinImages sWI = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; char *txt; if( sBI.DrawUp == true ) { sWI.BG = sBI.UImage; txt = sBI.UText; } else { sWI.BG = sBI.DImage; txt = sBI.DText; } if( sBI.AutoDraw ) DrawBorderedBox( Coord, sBI ); else { sWI.color = 0xffffff; //Backup, but can't be black sWI.TitleBar = false; //Make sure the thing doesn't draw a title bar DrawWindow( Coord, sWI ); } sBI.sTxtInf.Center = TRUE; sBI.sTxtInf.VCenter = TRUE; DrawStatic( Coord, sBI.sTxtInf, txt ); return true; } bool CDXDraw::DrawBorderedBox( RECT Coord, SButtonInf sBI, bool NoBox ) { //Add in a texture handler later LPDIRECT3DVERTEXBUFFER8 VtxLBox = NULL; LPDIRECT3DVERTEXBUFFER8 VtxBBox = NULL; if( DXDevice == NULL ) return false; DWORD ColorDrkBase, ColorLtBase; if( sBI.DrawUp == TRUE ) { ColorDrkBase = 0xff000000; ColorLtBase = 0xffffffff; } else { ColorDrkBase = 0xffffffff; ColorLtBase = 0xff000000; } PARAMETERS *pVertices = NULL; DXDevice->SetRenderState( D3DRS_AMBIENT,RGB(255,255,255) ); DXDevice->SetRenderState( D3DRS_LIGHTING, FALSE ); DXDevice->SetVertexShader( FVF_WINDOWVERTEX ); //SET THIS THING UP AS A BILLBOARD D3DXMATRIX Mtrx2D; D3DXMATRIX Identity; D3DXMatrixOrthoLH( &Mtrx2D, (float) SysWidth, (float) SysHeight, 0.0f, 1.0f ); D3DXMatrixIdentity( &Identity ); DXDevice->SetTransform( D3DTS_PROJECTION, &Mtrx2D ); DXDevice->SetTransform( D3DTS_WORLD, &Identity ); DXDevice->SetTransform( D3DTS_VIEW, &Identity ); //WORK OUT THE SIZES float Width = (float) ( Coord.right ) - (float) ( Coord.left ); float Height = (float) ( Coord.bottom )- (float) ( Coord.top ); ScaleRect( Coord ); /////////////////////////////// //Draw big box DXDevice->CreateVertexBuffer( 4 * sizeof( PARAMETERS ), D3DUSAGE_WRITEONLY, FVF_WINDOWVERTEX, D3DPOOL_MANAGED, &VtxBBox ); VtxBBox->Lock (0, 0, (BYTE**) &pVertices, 0 ); //Color of corners pVertices[0].color = ColorLtBase ; pVertices[1].color = 0xffb6b6b6; //Medium grey pVertices[3].color = 0xffa0a0a0; pVertices[2].color = ColorDrkBase; //H/W of the big box pVertices[0].x = pVertices[3].x = -Width / 2.0f; pVertices[1].x = pVertices[2].x = Width/2.0f; pVertices[0].y = pVertices[1].y = Height/2.0f; pVertices[2].y = pVertices[3].y = -Height/2.0f; //Stupid stuff pVertices[0].z = pVertices[1].z = pVertices[2].z = pVertices[3].z = 0.0f; pVertices[1].u = pVertices[2].u = 1.0f; pVertices[0].u = pVertices[3].u = 0.0f; pVertices[0].v = pVertices[1].v = 0.0f; pVertices[2].v = pVertices[3].v = 1.0f; VtxBBox->Unlock(); ///////////////////////////////// //Draw little box (button itself) // sBI.BorderWidth = ScaleY( sBI.BorderWidth ); if( NoBox == false ) { DXDevice->CreateVertexBuffer( 4 * sizeof( PARAMETERS ), D3DUSAGE_WRITEONLY, FVF_WINDOWVERTEX, D3DPOOL_MANAGED, &VtxLBox ); VtxLBox->Lock (0, 0, (BYTE**) &pVertices, 0 ); //Color is all the same pVertices[0].color = pVertices[1].color = pVertices[3].color = pVertices[2].color = sBI.color; //W/H, this is modified pVertices[0].x = pVertices[3].x = -Width / 2.0f + sBI.BorderWidth; pVertices[1].x = pVertices[2].x = Width /2.0f - sBI.BorderWidth; pVertices[0].y = pVertices[1].y = Height/2.0f - sBI.BorderWidth; pVertices[2].y = pVertices[3].y = -Height/2.0f + sBI.BorderWidth; //Useless crap pVertices[0].z = pVertices[1].z = pVertices[2].z = pVertices[3].z = 0.0f; pVertices[1].u = pVertices[2].u = 1.0f; pVertices[0].u = pVertices[3].u = 0.0f; pVertices[0].v = pVertices[1].v = 0.0f; pVertices[2].v = pVertices[3].v = 1.0f; VtxLBox->Unlock(); }; ///////////////////////////////////////////////// //TRANSLATION D3DXMATRIX Position; D3DXMatrixTranslation( &Position, -( ( SysWidth / 2.0f ) - ( Width/2.0f ) ) + Coord.left, ( SysHeight / 2.0f ) - ( Height/2.0f ) - Coord.top , 0.0f); //-( ( SysWidth / 2.0f ) - ( Width/2.0f ) ) + Coord.left, // ( SysHeight / 2.0f ) - ( Height/2.0f ) - Coord.top , // 0.0f // ); DXDevice->SetTransform( D3DTS_WORLD, &Position ); ///////////////////////////////////////////////// //RENDERING SEQUENCE DXDevice->SetStreamSource( 0, VtxBBox, sizeof( PARAMETERS ) ); DXDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 ); if( NoBox == false ) { DXDevice->SetStreamSource( 0, VtxLBox, sizeof( PARAMETERS ) ); DXDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 ); }; return true; } bool CDXDraw::DrawButtonAuto( RECT Coord, SButtonInf sBI ) { LPDIRECT3DVERTEXBUFFER8 VtxLeft = NULL; LPDIRECT3DVERTEXBUFFER8 VtxBottom = NULL; LPDIRECT3DVERTEXBUFFER8 VtxTop = NULL; LPDIRECT3DVERTEXBUFFER8 VtxRight = NULL; LPDIRECT3DVERTEXBUFFER8 VtxBox = NULL; DWORD ColorDrkFade, ColorDrkBase, ColorLtBase, ColorLtFade; if( sBI.DrawUp == TRUE ) { ColorDrkFade = 0xff7d7d7d; ColorDrkBase = 0xff646464; ColorLtBase = 0xffffffff; ColorLtFade = 0xffd2d2d2; } else { ColorDrkFade = 0xffd2d2d2; ColorDrkBase = 0xffffffff; ColorLtBase = 0xff646464; ColorLtFade = 0xff7d7d7d; } PARAMETERS *pVertices = NULL; if( DXDevice == NULL ) return false; DXDevice->SetRenderState( D3DRS_AMBIENT,RGB(255,255,255) ); DXDevice->SetRenderState( D3DRS_LIGHTING, FALSE ); DXDevice->SetVertexShader( FVF_WINDOWVERTEX ); //SET THIS THING UP AS A BILLBOARD D3DXMATRIX Mtrx2D; D3DXMATRIX Identity; D3DXMatrixOrthoLH( &Mtrx2D, (float) SysWidth, (float) SysHeight, 0.0f, 1.0f ); D3DXMatrixIdentity( &Identity ); DXDevice->SetTransform( D3DTS_PROJECTION, &Mtrx2D ); DXDevice->SetTransform( D3DTS_WORLD, &Identity ); DXDevice->SetTransform( D3DTS_VIEW, &Identity ); //WORK OUT THE SIZES float Width = (float) ( Coord.right ) - (float) ( Coord.left ); float Height = (float) ( Coord.bottom )- (float) ( Coord.top ); float Buffer = 5; ScaleRect( Coord ); //////////////////////////////////////////////////// //Left Square DXDevice->CreateVertexBuffer( 4 * sizeof( PARAMETERS ), D3DUSAGE_WRITEONLY, FVF_WINDOWVERTEX, D3DPOOL_MANAGED, &VtxLeft ); VtxLeft->Lock (0, 0, (BYTE**) &pVertices, 0 ); pVertices[0].color = pVertices[3].color = ColorLtBase; pVertices[1].color = pVertices[2].color = ColorLtFade; pVertices[0].x = pVertices[3].x = -Width / 2.0f ; pVertices[1].x = pVertices[2].x = -Width/2.0f +4; pVertices[0].y = Height/2.0f; //The angled corner pVertices[1].y = Height/2.0f; pVertices[2].y = -Height/2.0f; pVertices[3].y = -Height/2.0f - 2; pVertices[0].z = pVertices[1].z = pVertices[2].z = pVertices[3].z = 0.0f; pVertices[1].u = pVertices[2].u = 1.0f; pVertices[0].u = pVertices[3].u = 0.0f; pVertices[0].v = pVertices[1].v = 0.0f; pVertices[2].v = pVertices[3].v = 1.0f; VtxLeft->Unlock(); //////////////////////////////////////////////////// //Right Square DXDevice->CreateVertexBuffer( 4 * sizeof( PARAMETERS ), D3DUSAGE_WRITEONLY, FVF_WINDOWVERTEX, D3DPOOL_MANAGED, &VtxRight ); VtxRight->Lock (0, 0, (BYTE**) &pVertices, 0 ); pVertices[0].color = pVertices[3].color = ColorDrkBase; pVertices[1].color = pVertices[2].color = ColorDrkFade; pVertices[0].x = pVertices[3].x = Width / 2.0f ; pVertices[1].x = pVertices[2].x = Width/2.0f -4; pVertices[0].y = -Height/2.0f; //The angled corner pVertices[1].y = -Height/2.0f +3; pVertices[2].y = Height/2.0f -3; pVertices[3].y = Height/2.0f +1; pVertices[0].z = pVertices[1].z = pVertices[2].z = pVertices[3].z = 0.0f; pVertices[1].u = pVertices[2].u = 1.0f; pVertices[0].u = pVertices[3].u = 0.0f; pVertices[0].v = pVertices[1].v = 0.0f; pVertices[2].v = pVertices[3].v = 1.0f; VtxRight->Unlock(); /////////////////////////////////////////////////////// //Bottom Square DXDevice->CreateVertexBuffer( 4 * sizeof( PARAMETERS ), D3DUSAGE_WRITEONLY, FVF_WINDOWVERTEX, D3DPOOL_MANAGED, &VtxBottom ); VtxBottom->Lock (0, 0, (BYTE**) &pVertices, 0 ); pVertices[0].color = pVertices[1].color = ColorDrkFade; pVertices[3].color = pVertices[2].color = ColorDrkBase; pVertices[0].x = -Width / 2.0f + 4.45; pVertices[3].x = -Width / 2.0f - 1; pVertices[1].x = pVertices[2].x = Width/2.0f; pVertices[0].y = pVertices[1].y = -Height/2.0f +4 ; pVertices[2].y = -Height/2.0f -1; pVertices[3].y = -Height/2.0f -1; pVertices[0].z = pVertices[1].z = pVertices[2].z = pVertices[3].z = 0.0f; pVertices[1].u = pVertices[2].u = 1.0f; pVertices[0].u = pVertices[3].u = 0.0f; pVertices[0].v = pVertices[1].v = 0.0f; pVertices[2].v = pVertices[3].v = 1.0f; VtxBottom->Unlock(); /////////////////////////////////////////////////////// //Top Square DXDevice->CreateVertexBuffer( 4 * sizeof( PARAMETERS ), D3DUSAGE_WRITEONLY, FVF_WINDOWVERTEX, D3DPOOL_MANAGED, &VtxTop ); VtxTop->Lock (0, 0, (BYTE**) &pVertices, 0 ); pVertices[0].color = pVertices[1].color = ColorLtBase; pVertices[3].color = pVertices[2].color = ColorLtFade; pVertices[0].x = pVertices[3].x = -Width / 2.0f ; pVertices[1].x = Width/2.0f ; pVertices[2].x = Width/2.0f - 4; pVertices[0].y = pVertices[1].y = Height/2.0f +1 ; pVertices[2].y = pVertices[3].y = Height/2.0f -3; pVertices[0].z = pVertices[1].z = pVertices[2].z = pVertices[3].z = 0.0f; pVertices[1].u = pVertices[2].u = 1.0f; pVertices[0].u = pVertices[3].u = 0.0f; pVertices[0].v = pVertices[1].v = 0.0f; pVertices[2].v = pVertices[3].v = 1.0f; VtxTop->Unlock(); /////////////////////////////////////////////////////// //Box DXDevice->CreateVertexBuffer( 4 * sizeof( PARAMETERS ), D3DUSAGE_WRITEONLY, FVF_WINDOWVERTEX, D3DPOOL_MANAGED, &VtxBox ); VtxBox->Lock (0, 0, (BYTE**) &pVertices, 0 ); pVertices[0].color = pVertices[1].color = pVertices[3].color = pVertices[2].color = sBI.color; pVertices[0].x = pVertices[3].x = -Width / 2.0f +4; pVertices[1].x = pVertices[2].x = Width/2.0f -4; pVertices[0].y = pVertices[1].y = Height/2.0f -2; pVertices[2].y = pVertices[3].y = -Height/2.0f +4; pVertices[0].z = pVertices[1].z = pVertices[2].z = pVertices[3].z = 0.0f; pVertices[1].u = pVertices[2].u = 1.0f; pVertices[0].u = pVertices[3].u = 0.0f; pVertices[0].v = pVertices[1].v = 0.0f; pVertices[2].v = pVertices[3].v = 1.0f; VtxBox->Unlock(); ///////////////////////////////////////////////// //TRANSLATION D3DXMATRIX Position; D3DXMatrixTranslation( &Position, -( ( SysWidth / 2.0f ) - ( Width/2.0f ) ) + Coord.left, ( SysHeight / 2.0f ) - ( Height/2.0f ) - Coord.top , 0.0f); DXDevice->SetTransform( D3DTS_WORLD, &Position ); ///////////////////////////////////////////////// //RENDERING SEQUENCE DXDevice->SetStreamSource( 0, VtxBox, sizeof( PARAMETERS ) ); DXDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 ); DXDevice->SetStreamSource( 0, VtxLeft, sizeof( PARAMETERS ) ); DXDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 ); DXDevice->SetStreamSource( 0, VtxBottom, sizeof( PARAMETERS ) ); DXDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 ); DXDevice->SetStreamSource( 0, VtxRight, sizeof( PARAMETERS ) ); DXDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 ); DXDevice->SetStreamSource( 0, VtxTop, sizeof( PARAMETERS ) ); DXDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 ); return true; } int CDXDraw::ScaleX( int X ) { GetClientRect( hWnd, &windowSize); return ( windowSize.right - 5.0 ) / (float) SysWidth * X; } int CDXDraw::ScaleY( int Y ) { GetClientRect( hWnd, &windowSize); return ( windowSize.bottom - 5.0 ) / (float) SysHeight * Y; } void CDXDraw::ScaleRect( RECT &r ) { if( &r == NULL ) return; GetWindowRect( hWnd, &windowSize); r.left = ( ( windowSize.right ) / (float) SysWidth )* r.left; r.right = ( ( windowSize.right ) / (float) SysWidth ) * r.right; r.bottom = ( ( windowSize.bottom ) / (float) SysHeight ) * r.bottom; r.top = ( (windowSize.bottom ) / (float)SysHeight ) * r.top; } Interface for a Button Object class CButton : public CWindow_GUI { public: CButton(); virtual ~CButton(); virtual int RenderWindow( ); virtual void Init( ); // virtual void Init( ); //these refer to the face void SetImage( char *UpImage, char *DownImage = NULL ); void SetButtonText( char *UpText, char* DownText = NULL ); bool CreateSurface( ); void SetFont( char *FontType = NULL ); void SetPoint( int Point = 12 ); void SetColor( DWORD Color = 0 ); void SetMargins( short Vertical, short Horizontal ); void SetParams( bool Italic = false, bool Bold = false, bool Underline = false ); void SetAutoDraw( bool Auto = true, DWORD color = 0xffBCBCBC ); void SetCommandLeft( void *ComLMB ); // virtual void Test( int a ); //Messaging virtual void GM_MOUSEACTION( int MouseX, int MouseY, short Btn, short LastBtnState ); protected: SButtonInf sButtonInf; // void *CommandLB(); }; #endif CButton::CButton() { } CButton::~CButton() { } void CButton::Init( ) { //TODO: Put this in initialize sButtonInf.DrawUp = true; sButtonInf.sTxtInf.Italic = false; sButtonInf.sTxtInf.Bold = 0; sButtonInf.sTxtInf.Underline = false; sButtonInf.sTxtInf.Font = "Times New Roman"; sButtonInf.sTxtInf.Point = 10; sButtonInf.sTxtInf.Color = 0xff000000; sButtonInf.BorderWidth = 3; sButtonInf.AutoDraw = true; sButtonInf.color = 0xffBCBCBC; sButtonInf.UText = "Hello World"; sButtonInf.DText = "Hello World"; sButtonInf.DrawUp = true; sButtonInf.HMargin = 4; sButtonInf.VMargin = 4; SetPos( 0, 0 ); SetSize( 100, 100 ); } void CButton::SetFont( char *FontType ) { if( FontType != NULL ) sButtonInf.sTxtInf.Font = FontType; else sButtonInf.sTxtInf.Font = "Arial"; } void CButton::SetPoint( int Point ) { if( Point % 2 ) Point--; if( Point > 24 ) Point = 24; if( Point == 0 ) Point = 12; if( Point < 8 ) Point = 8; sButtonInf.sTxtInf.Point = Point; } void CButton::SetColor( DWORD Color ) { sButtonInf.sTxtInf.Color = Color; } void CButton::SetParams( bool Italic, bool Bold, bool Underline ) { if( Bold ) sButtonInf.sTxtInf.Bold = 700; else sButtonInf.sTxtInf.Bold = 0; sButtonInf.sTxtInf.Italic = Italic; sButtonInf.sTxtInf.Underline = Underline; } void CButton::SetImage( char *UpImage, char *DownImage ) { sButtonInf.UImage = UpImage; if( DownImage == NULL ) sButtonInf.DImage = sButtonInf.UImage; else sButtonInf.DImage = DownImage; } void CButton::SetButtonText( char *UpText, char* DownText ) { sButtonInf.UText = UpText; if ( DownText == NULL ) sButtonInf.DText = sButtonInf.UText; else sButtonInf.DText = DownText; } int CButton::RenderWindow( ) { DXControl->DrawButton( sCoord.pos, sButtonInf ); return 0; } void CButton::SetMargins( short Vertical, short Horizontal ) { sButtonInf.VMargin = Vertical; sButtonInf.HMargin = Horizontal; } void CButton::GM_MOUSEACTION( int MouseX, int MouseY, short Btn, short LastBtnState ) { bool inside = ClickInside( MouseX, MouseY ); bool up = sButtonInf.DrawUp; //State machine if( inside == true && up == true )//Button has been clicked on sButtonInf.DrawUp = false; if( inside == true && up == false )//Button has been activated { sButtonInf.DrawUp = true; GM_USERACTION_MOUSE( Btn ); // (void)CommandLB( ); } if( inside == false && up == false )//Button has been cancelled sButtonInf.DrawUp = true; } void CButton::SetAutoDraw( bool Auto, DWORD color ) { sButtonInf.AutoDraw = Auto; sButtonInf.color = color; } /* void CButton::Test( int a ) { if( sButtonInf.DrawUp == false ) sButtonInf.DrawUp = true; else sButtonInf.DrawUp = false; }*/ void CButton::SetCommandLeft( void *ComLMB ) { // CommandLB() = ComLMB(); } The likned list template, homemade I might say... template< class NTYPE > class ArrayPtrCtrl { public: ArrayPtrCtrl( ); ~ArrayPtrCtrl( ); //TODO: NEED DELETE ELEMENT NOT ITEM //ALSO NEED TO ADD INSERT IN LINKS //ALSO NEED TO REVIEW ALL ITERATION ROUTINES int Add( NTYPE value ); //add pointer to back int Delete( NTYPE value ); //delete a given pointer NTYPE GetData( int ind ) const; //Give index # and get data NTYPE GetDataBW( int index ) const; bool IsValid( int ind ); bool IsEmpty( ); int GetCount( ); void DeleteAll( ); private: APtrNode< NTYPE > * Search( NTYPE Data ); NTYPE GetDBW( int index, int dest, APtrNode< NTYPE > *ptr ) const; int size; APtrNode< NTYPE > *Start; //Pointer to start of list APtrNode< NTYPE > *End; //pointer to end APtrNode< NTYPE > *getNewNode( const NTYPE/*, APtrNode< NTYPE > last*/ ); NTYPE Value; int count; }; /////////////////////////////////////////////////////////////// /////////Implementaion /////////////////////////////////////////////////////////////// template< class NTYPE > ArrayPtrCtrl< NTYPE >::ArrayPtrCtrl( ) : Start( NULL ), End( NULL ) { count = 0; }; template< class NTYPE > ArrayPtrCtrl< NTYPE >::~ArrayPtrCtrl( ) { //List has stuff in it if( !IsEmpty( ) ) { APtrNode< NTYPE > *currentPtr = Start; APtrNode< NTYPE > *tempPtr; while ( currentPtr != NULL ) { tempPtr = currentPtr; //make addy of temp be that of the current ptr currentPtr = currentPtr->nextPtr;//change the current tempPtr->data = NULL; delete tempPtr; //delete the one that was previous tempPtr = NULL; } } } template< class NTYPE > ArrayPtrCtrl< NTYPE >::Add( NTYPE value ) { //FOUL!!!! // if ( value == NULL ) // return -1; APtrNode< NTYPE > *nPtr = getNewNode( value ); if( nPtr == NULL ) MessageBox( NULL, "nPtr Null", "AptrNode", MB_YESNO ); if( value == NULL ) MessageBox( NULL, "value Null", "AptrNode", MB_YESNO ); if ( IsEmpty( ) ) //List is empty { Start = nPtr; End = nPtr; nPtr->lastPtr = Start; } else { End->nextPtr = nPtr; //Assign the last ptr's new ptr nPtr->lastPtr = End; End = nPtr; //Assign last pointer to the new ptr }; count++; return 1; }; template< class NTYPE > //This adds another point to the node APtrNode< NTYPE > *ArrayPtrCtrl< NTYPE >::getNewNode ( NTYPE value/*, APtrNode< NTYPE > last*/ ) { APtrNode< NTYPE > *ptr = new APtrNode< NTYPE > ( value ); return ptr; }; //This will return the address of data template< class NTYPE > APtrNode< NTYPE > *ArrayPtrCtrl< NTYPE >::Search( NTYPE data ) { APtrNode< NTYPE > *currentPtr = Start; while ( currentPtr != NULL ) { //Check if the current node has the data being searched for if ( currentPtr->GetData( ) == data ) { //if so, return the node address return currentPtr; break; }; //This sets the current pointer address to the address specified in //currentpointer.NextPointer currentPtr = currentPtr -> nextPtr; }; return NULL; }; template< class NTYPE > int ArrayPtrCtrl< NTYPE >::Delete( NTYPE data ) { //Pointer to delete APtrNode< NTYPE > *delPtr = Search( data ); //See if the data is in the list if( delPtr == NULL ) return NULL; //Since it is, begin from 1st address APtrNode< NTYPE > *currentPtr = Start; if ( currentPtr == delPtr ) { Start = currentPtr->nextPtr; currentPtr->nextPtr = NULL; delete delPtr; return true; };//just in case it is the first pointer while( currentPtr->nextPtr != NULL )//until end of list { //if the next pointer address is equal to the address of //the & of the node to be deleted, then set the next pointer //to the one of the pointer to be deleted if ( currentPtr->nextPtr == delPtr ) { currentPtr->nextPtr = delPtr->nextPtr; delPtr->nextPtr = NULL; return true; }; currentPtr = currentPtr->nextPtr; //break; }; return NULL;//Somethings wrong }; template< class NTYPE > bool ArrayPtrCtrl< NTYPE >::IsValid( int index ) { int in; //index APtrNode< NTYPE > *currentPtr; // currentPtr = Start; if ( currentPtr == NULL ) return false; if( index == 0 ) return true; //since this is the first on the list and wont get tested //loop through chain up to index for( in = 0 ; in<index ; in++ ) { //jump to next node currentPtr = currentPtr->nextPtr; //take the current pointer, //and assign it to the next on the list. if ( currentPtr == NULL ) //if the pointer becomes invalid, then the return false;//error //link does not exist }//we have 1 return true;//since CurrentPtr does exist, return true }; template< class NTYPE > NTYPE ArrayPtrCtrl< NTYPE >::GetData( int index ) const { int in; APtrNode< NTYPE > *currentPtr; currentPtr = Start; //loop through chain for( in = 0 ; in<index ; in++ ) { //jump to next node currentPtr = currentPtr->nextPtr; //take the current pointer, //and assign it to the next on the list. if ( currentPtr == NULL ) return NULL;//error }//we have 1 if ( index == 0 ) { currentPtr = Start; //in case the current pointer //is start and not a next ptr //when point is reached, return the data return currentPtr->GetData( ); } else return currentPtr->GetData( ); }; template< class NTYPE > bool ArrayPtrCtrl< NTYPE >::IsEmpty( ) { if ( Start == NULL ) return true; else return false; }; template< class NTYPE > NTYPE ArrayPtrCtrl< NTYPE >::GetDBW( int index, int dest, APtrNode< NTYPE > *ptr ) const { if( index == dest ) return ptr->GetData( ); GetDBW( index, (dest-1), ptr->lastPtr ); } template< class NTYPE > NTYPE ArrayPtrCtrl< NTYPE >::GetDataBW( int index ) const { if( index > count ) return 0; if( index == count ) return End->GetData( ); if( index <= 0 ) return Start->GetData( ); GetDBW( index, count, End ); }; template< class NTYPE > int ArrayPtrCtrl< NTYPE >::GetCount( ) { return count; } template< class NTYPE > void ArrayPtrCtrl< NTYPE >::DeleteAll( ) { if( IsEmpty( ) == false ) { APtrNode< NTYPE > *currentPtr = Start; APtrNode< NTYPE > *tempPtr; while ( currentPtr != NULL ) { tempPtr = currentPtr; //make addy of temp be that of the current ptr currentPtr = currentPtr->nextPtr;//change the current tempPtr->data = NULL; Start = NULL; End = NULL; delete tempPtr; //delete the one that was previous //tempPtr = NULL; } } }