PS2GL
OpenGL*-like API for the PS2
Loading...
Searching...
No Matches
dlist.cpp
1/* Copyright (C) 2000,2001,2002 Sony Computer Entertainment America
2
3 This file is subject to the terms and conditions of the GNU Lesser
4 General Public License Version 2.1. See the file "COPYING" in the
5 main directory of this archive for more details. */
6
7#include "ps2gl/dlist.h"
8#include "ps2gl/glcontext.h"
9#include "ps2gl/immgmanager.h"
10
11#include "kernel.h"
12
13/********************************************
14 * CDList
15 */
16
17CDList::CDList()
18 : VertexBuf(NULL)
19 , NormalBuf(NULL)
20 , TexCoordBuf(NULL)
21 , ColorBuf(NULL)
22 , NumRenderPackets(0)
23{
24 FlushCache(0); // hopefully we're not allocating these buffers too often..
25 FirstCmdBlock = CurCmdBlock = new CDListCmdBlock;
26}
27
28CDList::~CDList()
29{
30 if (VertexBuf)
31 delete VertexBuf;
32 if (NormalBuf)
33 delete NormalBuf;
34 if (TexCoordBuf)
35 delete TexCoordBuf;
36 if (ColorBuf)
37 delete ColorBuf;
38
39 // this will get them all
40 delete FirstCmdBlock;
41 for (int i = 0; i < NumRenderPackets; i++)
42 delete RenderPackets[i];
43}
44
45void CDList::Begin()
46{
47}
48
49CDmaPacket&
50CDList::GetVertexBuf()
51{
52 if (VertexBuf == NULL)
53 VertexBuf = new CDmaPacket(kBufferMaxQwordLength, DMAC::Channels::vif1,
54 Core::MemMappings::UncachedAccl);
55 return *VertexBuf;
56}
57
58CDmaPacket&
59CDList::GetNormalBuf()
60{
61 if (NormalBuf == NULL)
62 NormalBuf = new CDmaPacket(kBufferMaxQwordLength, DMAC::Channels::vif1,
63 Core::MemMappings::UncachedAccl);
64 return *NormalBuf;
65}
66
67CDmaPacket&
68CDList::GetTexCoordBuf()
69{
70 if (TexCoordBuf == NULL)
71 TexCoordBuf = new CDmaPacket(kBufferMaxQwordLength, DMAC::Channels::vif1,
72 Core::MemMappings::UncachedAccl);
73 return *TexCoordBuf;
74}
75
76CDmaPacket&
77CDList::GetColorBuf()
78{
79 if (ColorBuf == NULL)
80 ColorBuf = new CDmaPacket(kBufferMaxQwordLength, DMAC::Channels::vif1,
81 Core::MemMappings::UncachedAccl);
82 return *ColorBuf;
83}
84
85/********************************************
86 * CDListManager
87 */
88
89void CDListManager::SwapBuffers()
90{
91 CurBuffer = 1 - CurBuffer;
92 for (int i = 0; i < NumListsToBeFreed[CurBuffer]; i++)
93 delete ListsToBeFreed[CurBuffer][i];
94 NumListsToBeFreed[CurBuffer] = 0;
95}
96
97bool CDListManager::ListsAreFree(int firstListID, int numLists)
98{
99 bool listsAreFree = true;
100 for (int i = 0; i < numLists; i++)
101 if (Lists[firstListID + i] != NULL)
102 listsAreFree = false;
103 return listsAreFree;
104}
105
106unsigned int
107CDListManager::GenLists(int numLists)
108{
109 // very temporary..
110 int firstID = NextFreeListID;
111
112 mErrorIf(!ListsAreFree(NextFreeListID, numLists),
113 "Uh-oh.. time to write some real display list management code.");
114
115 NextFreeListID += numLists;
116
117 // wrap around and hope for the best.. (relying on ListsAreFree to do error checking)
118 if (NextFreeListID == kMaxListID - 1)
119 NextFreeListID = 1;
120
121 mErrorIf(NextFreeListID >= kMaxListID, "Ran out of lists.. time to rewrite this code.");
122
123 return firstID;
124}
125
126void CDListManager::DeleteLists(unsigned int firstListID, int numLists)
127{
128 for (int i = 0; i < numLists; i++) {
129 if (Lists[firstListID + i]) {
130 // don't delete the dlist immediately -- it might not have been dma'ed yet..
131 AddListToBeFreed(Lists[firstListID + i]);
132 Lists[firstListID + i] = NULL;
133 }
134 }
135}
136
137void CDListManager::NewList(unsigned int listID, GLenum mode)
138{
139 mWarnIf(mode == GL_COMPILE_AND_EXECUTE,
140 "GL_COMPILE_AND_EXECUTE is not yet supported");
141
142 OpenListID = listID;
143 OpenList = new CDList;
144 OpenList->Begin();
145}
146
147void CDListManager::EndList()
148{
149 mErrorIf(OpenListID == 0, "There is no list to end!");
150
151 if (Lists[OpenListID])
152 AddListToBeFreed(Lists[OpenListID]);
153 Lists[OpenListID] = OpenList;
154 Lists[OpenListID]->End();
155 OpenListID = 0;
156 OpenList = NULL;
157}
158
159class CCallListCmd : public CDListCmd {
160 unsigned int ListID;
161
162public:
163 CCallListCmd(unsigned listID)
164 : ListID(listID)
165 {
166 }
167 CDListCmd* Play()
168 {
169 pGLContext->GetDListManager().CallList(ListID);
170 return CDListCmd::GetNextCmd(this);
171 }
172};
173
174void CDListManager::CallList(unsigned int listID)
175{
176 if (OpenListID != 0) {
177 // we're inside a list definition, so add the call to listID to the open list
178 *OpenList += CCallListCmd(listID);
179 } else {
180 mErrorIf(Lists[listID] == NULL, "List does not exist.");
181 pGLContext->GetImmGeomManager().Flush();
182 Lists[listID]->Play();
183 }
184}
185
186/********************************************
187 * gl api
188 */
189
190GLuint glGenLists(GLsizei range)
191{
192 GL_FUNC_DEBUG("%s(%d)\n", __FUNCTION__, range);
193
194 return pGLContext->GetDListManager().GenLists(range);
195}
196
197void glDeleteLists(GLuint list, GLsizei range)
198{
199 GL_FUNC_DEBUG("%s(%d,%d)\n", __FUNCTION__, list, range);
200
201 pGLContext->GetDListManager().DeleteLists(list, range);
202}
203
204void glNewList(GLuint listID, GLenum mode)
205{
206 GL_FUNC_DEBUG("%s(%d,%d)\n", __FUNCTION__, listID, mode);
207
208 pGLContext->BeginDListDef(listID, mode);
209}
210
211void glEndList(void)
212{
213 GL_FUNC_DEBUG("%s()\n", __FUNCTION__);
214
215 pGLContext->EndDListDef();
216}
217
218void glCallList(GLuint listID)
219{
220 GL_FUNC_DEBUG("%s(%d)\n", __FUNCTION__, listID);
221
222 pGLContext->GetDListManager().CallList(listID);
223}