1program lesson7;
2
3{$J+}
4{$macro on}
5{$mode objfpc}
6
7uses
8  cmem, ctypes, gctypes, gccore;
9
10{$include inc/crate.tpl.inc}
11{$link build/crate.tpl.o}
12
13const crate = 0;
14
15const
16  DEFAULT_FIFO_SIZE = (256 * 1024);
17
18type
19  tagtexdef  = record
20    pal_data: pointer;
21    tex_data: pointer;
22    sz_x: cuint32;
23    sz_y: cuint32;
24    fmt: cuint32;
25    min_lod: cuint32;
26    max_lod: cuint32;
27    min: cuint32;
28    mag: cuint32;
29    wrap_s: cuint32;
30    wrap_t: cuint32;
31    nextdef: pointer;
32  end;
33  texdef = tagtexdef;
34  ptexdef = ^texdef;
35
36var
37  frameBuffer: array [0..1] of pcuint32 = (nil, nil);
38  rmode: PGXRModeObj = nil;
39//static texdef *txdef = (texdef*)crate0_texture;
40
41	yscale: f32 = 0;
42  zt: f32 = 0;
43	xfbHeight: cuint32;
44	fb: cuint32 = 0;
45	rquad: f32 = 0.0;
46	first_frame: cuint32 = 1;
47	texture: GXTexObj;
48	view: Mtx; // view and perspective matrices
49	model, modelview: Mtx;
50	perspective: Mtx44;
51	gpfifo: pointer = nil;
52	background: GXColor = (r:0; g:0; b:0; a:$ff;);
53	cam: guVector = (x:0.0; y:0.0; z:0.0;);
54	up: guVector = (x:0.0; y:1.0; z:0.0;);
55	look: guVector = (x:0.0; y:0.0; z:-1.0;);
56  cubeAxis: guVector  = (x: 1.0; y: 1.0; z: 1.0;);
57
58	crateTPL: TPLFile;
59
60  w, h: f32;
61
62begin
63
64	VIDEO_Init();
65	WPAD_Init();
66
67	rmode := VIDEO_GetPreferredMode(nil);
68
69	// allocate 2 framebuffers for double buffering
70	frameBuffer[0] := SYS_AllocateFramebuffer(rmode);
71	frameBuffer[1] := SYS_AllocateFramebuffer(rmode);
72
73	// configure video
74	VIDEO_Configure(rmode);
75	VIDEO_SetNextFramebuffer(frameBuffer[fb]);
76	VIDEO_Flush();
77	VIDEO_WaitVSync();
78	if(rmode^.viTVMode and VI_NON_INTERLACE) <> 0 then
79    VIDEO_WaitVSync();
80
81	// allocate the fifo buffer
82	gpfifo := memalign(32,DEFAULT_FIFO_SIZE);
83	memset(gpfifo,0,DEFAULT_FIFO_SIZE);
84
85	fb := fb xor 1;
86
87	// init the flipper
88	GX_Init(gpfifo,DEFAULT_FIFO_SIZE);
89
90	// clears the bg to color and clears the z buffer
91	GX_SetCopyClear(background, $00ffffff);
92
93	// other gx setup
94	GX_SetViewport(0,0,rmode^.fbWidth,rmode^.efbHeight,0,1);
95	yscale := GX_GetYScaleFactor(rmode^.efbHeight,rmode^.xfbHeight);
96	xfbHeight := GX_SetDispCopyYScale(yscale);
97	GX_SetScissor(0,0,rmode^.fbWidth,rmode^.efbHeight);
98	GX_SetDispCopySrc(0,0,rmode^.fbWidth,rmode^.efbHeight);
99	GX_SetDispCopyDst(rmode^.fbWidth,xfbHeight);
100	GX_SetCopyFilter(rmode^.aa,rmode^.sample_pattern,GX_TRUE,rmode^.vfilter);
101
102  if rmode^.viHeight = 2 * rmode^.xfbHeight then
103    GX_SetFieldMode(rmode^.field_rendering, GX_ENABLE)
104  else
105    GX_SetFieldMode(rmode^.field_rendering, GX_DISABLE);
106
107	if (rmode^.aa) <> 0 then
108        GX_SetPixelFmt(GX_PF_RGB565_Z16, GX_ZC_LINEAR)
109  else
110        GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
111
112	GX_SetCullMode(GX_CULL_NONE);
113	GX_CopyDisp(frameBuffer[fb],GX_TRUE);
114	GX_SetDispCopyGamma(GX_GM_1_0);
115
116	// setup the vertex attribute table
117	// describes the data
118	// args: vat location 0-7, type of data, data format, size, scale
119	// so for ex. in the first call we are sending position data with
120	// 3 values X,Y,Z of size F32. scale sets the number of fractional
121	// bits for non float data.
122	GX_ClearVtxDesc();
123	GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
124	GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT);
125	GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
126
127	GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
128	GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
129	GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGB8, 0);
130
131    GX_InvVtxCache();
132	GX_InvalidateTexAll();
133	TPL_OpenTPLFromMemory(@crateTPL, @crate_tpl[0], crate_tpl_size);
134	TPL_GetTexture(@crateTPL,crate,@texture);
135
136	// setup our camera at the origin
137	// looking down the -z axis with y up
138	guLookAt(view, @cam, @up, @look);
139
140	// setup our projection matrix
141	// this creates a perspective matrix with a view angle of 90,
142	// and aspect ratio based on the display resolution
143  w := rmode^.viWidth;
144  h := rmode^.viHeight;
145	guPerspective(perspective, 45, f32(w/h), 0.1, 300.0);
146	GX_LoadProjectionMtx(perspective, GX_PERSPECTIVE);
147
148
149	while true do
150	begin
151
152		WPAD_ScanPads();
153		if (WPAD_ButtonsDown(0) and WPAD_BUTTON_HOME) <> 0 then exit
154		else
155    if (WPAD_ButtonsHeld(0) and WPAD_BUTTON_UP) <> 0 then zt := zt - 0.25
156		else
157    if (WPAD_ButtonsHeld(0) and WPAD_BUTTON_DOWN) <> 0 then zt := zt + 0.25;
158
159		// set number of rasterized color channels
160		GX_SetNumChans(1);
161
162		//set number of textures to generate
163		GX_SetNumTexGens(1);
164
165		// setup texture coordinate generation
166		// args: texcoord slot 0-7, matrix type, source to generate texture coordinates from, matrix to use
167		GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
168
169		GX_SetTevOp(GX_TEVSTAGE0,GX_REPLACE);
170		GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
171
172		GX_LoadTexObj(@texture, GX_TEXMAP0);
173
174		guMtxIdentity(model);
175		guMtxRotAxisDeg(model, @cubeAxis, rquad);
176		guMtxTransApply(model, model, 0.0,0.0,zt-7.0);
177		guMtxConcat(view,model,modelview);
178		// load the modelview matrix into matrix memory
179		GX_LoadPosMtxImm(modelview, GX_PNMTX3);
180		GX_SetCurrentMtx(GX_PNMTX3);
181
182		GX_Begin(GX_QUADS, GX_VTXFMT0, 24);			// Draw a Cube
183
184			GX_Position3f32(-1.0, 1.0, -1.0);	// Top Left of the quad (top)
185			GX_Color3f32(0.0,1.0,0.0);			// Set The Color To Green
186			GX_TexCoord2f32(0.0,0.0);
187			GX_Position3f32(-1.0, 1.0, 1.0);	// Top Right of the quad (top)
188			GX_Color3f32(0.0,1.0,0.0);			// Set The Color To Green
189			GX_TexCoord2f32(1.0,0.0);
190			GX_Position3f32(-1.0, -1.0, 1.0);	// Bottom Right of the quad (top)
191			GX_Color3f32(0.0,1.0,0.0);			// Set The Color To Green
192			GX_TexCoord2f32(1.0,1.0);
193			GX_Position3f32(- 1.0, -1.0, -1.0);		// Bottom Left of the quad (top)
194			GX_Color3f32(0.0,1.0,0.0);			// Set The Color To Green
195			GX_TexCoord2f32(0.0,1.0);
196
197			GX_Position3f32( 1.0,1.0, -1.0);	// Top Left of the quad (bottom)
198			GX_Color3f32(1.0,0.5,0.0);			// Set The Color To Orange
199			GX_TexCoord2f32(0.0,0.0);
200			GX_Position3f32(1.0,-1.0, -1.0);	// Top Right of the quad (bottom)
201			GX_Color3f32(1.0,0.5,0.0);			// Set The Color To Orange
202			GX_TexCoord2f32(1.0,0.0);
203			GX_Position3f32(1.0,-1.0,1.0);	// Bottom Right of the quad (bottom)
204			GX_Color3f32(1.0,0.5,0.0);			// Set The Color To Orange
205			GX_TexCoord2f32(1.0,1.0);
206			GX_Position3f32( 1.0,1.0,1.0);	// Bottom Left of the quad (bottom)
207			GX_Color3f32(1.0,0.5,0.0);			// Set The Color To Orange
208			GX_TexCoord2f32(0.0,1.0);
209
210			GX_Position3f32( -1.0, -1.0, 1.0);		// Top Right Of The Quad (Front)
211			GX_Color3f32(1.0,0.0,0.0);			// Set The Color To Red
212			GX_TexCoord2f32(0.0,0.0);
213			GX_Position3f32(1.0, -1.0, 1.0);	// Top Left Of The Quad (Front)
214			GX_Color3f32(1.0,0.0,0.0);			// Set The Color To Red
215			GX_TexCoord2f32(1.0,0.0);
216			GX_Position3f32(1.0,-1.0, -1.0);	// Bottom Left Of The Quad (Front)
217			GX_Color3f32(1.0,0.0,0.0);			// Set The Color To Red
218			GX_TexCoord2f32(1.0,1.0);
219			GX_Position3f32( -1.0,-1.0, -1.0);	// Bottom Right Of The Quad (Front)
220			GX_Color3f32(1.0,0.0,0.0);			// Set The Color To Red
221			GX_TexCoord2f32(0.0,1.0);
222
223			GX_Position3f32( -1.0,1.0,1.0);	// Bottom Left Of The Quad (Back)
224			GX_Color3f32(1.0,1.0,0.0);			// Set The Color To Yellow
225			GX_TexCoord2f32(0.0,0.0);
226			GX_Position3f32(-1.0,1.0,-1.0);	// Bottom Right Of The Quad (Back)
227			GX_Color3f32(1.0,1.0,0.0);			// Set The Color To Yellow
228			GX_TexCoord2f32(1.0,0.0);
229			GX_Position3f32(1.0, 1.0,-1.0);	// Top Right Of The Quad (Back)
230			GX_Color3f32(1.0,1.0,0.0);			// Set The Color To Yellow
231			GX_TexCoord2f32(1.0,1.0);
232			GX_Position3f32( 1.0, 1.0,1.0);	// Top Left Of The Quad (Back)
233			GX_Color3f32(1.0,1.0,0.0);			// Set The Color To Yellow
234			GX_TexCoord2f32(0.0,1.0);
235
236			GX_Position3f32(1.0, -1.0, -1.0);	// Top Right Of The Quad (Left)
237			GX_Color3f32(0.0,0.0,1.0);			// Set The Color To Blue
238			GX_TexCoord2f32(0.0,0.0);
239			GX_Position3f32(1.0, 1.0,-1.0);	// Top Left Of The Quad (Left)
240			GX_Color3f32(0.0,0.0,1.0);			// Set The Color To Blue
241			GX_TexCoord2f32(1.0,0.0);
242			GX_Position3f32(-1.0,1.0,-1.0);	// Bottom Left Of The Quad (Left)
243			GX_Color3f32(0.0,0.0,1.0);			// Set The Color To Blue
244			GX_TexCoord2f32(1.0,1.0);
245			GX_Position3f32(-1.0,-1.0, -1.0);	// Bottom Right Of The Quad (Left)
246			GX_Color3f32(0.0,0.0,1.0);			// Set The Color To Blue
247			GX_TexCoord2f32(0.0,1.0);
248
249			GX_Position3f32( 1.0, -1.0,1.0);	// Top Right Of The Quad (Right)
250			GX_Color3f32(1.0,0.0,1.0);			// Set The Color To Violet
251			GX_TexCoord2f32(0.0,0.0);
252			GX_Position3f32( -1.0, -1.0, 1.0);		// Top Left Of The Quad (Right)
253			GX_Color3f32(1.0,0.0,1.0);			// Set The Color To Violet
254			GX_TexCoord2f32(1.0,0.0);
255			GX_Position3f32( -1.0,1.0, 1.0);	// Bottom Left Of The Quad (Right)
256			GX_Color3f32(1.0,0.0,1.0);			// Set The Color To Violet
257			GX_TexCoord2f32(1.0,1.0);
258			GX_Position3f32( 1.0,1.0,1.0);	// Bottom Right Of The Quad (Right)
259			GX_Color3f32(1.0,0.0,1.0);			// Set The Color To Violet
260			GX_TexCoord2f32(0.0,1.0);
261
262		GX_End();									// Done Drawing The Quad
263
264		GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
265		GX_SetColorUpdate(GX_TRUE);
266		GX_CopyDisp(frameBuffer[fb],GX_TRUE);
267
268		GX_DrawDone();
269
270		VIDEO_SetNextFramebuffer(frameBuffer[fb]);
271		if(first_frame) <> 0 then
272		begin
273			first_frame := 0;
274			VIDEO_SetBlack(FALSE);
275		end;
276		VIDEO_Flush();
277 		VIDEO_WaitVSync();
278		fb := fb xor 1;
279
280		rquad := rquad - 0.15;				// Decrease The Rotation Variable For The Quad     ( NEW )
281	end;
282end.
283