source: trunk/src/platform/ps3/ps3app.cpp @ 2569

Last change on this file since 2569 was 2569, checked in by sam, 10 years ago

ps3: create an audio device at startup.

  • Property svn:keywords set to Id
File size: 7.9 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
7//   Public License, Version 2, as published by Sam Hocevar. See
8//   http://www.wtfpl.net/ for more details.
9//
10
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#if defined __CELLOS_LV2__
16#   include <sys/ppu_thread.h> /* sys_ppu_thread_get_stack_information */
17#   include <sys/spu_initialize.h>
18#   include <sys/paths.h> /* SYS_HOST_ROOT */
19#   include <cell/sysmodule.h>
20#   include <PSGL/psgl.h>
21
22#   include <cell/mstream.h> /* multistream */
23
24#   include <cell/spurs/control.h> /* SPURS */
25#   include <cell/spurs/task.h>
26#   include <cell/spurs/event_flag.h>
27#endif
28
29#include "core.h"
30#include "lolgl.h"
31#include "ps3app.h"
32#include "ps3input.h"
33
34namespace lol
35{
36
37/*
38 * PS3 App implementation class
39 */
40
41/* FIXME: this shouldn't be a global */
42static unsigned int port_num;
43
44class Ps3AppData
45{
46    friend class Ps3App;
47
48private:
49#if defined __CELLOS_LV2__
50    static void SysCallBack(uint64_t status, uint64_t param, void *data)
51    {
52        if (status == CELL_SYSUTIL_REQUEST_EXITGAME)
53            Ticker::Shutdown();
54    }
55
56    static void MultiStreamThread(uint64_t param)
57    {
58        Timer t;
59        cellAudioPortStart(port_num);
60        /* FIXME: quit gracefully if needed */
61        while (true)
62        {
63            if (!cellMSSystemSignalSPU())
64            {
65               t.Get();
66               t.Wait(1.f / 60.f / 32);
67            }
68
69            cellMSSystemGenerateCallbacks();
70        }
71        cellAudioPortStop(port_num);
72        sys_ppu_thread_exit(0);
73    }
74
75    CellSpurs m_spurs __attribute__((aligned (128)));
76#endif
77};
78
79/*
80 * Public Ps3App class
81 */
82
83Ps3App::Ps3App(char const *title, ivec2 res, float fps) :
84    data(new Ps3AppData())
85{
86#if defined __CELLOS_LV2__
87    sys_spu_initialize(6, 1);
88
89    /* FIXME: we should check for CELL_SYSMODULE_ERROR_UNKNOWN and others,
90     * but what could we do anyway? */
91    cellSysmoduleLoadModule(CELL_SYSMODULE_GCM_SYS);
92    cellSysmoduleLoadModule(CELL_SYSMODULE_FS);
93    cellSysmoduleLoadModule(CELL_SYSMODULE_USBD);
94    cellSysmoduleLoadModule(CELL_SYSMODULE_IO);
95
96    cellSysutilRegisterCallback(0, Ps3AppData::SysCallBack, nullptr);
97
98    PSGLinitOptions psglio;
99    psglio.enable = PSGL_INIT_MAX_SPUS
100                  | PSGL_INIT_INITIALIZE_SPUS
101                  | PSGL_INIT_HOST_MEMORY_SIZE;
102    psglio.maxSPUs = 1;
103    psglio.initializeSPUs = false;
104    psglio.hostMemorySize = 128 * 1024 * 1024;
105
106    psglInit(&psglio);
107
108#if 0
109    sys_ppu_thread_stack_t stack;
110    sys_ppu_thread_get_stack_information(&stack);
111    printf("stack starts at %p, ends at %p\n", stack.pst_addr,
112           (uint8_t *)stack.pst_addr + stack.pst_size);
113#endif
114
115    PSGLdeviceParameters psgldp;
116    psgldp.enable = PSGL_DEVICE_PARAMETERS_COLOR_FORMAT
117                  | PSGL_DEVICE_PARAMETERS_DEPTH_FORMAT
118                  | PSGL_DEVICE_PARAMETERS_MULTISAMPLING_MODE
119                  | PSGL_DEVICE_PARAMETERS_WIDTH_HEIGHT;
120    psgldp.colorFormat = GL_ARGB_SCE; /* can also be GL_RGBA16F_ARB */
121    psgldp.depthFormat = GL_DEPTH_COMPONENT16; /* can also be 24-bit */
122    psgldp.multisamplingMode = GL_MULTISAMPLING_4X_SQUARE_ROTATED_SCE;
123    psgldp.width = 720;
124    psgldp.height = 480;
125
126    /* Find closest valid resolution */
127    ivec2 const valid_resolutions[8] =
128    {
129        ivec2( 720,  480),
130        ivec2( 720,  576),
131        ivec2(1280,  720),
132        ivec2(1920, 1080),
133        ivec2( 960, 1080),
134        ivec2(1280, 1080),
135        ivec2(1440, 1080),
136        ivec2(1600, 1080),
137    };
138
139    for (int i = 0; i < 8; ++i)
140    {
141        ivec2 cur(psgldp.width, psgldp.height);
142        if (sqlength(valid_resolutions[i] - res) < sqlength(cur - res))
143        {
144            psgldp.width = valid_resolutions[i].x;
145            psgldp.height = valid_resolutions[i].y;
146        }
147    }
148
149    /* Create graphics device */
150    PSGLdevice* psgl = psglCreateDeviceExtended(&psgldp);
151    if (!psgl)
152        Log::Error("could not create PSGL device; expect imminent crash\n");
153
154    GLuint w, h;
155    psglGetDeviceDimensions(psgl, &w, &h);
156    ivec2 newres(w, h);
157    Log::Debug("resolution asked %d×%d, closest valid %d×%d, final %d×%d\n",
158               res.x, res.y, psgldp.width, psgldp.height, newres.x, newres.y);
159
160    PSGLcontext *ctx = psglCreateContext();
161    psglMakeCurrent(ctx, psgl);
162    /* TODO: load our shaders when we actually ship them */
163    //psglLoadShaderLibrary("/shaders.bin");
164    psglResetCurrentContext();
165
166    /* Create audio device */
167    cellSysmoduleLoadModule(CELL_SYSMODULE_IO);
168    cellSysmoduleLoadModule(CELL_SYSMODULE_AUDIO);
169    cellSysmoduleLoadModule(CELL_SYSMODULE_RESC);
170    cellSysmoduleLoadModule(CELL_SYSMODULE_SPURS);
171
172    int ret = cellMSSystemConfigureSysUtilEx(CELL_MS_AUDIOMODESELECT_SUPPORTSLPCM
173                                           | CELL_MS_AUDIOMODESELECT_SUPPORTSDOLBY
174                                           | CELL_MS_AUDIOMODESELECT_SUPPORTSDTS
175                                           | CELL_MS_AUDIOMODESELECT_PREFERDOLBY);
176    int num_chans = ret & 0xf;
177    int has_dolby = (ret & 0x10) >> 4;
178    int has_dts = (ret & 0x20) >> 5;
179
180    Log::Debug("audio channels %d, dolby %d, DTS %d\n",
181               num_chans, has_dolby, has_dts);
182    ret = cellAudioInit();
183
184    CellAudioPortParam ap;
185    memset(&ap, 0, sizeof(ap));
186    ap.nChannel = CELL_AUDIO_PORT_8CH;
187    ap.nBlock = CELL_AUDIO_BLOCK_8;
188    ret = cellAudioPortOpen(&ap, &port_num);
189    Log::Debug("audio port %d\n", port_num);
190
191    CellAudioPortConfig pc;
192    ret = cellAudioGetPortConfig(port_num, &pc);
193
194    cellMSSystemConfigureLibAudio(&ap, &pc);
195
196    CellMSSystemConfig cfg;
197    cfg.channelCount = 400; /* Maximum number of streams */
198    cfg.subCount = 31; /* ? */
199    cfg.dspPageCount = 5;
200    cfg.flags = CELL_MS_NOFLAGS;
201
202    uint8_t const prios[8] = { 1, 0, 0, 0, 0, 0, 0, 0 };
203    int mem_needed = cellMSSystemGetNeededMemorySize(&cfg);
204    void *ms_mem = memalign(128, mem_needed);
205    sys_ppu_thread_t tid;
206    sys_ppu_thread_get_id(&tid);
207    int tprio;
208    sys_ppu_thread_get_priority(tid, &tprio);
209    cellSpursInitialize(&data->m_spurs, 1, 250 /* thread group priority */,
210                        tprio - 1, false);
211    cellMSSystemInitSPURS(ms_mem, &cfg, &data->m_spurs, &prios[0]);
212
213    float const bus_vols[64] =
214    {
215        1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
216        0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
217        0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 0.f,
218        0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f,
219        0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f,
220        0.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f,
221        0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f,
222        0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f,
223    };
224
225    sys_ppu_thread_t thread;
226    ret = sys_ppu_thread_create(&thread, Ps3AppData::MultiStreamThread,
227                                NULL, 0 /* Server prio */,
228                                0x4000 /* 16 KiB stack */,
229                                SYS_PPU_THREAD_CREATE_JOINABLE,
230                                "Audio Thread");
231
232    cellMSCoreSetVolume64(CELL_MS_SUBBUS_1, CELL_MS_DRY, bus_vols);
233    cellMSCoreSetVolume64(CELL_MS_MASTER_BUS, CELL_MS_DRY, bus_vols);
234
235    /* Initialise everything */
236    Ticker::Setup(fps);
237    Video::Setup(newres);
238    Audio::Setup(2);
239
240    /* Autoreleased objects */
241    new Ps3Input();
242#endif
243}
244
245void Ps3App::ShowPointer(bool show)
246{
247    ;
248}
249
250void Ps3App::Tick()
251{
252    /* Tick the renderer, show the frame and clamp to desired framerate. */
253    Ticker::TickDraw();
254
255#if defined __CELLOS_LV2__
256    psglSwap();
257
258    /* Check if exit callback was called */
259    cellSysutilCheckCallback();
260#endif
261}
262
263Ps3App::~Ps3App()
264{
265#if defined __CELLOS_LV2__
266    glFinish();
267
268    /* Unload audio modules */
269    cellSysmoduleUnloadModule(CELL_SYSMODULE_IO);
270    cellSysmoduleUnloadModule(CELL_SYSMODULE_AUDIO);
271    cellSysmoduleUnloadModule(CELL_SYSMODULE_RESC);
272    cellSysmoduleUnloadModule(CELL_SYSMODULE_SPURS);
273#endif
274    delete data;
275}
276
277} /* namespace lol */
278
Note: See TracBrowser for help on using the repository browser.