1 /*---------------------------------------------------------------------------*
2 Project: KPAD sample program
3 File: main.c
4 Programmer: Keizo Ohta
5 HIRATSU Daisuke
6
7 Copyright 2005-2006 Nintendo. All rights reserved.
8
9 These coded instructions, statements, and computer programs contain
10 proprietary information of Nintendo of America Inc. and/or Nintendo
11 Company Ltd., and are protected by Federal copyright law. They may
12 not be disclosed to third parties or copied or duplicated in any form,
13 in whole or in part, without the prior written consent of Nintendo.
14 *---------------------------------------------------------------------------*/
15
16 #include <revolution.h>
17 #include <math.h>
18
19 #include <revolution/kpadOld.h>
20 #include <revolution/mem.h>
21
22 #include "main.h"
23 #include "kfont.h"
24 #include "sample.h"
25
26
27 /***************************************************************
28 GXFIFO
29 ***************************************************************/
30 #define GX_FIFO_SIZE ( 1 * 1024*1024 ) // Large enough (The smaller the FIFO, the larger the chance of waiting for space to open when a command is issued.)
31
32 static void *gx_fifo_p ; // Pointer to buffer
33 static GXFifoObj *gx_fifo_obj ; // Management structure
34
35
36 /***************************************************************
37 Frame buffer
38 ***************************************************************/
39 GXRenderModeObj *rmode_p ; // Pointer to drawing mode
40 static u8 vfilter[7] = { 0,8, 16,16,16, 8,0 } ;
41
42 static void *xfb_p[ 2 ] ; // Pointer to double buffer
43 static s32 draw_xfb_idx ; // XFB being drawn by GX
44 static s32 disp_xfb_idx ; // XFB being displayed by VI
45
46
47 /***************************************************************
48 Controller
49 ***************************************************************/
50 KPADStatus kpads[ WPAD_MAX_CONTROLLERS ][ KPAD_MAX_READ_BUFS ] ;
51 s32 kpad_reads ;
52
53
54 /*******************************************************************************
55 Memory initialization
56 *******************************************************************************/
init_memory(void)57 static void init_memory( void )
58 {
59 void *arenaLo, *arenaHi ;
60 OSHeapHandle heap ;
61
62
63 //----- Check available memory
64 arenaLo = OSGetArenaLo() ;
65 arenaHi = OSGetArenaHi() ;
66
67 //----- Declare the creation of one heap that takes up all available memory
68 arenaLo = OSInitAlloc( arenaLo, arenaHi, 1 ) ;
69 OSSetArenaLo( arenaLo ) ; // Reset because the available memory changes
70
71 //----- Create a heap which takes up all available memory and set it as the current heap
72 heap = OSCreateHeap( arenaLo, arenaHi ) ;
73 (void)OSSetCurrentHeap( heap ) ;
74
75 //----- Make it clear ahead of time that available memory has been utilized
76 arenaLo = arenaHi ;
77 OSSetArenaLo( arenaLo ) ;
78 }
79
80
81 /*******************************************************************************
82 Initialize memory (MEM2)
83 *******************************************************************************/
84 static MEMAllocator s_mem2Allocator;
85 static MEMHeapHandle s_handle;
86
init_memory2(void)87 static void init_memory2(void)
88 {
89 void *lo = OSGetMEM2ArenaLo();
90 void *hi = OSGetMEM2ArenaHi();
91 s_handle = MEMCreateFrmHeap(lo, (u32)hi - (u32)lo);
92 if ( s_handle == MEM_HEAP_INVALID_HANDLE )
93 {
94 OSHalt("MEM2 heap allocation error.\n");
95 }
96 else
97 {
98 OSSetMEM2ArenaLo(hi);
99 MEMInitAllocatorForFrmHeap(&s_mem2Allocator, s_handle, 32); // Buffer requires 32-byte alignment.
100 }
101 }
102
alloc32(u32 size)103 static void* alloc32(u32 size)
104 {
105 return MEMAllocFromAllocator(&s_mem2Allocator, size);
106
107 }
108
free32(void * addr)109 static u8 free32(void *addr)
110 {
111 MEMFreeToAllocator(&s_mem2Allocator, addr);
112 return 1;
113 }
114
115
116 /*******************************************************************************
117 Initialize relationship with display device
118 *******************************************************************************/
init_display(void)119 static void init_display( void )
120 {
121 u32 xfb_size ;
122
123
124 //----- Select drawing mode
125 rmode_p = &GXNtsc480IntDf ;
126
127 //----- Allocate frame buffer
128 xfb_size = VIPadFrameBufferWidth(rmode_p->fbWidth) * rmode_p->xfbHeight * (u32)VI_DISPLAY_PIX_SZ ;
129 xfb_p[0] = OSAlloc( xfb_size ) ;
130 xfb_p[1] = OSAlloc( xfb_size ) ;
131
132 //----- Select a drawing buffer and display buffer
133 draw_xfb_idx = 0 ;
134 disp_xfb_idx = 1 ;
135
136 //----- Initialize VI
137 VIConfigure( rmode_p ) ;
138 VISetNextFrameBuffer( xfb_p[ disp_xfb_idx ] ) ;
139 VIFlush() ;
140
141 VIWaitForRetrace() ; // In order to enable Configure,
142 VIWaitForRetrace() ; // you need to wait two times.
143 }
144
145
146 /*******************************************************************************
147 Initialize GX relationship
148 *******************************************************************************/
init_gx(void)149 static void init_gx( void )
150 {
151 GXColor clear_clr = { 0,0,0, 0 } ;
152
153
154 //----- Create GXFIFO
155 gx_fifo_p = OSAlloc( GX_FIFO_SIZE ) ;
156 gx_fifo_obj = GXInit( gx_fifo_p, GX_FIFO_SIZE ) ;
157
158 //----- Select pixel format
159 GXSetPixelFmt( GX_PF_RGB8_Z24, GX_ZC_LINEAR ) ;
160 GXSetDither( GX_DISABLE ) ;
161
162 //----- Initialize settings for copying from EFB to XFB
163 GXSetDispCopySrc( 0, 0, rmode_p->fbWidth, rmode_p->efbHeight ) ;
164 GXSetDispCopyDst( rmode_p->fbWidth, rmode_p->xfbHeight ) ;
165 (void)GXSetDispCopyYScale( (f32)(rmode_p->xfbHeight) / (f32)(rmode_p->efbHeight) ) ;
166 GXSetDispCopyGamma( GX_GM_1_0 ) ;
167
168 GXSetCopyFilter( rmode_p->aa, rmode_p->sample_pattern, GX_ENABLE, vfilter ) ;
169 GXSetCopyClear( clear_clr, 0x00FFFFFF ) ;
170
171 //----- Initialize EFB drawing area
172 GXSetViewport( 0.0f, 0.0f, rmode_p->fbWidth, rmode_p->efbHeight, 0.0f, 1.0f ) ;
173 GXSetScissor( 0, 0, (u32)rmode_p->fbWidth, (u32)rmode_p->efbHeight ) ;
174
175 //----- Clear EFB and XFB
176 GXCopyDisp( xfb_p[0], GX_ENABLE ) ; // The EFB is cleared and garbage is placed in XFB[0]
177 GXCopyDisp( xfb_p[0], GX_DISABLE ) ; // The cleared EFB is placed in XFB[0]
178 GXCopyDisp( xfb_p[1], GX_DISABLE ) ; // The cleared EFB is placed in XFB[1]
179 GXDrawDone() ;
180 }
181
182
183 /*******************************************************************************
184 Main
185 *******************************************************************************/
main(void)186 void main( void )
187 {
188 /***********************************************************************
189 Initialization processing
190 ***********************************************************************/
191 //----- Highest-priority hardware initialization
192 VIInit() ;
193
194 //----- Other priority initializations
195 init_memory() ; // Enable allocation and release of memory
196 init_memory2();
197 init_display() ; // Display device-related
198 init_gx() ; // GX-related
199 WPADRegisterAllocator(alloc32, free32);
200 KPADInit() ; // Controller
201
202
203
204 //----- Initialize application
205 init_kfont_texture() ;
206 init_sample() ;
207
208 //----- Screen display ON
209 VISetBlack( FALSE ) ;
210 VIFlush() ;
211
212
213 /***********************************************************************
214 Main loop
215 ***********************************************************************/
216 while (1) {
217 /***************************************************************
218 First, perform calculations by the CPU
219 Then find coordinates based on controller input,
220 And prepare the data necessary to issue a GX command
221 ***************************************************************/
222 //----- Load controller
223 kpad_reads = KPADRead( 0, &kpads[0][0], KPAD_MAX_READ_BUFS ) ;
224
225 //----- Various calculations
226 work_sample() ;
227
228
229 /***************************************************************
230 Issue GX command and go on drawing to EFB
231 ***************************************************************/
232 //----- Cast spell to start issuing the command
233 GXInvalidateVtxCache() ;
234 GXInvalidateTexAll() ;
235
236 //----- Issue various commands
237 draw_sample() ;
238
239 //----- Finally, copy from EFB to XFB
240 GXCopyDisp( xfb_p[ draw_xfb_idx ], GX_ENABLE ) ;
241 GXDrawDone() ;
242
243
244 /***************************************************************
245 The XFB copied here can be selected for display on the TV
246 ***************************************************************/
247 disp_xfb_idx = draw_xfb_idx ;
248 VISetNextFrameBuffer( xfb_p[ disp_xfb_idx ] ) ;
249 VIFlush() ;
250
251 //----- Wait for the display to actually switch
252 VIWaitForRetrace() ;
253
254 //----- Switch to the no longer displayed XFB ahead of time for the next drawing
255 draw_xfb_idx ^= 1 ;
256 }
257 }
258
259