00001
00002
00003 This file is subject to the terms and conditions of the GNU Lesser
00004 General Public License Version 2.1. See the file "COPYING" in the
00005 main directory of this archive for more details. */
00006
00007 #include "ps2gl/dlist.h"
00008 #include "ps2gl/glcontext.h"
00009 #include "ps2gl/immgmanager.h"
00010
00011
00012 * CDList
00013 */
00014
00015 CDList::CDList()
00016 : VertexBuf(NULL), NormalBuf(NULL), TexCoordBuf(NULL), ColorBuf(NULL),
00017 NumRenderPackets(0)
00018 {
00019 #ifndef PS2_LINUX
00020 FlushCache(0);
00021 #endif
00022 FirstCmdBlock = CurCmdBlock = new CDListCmdBlock;
00023 }
00024
00025 CDList::~CDList()
00026 {
00027 if ( VertexBuf ) delete VertexBuf;
00028 if ( NormalBuf ) delete NormalBuf;
00029 if ( TexCoordBuf ) delete TexCoordBuf;
00030 if ( ColorBuf ) delete ColorBuf;
00031
00032
00033 delete FirstCmdBlock;
00034 for ( int i = 0; i < NumRenderPackets; i++ )
00035 delete RenderPackets[i];
00036 }
00037
00038 void
00039 CDList::Begin()
00040 {
00041 }
00042
00043 CDmaPacket&
00044 CDList::GetVertexBuf()
00045 {
00046 if ( VertexBuf == NULL )
00047 VertexBuf = new CDmaPacket( kBufferMaxQwordLength, DMAC::Channels::vif1,
00048 Core::MemMappings::UncachedAccl );
00049 return *VertexBuf;
00050 }
00051
00052 CDmaPacket&
00053 CDList::GetNormalBuf()
00054 {
00055 if ( NormalBuf == NULL )
00056 NormalBuf = new CDmaPacket( kBufferMaxQwordLength, DMAC::Channels::vif1,
00057 Core::MemMappings::UncachedAccl );
00058 return *NormalBuf;
00059 }
00060
00061 CDmaPacket&
00062 CDList::GetTexCoordBuf()
00063 {
00064 if ( TexCoordBuf == NULL )
00065 TexCoordBuf = new CDmaPacket( kBufferMaxQwordLength, DMAC::Channels::vif1,
00066 Core::MemMappings::UncachedAccl );
00067 return *TexCoordBuf;
00068 }
00069
00070 CDmaPacket&
00071 CDList::GetColorBuf()
00072 {
00073 if ( ColorBuf == NULL )
00074 ColorBuf = new CDmaPacket( kBufferMaxQwordLength, DMAC::Channels::vif1,
00075 Core::MemMappings::UncachedAccl );
00076 return *ColorBuf;
00077 }
00078
00079
00080 * CDListManager
00081 */
00082
00083 void
00084 CDListManager::SwapBuffers()
00085 {
00086 CurBuffer = 1 - CurBuffer;
00087 for ( int i = 0; i < NumListsToBeFreed[CurBuffer]; i++ )
00088 delete ListsToBeFreed[CurBuffer][i];
00089 NumListsToBeFreed[CurBuffer] = 0;
00090 }
00091
00092 bool
00093 CDListManager::ListsAreFree( int firstListID, int numLists )
00094 {
00095 bool listsAreFree = true;
00096 for ( int i = 0; i < numLists; i++ )
00097 if ( Lists[firstListID + i] != NULL )
00098 listsAreFree = false;
00099 return listsAreFree;
00100 }
00101
00102 unsigned int
00103 CDListManager::GenLists( int numLists )
00104 {
00105
00106 int firstID = NextFreeListID;
00107
00108 mErrorIf( ! ListsAreFree(NextFreeListID, numLists),
00109 "Uh-oh.. time to write some real display list management code." );
00110
00111 NextFreeListID += numLists;
00112
00113
00114 if ( NextFreeListID == kMaxListID - 1 )
00115 NextFreeListID = 1;
00116
00117 mErrorIf( NextFreeListID >= kMaxListID, "Ran out of lists.. time to rewrite this code." );
00118
00119 return firstID;
00120 }
00121
00122 void
00123 CDListManager::DeleteLists( unsigned int firstListID, int numLists )
00124 {
00125 for ( int i = 0; i < numLists; i++ ) {
00126 if ( Lists[firstListID + i] ) {
00127
00128 AddListToBeFreed( Lists[firstListID + i] );
00129 Lists[firstListID + i] = NULL;
00130 }
00131 }
00132 }
00133
00134 void
00135 CDListManager::NewList( unsigned int listID, GLenum mode )
00136 {
00137 mWarnIf( mode == GL_COMPILE_AND_EXECUTE,
00138 "GL_COMPILE_AND_EXECUTE is not yet supported" );
00139
00140 OpenListID = listID;
00141 OpenList = new CDList;
00142 OpenList->Begin();
00143 }
00144
00145 void
00146 CDListManager::EndList()
00147 {
00148 mErrorIf( OpenListID == 0, "There is no list to end!" );
00149
00150 if ( Lists[OpenListID] ) AddListToBeFreed( Lists[OpenListID] );
00151 Lists[OpenListID] = OpenList;
00152 Lists[OpenListID]->End();
00153 OpenListID = 0;
00154 OpenList = NULL;
00155 }
00156
00157 class CCallListCmd : public CDListCmd {
00158 unsigned int ListID;
00159 public:
00160 CCallListCmd( unsigned listID ) : ListID(listID) {}
00161 CDListCmd* Play() {
00162 pGLContext->GetDListManager().CallList( ListID );
00163 return CDListCmd::GetNextCmd( this );
00164 }
00165 };
00166
00167 void
00168 CDListManager::CallList( unsigned int listID )
00169 {
00170 if ( OpenListID != 0 ) {
00171
00172 *OpenList += CCallListCmd( listID );
00173 }
00174 else {
00175 mErrorIf( Lists[listID] == NULL, "List does not exist." );
00176 pGLContext->GetImmGeomManager().Flush();
00177 Lists[listID]->Play();
00178 }
00179 }
00180
00181
00182
00183 * gl api
00184 */
00185
00186 GLuint glGenLists( GLsizei range )
00187 {
00188 return pGLContext->GetDListManager().GenLists( range );
00189 }
00190
00191 void glDeleteLists( GLuint list, GLsizei range )
00192 {
00193 pGLContext->GetDListManager().DeleteLists( list, range );
00194 }
00195
00196 void glNewList( GLuint listID, GLenum mode )
00197 {
00198 pGLContext->BeginDListDef( listID, mode );
00199 }
00200
00201 void glEndList( void )
00202 {
00203 pGLContext->EndDListDef();
00204 }
00205
00206 void glCallList( GLuint listID )
00207 {
00208 pGLContext->GetDListManager().CallList( listID );
00209 }