1 /*---------------------------------------------------------------------------*
2 
3   Copyright (C) Nintendo.  All rights reserved.
4 
5   These coded instructions, statements, and computer programs contain
6   proprietary information of Nintendo of America Inc. and/or Nintendo
7   Company Ltd., and are protected by Federal copyright law.  They may
8   not be disclosed to third parties or copied or duplicated in any form,
9   in whole or in part, without the prior written consent of Nintendo.
10 
11  *---------------------------------------------------------------------------*/
12 ////===========================================================================
13 ///  demoSystem.c
14 ///
15 ///     This is system code for the demo library.
16 ///
17 ////===========================================================================
18 #include <cafe/demo.h>
19 #include <cafe/procui.h>
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdarg.h>
24 
25 void (*DEMOReleaseCallback)(void);
26 
27 #define MAX_BUFSIZ 512
28 extern unsigned int TCoreMEM2Limit(void);
TCoreMEM2Limit(void)29 extern unsigned int TCoreMEM2Limit(void)
30 {
31     // Limit TCore MEM2 Usage to: 12MB
32     // TOD0: Pick a less randmon TCore MEM limit
33     return 0x00C00000;
34 }
35 
DEMOSaveCallback(void * unused)36 u32 DEMOSaveCallback(void* unused)
37 {
38     // Finish any saving before calling OSSavesDone_ReadyToRelease
39 
40     OSSavesDone_ReadyToRelease();
41 
42     return 0;
43 }
44 
DEMOEmptyReleaseCallback(void)45 void DEMOEmptyReleaseCallback(void)
46 {
47         // If fading or something else is desired, this call can be postponed
48     ProcUIDrawDoneRelease();
49 }
50 
DEMOSetReleaseCallback(DEMOReleaseCallbackFunc func)51 void DEMOSetReleaseCallback(DEMOReleaseCallbackFunc func)
52 {
53     DEMOReleaseCallback = func;
54 }
55 
56 static BOOL gDemoInitFlag = FALSE;
57 static BOOL gDemoRunningFlag = FALSE;
58 static int sMainCore = -1;
59 
60 static DEMODefaultAllocateFunc gpAllocFunc = NULL;
61 static DEMODefaultFreeFunc     gpFreeFunc  = NULL;
62 
DEMOInit()63 void DEMOInit()
64 {
65     OSReport("DEMO: Build date - %s %s\n", __DATE__, __TIME__);
66     gDemoRunningFlag = TRUE;
67     gDemoInitFlag = TRUE;
68     sMainCore = OSGetCoreId();
69 
70     DEMOPadInit();
71 
72     ProcUIInitEx(&DEMOSaveCallback, NULL);
73 
74     DEMOReleaseCallback = &DEMOEmptyReleaseCallback;
75 }
76 
DEMOSetMainCore(int core)77 void DEMOSetMainCore(int core)
78 {
79     sMainCore = core;
80 }
81 
DEMOStopRunning()82 void DEMOStopRunning()
83 {
84     gDemoRunningFlag = FALSE;
85 }
86 
DEMOShutdown()87 void DEMOShutdown()
88 {
89         // The real purpose of this is to avoid the unused warning
90     if (!gDemoInitFlag)
91         return;
92 
93     DEMOStopRunning();
94     DEMOPadShutdown();
95 
96     gpAllocFunc = NULL;
97     gpFreeFunc  = NULL;
98 
99     gDemoInitFlag = FALSE;
100     OSReport("\nEnd of demo\n");
101 }
102 
DEMOIsRunning()103 BOOL DEMOIsRunning()
104 {
105     // Only do extra on the proper core
106     if (OSGetCoreId() != sMainCore)
107     {
108         ProcUISubProcessMessages(TRUE);
109         return gDemoRunningFlag;
110     }
111 
112     // See if test action needs to be taken
113     DEMOTestCheck();
114 
115     // See if any process switching or exiting is going on
116     ProcUIStatus status;
117 
118     // Block if we're in the background
119     status = ProcUIProcessMessages(TRUE);
120 
121         // Handle exiting or release
122     if (status == PROCUI_STATUS_EXIT)
123         DEMOStopRunning();
124     else if (status == PROCUI_STATUS_RELEASING)
125         DEMOReleaseCallback();
126 
127     if (!gDemoRunningFlag)
128     {
129             // This function can only be called when in the foreground
130             // This must be called prior to freeing any shaders or other memory the GPU might be using
131         DEMOGfxDrawDone();
132 
133         ProcUIShutdown();
134     }
135 
136     return gDemoRunningFlag;
137 }
138 
DEMOSetDefaultAllocator(DEMODefaultAllocateFunc pfnAlloc,DEMODefaultFreeFunc pfnFree)139 void DEMOSetDefaultAllocator(DEMODefaultAllocateFunc pfnAlloc, DEMODefaultFreeFunc pfnFree)
140 {
141     DEMOAssert(!gDemoInitFlag);
142     gpAllocFunc = pfnAlloc;
143     gpFreeFunc  = pfnFree;
144 }
145 
DEMOGetDefaultAllocator(DEMODefaultAllocateFunc * ppfnAlloc,DEMODefaultFreeFunc * ppfnFree)146 void DEMOGetDefaultAllocator(DEMODefaultAllocateFunc *ppfnAlloc, DEMODefaultFreeFunc *ppfnFree)
147 {
148     if (ppfnAlloc) *ppfnAlloc = gpAllocFunc;
149     if (ppfnFree)  *ppfnFree  = gpFreeFunc;
150 }
151 
DEMOAlloc(u32 size)152 void* DEMOAlloc(u32 size)
153 {
154     DEMOAssert(gDemoInitFlag);
155     if (!gpAllocFunc) {
156         return MEMAllocFromDefaultHeapEx(size, PPC_IO_BUFFER_ALIGN);
157     }
158     return gpAllocFunc(size, PPC_IO_BUFFER_ALIGN);
159 }
160 
DEMOAllocEx(u32 size,u32 align)161 void* DEMOAllocEx(u32 size, u32 align)
162 {
163     DEMOAssert(gDemoInitFlag);
164     if (!gpAllocFunc) {
165         return MEMAllocFromDefaultHeapEx(size, align);
166     }
167     return gpAllocFunc(size, align);
168 }
169 
DEMOFree(void * ptr)170 void DEMOFree(void* ptr)
171 {
172     DEMOAssert(gDemoInitFlag);
173     if (!gpFreeFunc) {
174         MEMFreeToDefaultHeap(ptr);
175     } else {
176         gpFreeFunc(ptr);
177     }
178 }
179 
180 // ----------------------------------------------------------------------------
181 //  Random
182 // ----------------------------------------------------------------------------
183 
184 static u32 holdrand = 0;
185 
DEMOSRand(u32 seed)186 void DEMOSRand(u32 seed)
187 {
188     holdrand = seed;
189 }
190 
DEMOFRand()191 f32 DEMOFRand()
192 {
193     return (f32)DEMORand() / DEMO_RAND_MAX;
194 }
195 
DEMORand()196 u32 DEMORand()
197 {
198     return (((holdrand = holdrand * 214013L + 2531011L) >> 16) & 0xffff);
199 }
200 
201 // ----------------------------------------------------------------------------
202 //  Print
203 // ----------------------------------------------------------------------------
204 
DEMOPrintf(const char * msg,...)205 void DEMOPrintf(const char* msg, ...)
206 {
207     va_list args;
208     va_start(args, msg);
209     vprintf(msg, args);
210     va_end(args);
211 }
212