PS2GL
OpenGL*-like API for the PS2
Loading...
Searching...
No Matches
dlist.h
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#ifndef ps2gl_dlist_h
8#define ps2gl_dlist_h
9
10#include <string.h>
11
12#include "GL/gl.h"
13#include "ps2gl/debug.h"
14#include "ps2s/packet.h"
15
16/********************************************
17 * display list commands
18 */
19
20class CDListCmd {
21public:
22 CDListCmd() {}
23 virtual ~CDListCmd() {}
24
25 virtual CDListCmd* Play() = 0;
26
27 template <class CmdType>
28 static inline int SizeOf()
29 {
30 // SEE FUNCTION below if you change anything here..
31 int size = sizeof(CmdType);
32 // round up to nearest quad.. this is temporary so that I
33 // can use the vector classes for a while
34 if (size & 0xf)
35 size = (size & ~0xf) + 16;
36 return size;
37 }
38
39 template <class CmdType>
40 static CDListCmd* GetNextCmd(CmdType* cmd)
41 {
42 // for some reason gcc doesn't find the above method when called
43 // from here... go figure.
44 int size = sizeof(CmdType);
45 // round up to nearest quad.. this is temporary so that I
46 // can use the vector classes for a while
47 if (size & 0xf)
48 size = (size & ~0xf) + 16;
49
50 return reinterpret_cast<CDListCmd*>((unsigned int)cmd + size);
51 }
52};
53
54class CEmptyListCmd : public CDListCmd {
55public:
56 CDListCmd* Play()
57 {
58 mError("Trying to play an empty list!");
59 return NULL;
60 }
61
62 // round (size of this class) up to nearest quad.. this is temporary so that I
63 // can use the vector classes for a while
64 int filler[3];
65};
66
67class CEndListCmd : public CDListCmd {
68public:
69 CDListCmd* Play() { return NULL; }
70};
71
72class CDListCmdBlock;
73class CNextBlockCmd : public CDListCmd {
74 CDListCmdBlock* NextBlock;
75
76public:
78 : NextBlock(nextBlock)
79 {
80 }
81 CDListCmd* Play(); // defined after CDListCmdBlock
82};
83
84class CEnableCmd : public CDListCmd {
85 GLenum Property;
86
87public:
88 CEnableCmd(GLenum prop)
89 : Property(prop)
90 {
91 }
92 CDListCmd* Play()
93 {
94 glEnable(Property);
95 return CDListCmd::GetNextCmd(this);
96 }
97};
98
99/********************************************
100 * CDListCmdBlock
101 */
102
104 static const int ByteSize = 2048;
105 char Memory[ByteSize];
106 char* MemCursor;
107 int BytesLeft;
108 CDListCmdBlock* NextBlock;
109
110public:
112 : MemCursor(Memory)
113 , BytesLeft(ByteSize)
114 , NextBlock(NULL)
115 {
116 CEmptyListCmd empty;
117 memcpy(MemCursor, &empty, CDListCmd::SizeOf<CEmptyListCmd>());
118 }
120 {
121 if (NextBlock)
122 delete NextBlock;
123 }
124
125 template <class CmdType>
126 bool CanFit(CmdType cmd)
127 {
128 return (CDListCmd::SizeOf<CmdType>()
129 <= BytesLeft - CDListCmd::SizeOf<CNextBlockCmd>());
130 }
131
132 template <class CmdType>
133 void operator+=(CmdType cmd)
134 {
135 memcpy(MemCursor, &cmd, sizeof(CmdType)); // this should be the usual sizeof()
136 MemCursor += CDListCmd::SizeOf<CmdType>();
137 BytesLeft -= CDListCmd::SizeOf<CmdType>();
138 }
139
140 CDListCmd* GetFirstCmd() { return reinterpret_cast<CDListCmd*>(&Memory[0]); }
141
142 void SetNextBlock(CDListCmdBlock* next) { NextBlock = next; }
143 CDListCmdBlock* GetNextBlock() const { return NextBlock; }
144};
145
146inline CDListCmd*
147CNextBlockCmd::Play()
148{
149 return NextBlock->GetFirstCmd();
150}
151
152/********************************************
153 * CDList
154 */
155
156class CDList {
157 static const int kBufferMaxQwordLength = 16 * 1024; // 256kb
158 CDmaPacket *VertexBuf, *NormalBuf, *TexCoordBuf, *ColorBuf;
159 CDListCmdBlock *FirstCmdBlock, *CurCmdBlock;
160 static const int kMaxNumRenderPackets = 512;
161 int NumRenderPackets;
162 CVifSCDmaPacket* RenderPackets[kMaxNumRenderPackets];
163
164public:
165 CDList();
166 ~CDList();
167
168 // utility
169 template <class CmdType>
170 CDListCmd* GetNext(CmdType* cmd)
171 {
172 return 0;
173 }
174
175 template <class CmdType>
176 void operator+=(CmdType cmd)
177 {
178 if (!CurCmdBlock->CanFit(cmd)) {
179 // not enough space left in current cmd block, so terminate it
180 // and start a new one..
181 CDListCmdBlock* newBlock = new CDListCmdBlock;
182 CurCmdBlock->SetNextBlock(newBlock);
183 *CurCmdBlock += CNextBlockCmd(newBlock);
184 CurCmdBlock = newBlock;
185 }
186 *CurCmdBlock += cmd;
187 }
188
189 void Play()
190 {
191 CDListCmd* nextCmd = FirstCmdBlock->GetFirstCmd();
192 while (nextCmd)
193 nextCmd = nextCmd->Play();
194 }
195
196 void Begin();
197 void End()
198 {
199 CEndListCmd endList;
200 *this += endList;
201 }
202
203 CDmaPacket& GetVertexBuf();
204 CDmaPacket& GetNormalBuf();
205 CDmaPacket& GetTexCoordBuf();
206 CDmaPacket& GetColorBuf();
207
208 void RegisterNewPacket(CVifSCDmaPacket* packet)
209 {
210 RenderPackets[NumRenderPackets++] = packet;
211 }
212};
213
214/********************************************
215 * CDListManager
216 */
217
219 static const int kMaxListID = 4096;
220 int NextFreeListID;
221 CDList* Lists[kMaxListID];
222 unsigned int OpenListID;
223 CDList* OpenList;
224
225 bool ListsAreFree(int firstListID, int numLists);
226
227 static const int kMaxBuffersToBeFreed = 1024;
228 CDList* ListsToBeFreed[2][kMaxBuffersToBeFreed];
229 int NumListsToBeFreed[2];
230 int CurBuffer;
231
232 inline void AddListToBeFreed(CDList* dlist)
233 {
234 mAssert(NumListsToBeFreed[CurBuffer] < kMaxBuffersToBeFreed);
235 ListsToBeFreed[CurBuffer][NumListsToBeFreed[CurBuffer]++] = dlist;
236 }
237
238public:
240 : NextFreeListID(1)
241 , OpenListID(0)
242 , OpenList(NULL)
243 , CurBuffer(0)
244 {
245 for (int i = 0; i < kMaxListID; i++)
246 Lists[i] = NULL;
247 NumListsToBeFreed[0] = NumListsToBeFreed[1] = 0;
248 }
250 {
251 for (int i = 0; i < 10; i++)
252 if (Lists[i])
253 delete Lists[i];
254 }
255
256 void SwapBuffers();
257
258 unsigned int GenLists(int numLists);
259 void DeleteLists(unsigned int firstListID, int numLists);
260 void NewList(unsigned int listID, GLenum mode);
261 void EndList();
262 void CallList(unsigned int listID);
263
264 CDList& GetOpenDList() const { return *OpenList; }
265};
266
267#endif // ps2gl_dlist_h