home *** CD-ROM | disk | FTP | other *** search
/ NEXT Generation 27 / NEXT27.iso / pc / demos / emperor / dx3.exe / SDK / SAMPLES / IKLOWNS / CGDLIST.CPP < prev    next >
C/C++ Source or Header  |  1996-08-28  |  10KB  |  347 lines

  1. /*===========================================================================*\
  2. |
  3. |  File:        cgdlist.cpp
  4. |
  5. |  Description: 
  6. |       
  7. |-----------------------------------------------------------------------------
  8. |
  9. |  Copyright (C) 1995-1996 Microsoft Corporation.  All Rights Reserved.
  10. |
  11. |  Written by Moss Bay Engineering, Inc. under contract to Microsoft Corporation
  12. |
  13. \*===========================================================================*/
  14.  
  15. /**************************************************************************
  16.  
  17.     (C) Copyright 1995-1996 Microsoft Corp.  All rights reserved.
  18.  
  19.     You have a royalty-free right to use, modify, reproduce and 
  20.     distribute the Sample Files (and/or any modified version) in 
  21.     any way you find useful, provided that you agree that 
  22.     Microsoft has no warranty obligations or liability for any 
  23.     Sample Application Files which are modified. 
  24.  
  25.     we do not recomend you base your game on IKlowns, start with one of
  26.     the other simpler sample apps in the GDK
  27.  
  28.  **************************************************************************/
  29.  
  30. #include <windows.h>
  31. #include "cgrsrce.h"
  32. #include "cgexcpt.h"
  33. #include "strrec.h"
  34. #include "cgdebug.h"
  35. #include "cgchar.h"
  36. #include "cgimage.h"
  37. #include "cgload.h"
  38. #include "cgdlist.h"
  39.  
  40. #define CGG_CHARACTER 0
  41. #define CGG_TILEDIMAGE 1
  42. #define CGG_SKYIMAGE 2
  43. char* graphicTypes[] = 
  44. {
  45.     "Character",    // type 0
  46.     "TiledImage",   // type 1
  47.     "Sky",      // type 2
  48.     NULL
  49. };
  50.  
  51. /*---------------------------------------------------------------------------*\
  52. |
  53. |       Class CGameDisplayList
  54. |
  55. |  DESCRIPTION:
  56. |       
  57. |
  58. |
  59. \*---------------------------------------------------------------------------*/
  60. extern void dbgprintf(char *, ...);
  61. extern CLoadingScreen *gLoadingScreen;
  62.  
  63. CGameDisplayList::CGameDisplayList(
  64.     char* pFileName,
  65.     char* pLevelName,
  66.     CGameLevel* pLevel
  67.     ) : mpHead( NULL )
  68. {
  69.     char nameBuf[256];
  70.     char dataBuf[256];
  71.  
  72.     // load the graphic objects
  73.     GetPrivateProfileString(
  74.         pLevelName,
  75.         NULL,
  76.         "",     // no default
  77.         nameBuf,
  78.         sizeof( nameBuf ),
  79.         pFileName
  80.         );
  81.  
  82.  
  83.     for (char *pChar = nameBuf; *pChar; pChar++)
  84.     {
  85.         CGameGraphic* pGraphic;
  86.  
  87.         if (gLoadingScreen != NULL)
  88.             gLoadingScreen->Update();
  89.  
  90.         GetPrivateProfileString(
  91.             pLevelName,
  92.             pChar,
  93.             "",
  94.             dataBuf,
  95.             sizeof( dataBuf ),
  96.             pFileName
  97.             );
  98.  
  99.         // parse the data string into fields
  100.         CStringRecord fields( dataBuf, "," );
  101.  
  102.         for (int i=0; graphicTypes[i]; i++)
  103.         {
  104.             if (lstrcmpi(fields[0], graphicTypes[i]) == 0)
  105.             {
  106.                 break;  // we found it
  107.             }
  108.         }
  109.  
  110.         switch (i)
  111.         {
  112.             case CGG_CHARACTER:
  113.             
  114.                 if (atoi(fields[6]) == 1)
  115.                 {
  116.                     char *pRemoteName=NULL;
  117.                     if (fields.GetNumFields() > 7)
  118.                         pRemoteName = fields[7];
  119.  
  120.                     pGraphic = new CGameCharacter(
  121.                                     pFileName, 
  122.                                     pChar,
  123.                                     pLevelName,
  124.                                     pLevel, 
  125.                                     atoi(fields[1]), 
  126.                                     atoi(fields[2]),
  127.                                     atoi(fields[3]),
  128.                                     atoi(fields[4]),
  129.                                     NULL,
  130.                                     pRemoteName);
  131.                                         if (lstrcmpi(pChar, "Klown") == 0)
  132.                     {
  133.                     pLevel->mMainKlown = (CGameCharacter *) pGraphic;
  134.                     }
  135.  
  136.                 }
  137.                 else {
  138.                     pChar += lstrlen( pChar );  // move beyond terminator
  139.                     continue;
  140.                 }
  141.  
  142.                 break;
  143.  
  144.             case CGG_TILEDIMAGE:
  145.             {
  146.                 pGraphic = new CGameTiledImage(pChar, atoi(fields[1]), atoi(fields[2]), atoi(fields[3]));
  147.                 break;
  148.             }
  149.  
  150.  
  151.             case CGG_SKYIMAGE:
  152.                 pGraphic = new CGameSkyImage(pChar);
  153.                 break;
  154.  
  155.             default:
  156.                 pGraphic = NULL;
  157.                 break;
  158.         }
  159.  
  160.         if (pGraphic)
  161.         {
  162.             Insert( pGraphic );
  163.         }
  164.  
  165.         pChar += lstrlen( pChar );  // move beyond terminator
  166.  
  167. #if 1
  168.         // NOTE: if we don't grab messages, we see a white flash while we're
  169.         //      loading (!?!?).  We can't allow switching away until we've
  170.         //      finished loading, however, because we'll lose the surfaces
  171.         //      we've already created, so we just drop the messages on the floor.
  172.         MSG     msg;
  173.         if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE | PM_NOYIELD ) ) {
  174.         }
  175. #endif
  176.     }
  177. }   
  178.  
  179. CGameDisplayList::~CGameDisplayList()
  180. {
  181.     CGameGraphic* pNext = NULL;
  182.  
  183.     for (CGameGraphic* pGraphic = mpHead;
  184.         pGraphic;
  185.         pGraphic = pNext
  186.         )
  187.     {
  188.         pNext = pGraphic->GetNext();
  189.         delete pGraphic;
  190.         pGraphic = NULL;
  191.     }
  192. }
  193.  
  194. void
  195. CGameDisplayList::Update(CGameLevel* pLevel, CGameUpdateList* pUpdate)
  196. {
  197.     if (mpHead)
  198.     {
  199.         mpHead->Update(pLevel, pUpdate);
  200.         // see if we've collided...
  201.         int testZ;
  202.         CGameCharacter *pCur, *pNext;
  203.         pCur = (CGameCharacter *) mpHead;
  204.         pNext = (CGameCharacter *) mpHead->GetNext();
  205.  
  206.         while (pCur && pNext)
  207.         {
  208.             RECT temprect;
  209.             LPRECT pMyRect = pCur->GetRect();
  210.             testZ = pCur->GetCurrentZ();
  211.  
  212.             // look at  all chars in the Z order for conflicts...
  213.  
  214.             while (pNext && (testZ == pNext->GetCurrentZ()))
  215.             {
  216.                 if (IntersectRect(&temprect, pMyRect, pNext->GetRect()))
  217.                 {
  218.                     int removeme = pCur->Collided(pNext);
  219.                     int removeother = pNext->Collided(pCur);
  220.                 }
  221.  
  222.                 pNext = (CGameCharacter *) pNext->GetNext();
  223.             }
  224.  
  225.             pCur = (CGameCharacter *) pCur->GetNext();
  226.             pNext = (CGameCharacter *) pCur->GetNext();
  227.         }
  228.     }
  229. }
  230.  
  231. void
  232. CGameDisplayList::Render(CGameLevel* pLevel, CGameScreen* pScreen, CGameUpdateList* pUpdate)
  233. {
  234.     if (mpHead)
  235.         mpHead->Render(pLevel, pScreen, pUpdate);
  236. }
  237.  
  238. void
  239. CGameDisplayList::Insert( CGameGraphic* pGraphic )
  240. {
  241.     if (mpHead)
  242.     {
  243.         CGameGraphic* pNode = mpHead;
  244.         int lookZ = pGraphic->GetMinZ();
  245.  
  246.         if (lookZ < pNode->GetMinZ())
  247.         {
  248.             pGraphic->SetNext(pNode);
  249.             mpHead = pGraphic;          
  250.         }
  251.         else
  252.         {
  253.             while (pNode->GetNext() && (pNode->GetNext()->GetMinZ() < lookZ))
  254.             {
  255.                 pNode = pNode->GetNext();
  256.             }
  257.  
  258.             pNode->Add( pGraphic );     // put this graphic after (or in) this node
  259.         }
  260.     }
  261.     else
  262.     {
  263.         mpHead = pGraphic;
  264.     }
  265. }
  266.  
  267. void
  268. CGameDisplayList::Remove( CGameGraphic* pGraphic )
  269. {
  270.     
  271.     CGameGraphic* pNode = mpHead;
  272.     CGameGraphic* pNextNode;
  273.  
  274.     while (pNode)
  275.     {
  276.         pNextNode = pNode->GetNext();
  277.         if (pNode == pGraphic)
  278.         {
  279.             // must be head of list;
  280.             mpHead = pNextNode;
  281.             break;
  282.         }
  283.         else
  284.         {
  285.             if (pNextNode == pGraphic)
  286.             {
  287.                 // normal case; 
  288.                 pNode->SetNext( pNextNode->GetNext());
  289.                 break;
  290.             }
  291.         }
  292.         pNode = pNextNode;
  293.     }
  294.     delete pGraphic;
  295. }
  296.  
  297. void CGameDisplayList::ReSort()
  298. {
  299.     // traverse the list; resort based on Z order.  
  300.     // Naively assume only one mismatch for now.
  301.     CGameGraphic* pNode = mpHead;
  302.     CGameGraphic* pLastNode = mpHead;
  303.     CGameGraphic* pNextNode;
  304.  
  305.     // find bad node (if any!)
  306.     while (pNode)
  307.     {
  308.         pNextNode = pNode->GetNext();
  309.         if (pNextNode)
  310.         {
  311.             if (pNode->GetCurrentZ() > pNextNode->GetCurrentZ())
  312.             {
  313.                 // found a "bad" one!.  Remove from list
  314.                 if (pLastNode == pNode) // head of list
  315.                 {
  316.                     mpHead = pNextNode;
  317.                 }
  318.                 else
  319.                 {
  320.                     pLastNode->SetNext(pNextNode);
  321.                 }
  322.                 // this node *must* go somewhere *after* pNextNode, so start searching from there
  323.                 pLastNode = pNextNode;
  324.                 while (pNextNode)
  325.                 {
  326.                     if (pNode->GetCurrentZ() <= pNextNode->GetCurrentZ())
  327.                     {
  328.                         // insert here...
  329.                         pLastNode->SetNext(pNode);
  330.                         pNode->SetNext(pNextNode);
  331.                         return;
  332.                     }
  333.                     pLastNode = pNextNode;
  334.                     pNextNode = pNextNode->GetNext();
  335.                 }
  336.  
  337.                 // if here, pNextNode must be NULL....
  338.                 pLastNode->SetNext(pNode);
  339.                 pNode->SetNext(NULL);
  340.                 return;
  341.             }
  342.         }
  343.         pLastNode = pNode;
  344.         pNode = pNextNode;
  345.     }
  346. }
  347.