1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
program lesson1;
{$J+}
{$macro on}
{$mode objfpc}
uses
cmem, ctypes, gctypes, gccore;
const
DEFAULT_FIFO_SIZE = (256*1024);
var
frameBuffer: array [0..1] of pcuint32 = (nil, nil);
rmode: PGXRModeObj = nil;
yscale: f32;
xfbHeight: cuint32;
view: Mtx;
perspective: Mtx44;
fb: cuint32 = 0;
background: GXColor = (r:0; g:0; b:0; a:$ff;);
gp_fifo: pointer = nil;
cam: guVector = (x:0.0; y:0.0; z:0.0;);
up: guVector = (x:0.0; y:1.0; z:0.0;);
look: guVector = (x:0.0; y:0.0; z:-1.0;);
w,h: f32;
begin
VIDEO_Init();
WPAD_Init();
rmode := VIDEO_GetPreferredMode(nil);
// allocate 2 framebuffers for double buffering
frameBuffer[0] := MEM_K0_TO_K1(integer(SYS_AllocateFramebuffer(rmode)));
frameBuffer[1] := MEM_K0_TO_K1(integer(SYS_AllocateFramebuffer(rmode)));
VIDEO_Configure(rmode);
VIDEO_SetNextFramebuffer(frameBuffer[fb]);
VIDEO_SetBlack(false);
VIDEO_Flush();
VIDEO_WaitVSync();
if (rmode^.viTVMode and VI_NON_INTERLACE) <> 0 then
VIDEO_WaitVSync();
// setup the fifo and then init the flipper
gp_fifo := memalign(32, DEFAULT_FIFO_SIZE);
memset(gp_fifo, 0, DEFAULT_FIFO_SIZE);
GX_Init(gp_fifo, DEFAULT_FIFO_SIZE);
// clears the bg to color and clears the z buffer
GX_SetCopyClear(background, $00ffffff);
// other gx setup
GX_SetViewport(0,0,rmode^.fbWidth,rmode^.efbHeight,0,1);
yscale := GX_GetYScaleFactor(rmode^.efbHeight,rmode^.xfbHeight);
xfbHeight := GX_SetDispCopyYScale(yscale);
GX_SetScissor(0,0,rmode^.fbWidth,rmode^.efbHeight);
GX_SetDispCopySrc(0,0,rmode^.fbWidth,rmode^.efbHeight);
GX_SetDispCopyDst(rmode^.fbWidth,xfbHeight);
GX_SetCopyFilter(rmode^.aa,rmode^.sample_pattern,GX_TRUE,rmode^.vfilter);
if rmode^.viHeight = 2*rmode^.xfbHeight then
GX_SetFieldMode(rmode^.field_rendering,GX_ENABLE)
else
GX_SetFieldMode(rmode^.field_rendering,GX_DISABLE);
GX_SetCullMode(GX_CULL_NONE);
GX_CopyDisp(frameBuffer[fb],GX_TRUE);
GX_SetDispCopyGamma(GX_GM_1_0);
// setup our camera at the origin
// looking down the -z axis with y up
guLookAt(view, @cam, @up, @look);
// setup our projection matrix
// this creates a perspective matrix with a view angle of 90,
// and aspect ratio based on the display resolution
w := rmode^.viWidth;
h := rmode^.viHeight;
guPerspective(perspective, 45, f32(w / h), 0.1, 300.0);
GX_LoadProjectionMtx(perspective, GX_PERSPECTIVE);
while true do
begin
WPAD_ScanPads();
if (WPAD_ButtonsDown(0) and WPAD_BUTTON_HOME) <> 0 then
exit;
// do this before drawing
GX_SetViewport(0,0,rmode^.fbWidth,rmode^.efbHeight,0,1);
// do this stuff after drawing
GX_DrawDone();
fb := fb xor 1; // flip framebuffer
GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
GX_SetColorUpdate(GX_TRUE);
GX_CopyDisp(frameBuffer[fb],GX_TRUE);
VIDEO_SetNextFramebuffer(frameBuffer[fb]);
VIDEO_Flush();
VIDEO_WaitVSync();
end;
end.
|