source: trunk/src/platform/nacl/nacl-instance.cpp @ 2183

Last change on this file since 2183 was 1440, checked in by sam, 11 years ago

nacl: NaCl binaries no longer need a modified main() to work, the NaCl
instance object takes care of everything for us.

  • Property svn:keywords set to Id
File size: 5.4 KB
Line 
1// Copyright (c) 2011 The Native Client Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#if defined HAVE_CONFIG_H
6#   include "config.h"
7#endif
8
9#include <cstdlib>
10#include <cstdio>
11#include <cstring>
12#include <string>
13
14#include <ppapi/cpp/rect.h>
15#include <ppapi/cpp/size.h>
16#include <ppapi/cpp/var.h>
17#include <ppapi/cpp/module.h>
18#include <ppapi/cpp/completion_callback.h>
19#include <ppapi/cpp/input_event.h>
20
21#include "core.h"
22
23#include "platform/nacl/nacl-instance.h"
24#include "platform/nacl/opengl_context.h"
25
26/* One of these wrappers will be overridden by the user's version */
27void lol_nacl_main(void) __attribute__((weak));
28void lol_nacl_main(void) {}
29void lol_nacl_main(int argc, char **argv) __attribute__((weak));
30void lol_nacl_main(int argc, char **argv) {}
31void lol_nacl_main(int argc, char **argv, char **envp) __attribute__((weak));
32void lol_nacl_main(int argc, char **argv, char **envp) {}
33
34namespace lol
35{
36
37NaClInstance::NaClInstance(PP_Instance instance)
38    : pp::Instance(instance),
39      m_size(0, 0)
40{
41    RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE);
42}
43
44NaClInstance::~NaClInstance()
45{
46    // Destroy the cube view while GL context is current.
47    m_opengl_ctx->MakeContextCurrent(this);
48}
49
50static double const DELTA_MS = 1000.0 / 60.0;
51
52void NaClInstance::TickCallback(void* data, int32_t result)
53{
54    NaClInstance *instance = (NaClInstance *)data;
55    instance->DrawSelf();
56
57    /* FIXME: only set if if Ticker isn't finished */
58    pp::Module::Get()->core()->CallOnMainThread(
59            DELTA_MS, pp::CompletionCallback(&TickCallback, data), PP_OK);
60
61    /* Propagate gamepad information */
62    PP_GamepadsSampleData all_pads_data;
63    instance->m_pad_interface->Sample(instance->pp_instance(), &all_pads_data);
64
65    for (int i = 0; i < all_pads_data.length; i++)
66    {
67        PP_GamepadSampleData const& pad_data = all_pads_data.items[i];
68
69        if (i >= instance->m_sticks.Count())
70        {
71            Stick *stick = Input::CreateStick();
72            instance->m_sticks.Push(stick);
73        }
74
75        instance->m_sticks[i]->SetAxisCount(pad_data.axes_length);
76        for (int j = 0; j < pad_data.axes_length; j++)
77            instance->m_sticks[i]->SetAxis(j, pad_data.axes[j]);
78
79        instance->m_sticks[i]->SetButtonCount(pad_data.buttons_length);
80        for (int j = 0; j < pad_data.buttons_length; j++)
81            instance->m_sticks[i]->SetButton(j, pad_data.buttons[j] > 0.5f);
82    }
83}
84
85Mutex NaClInstance::main_mutex;
86Queue<NaClInstance::Args *, 1> NaClInstance::main_queue;
87
88bool NaClInstance::Init(uint32_t argc,
89                        const char* /* argn */[],
90                        const char* argv[])
91{
92    /* Ensure only one NaClInstance does Init() at the same time. */
93    main_mutex.Lock();
94    char *env[] = { NULL };
95    Args arglist(argc, const_cast<char **>(argv), const_cast<char **>(env));
96    main_queue.Push(&arglist);
97    m_main_thread = new Thread(MainRun, NULL);
98    /* Push so that only MainSignal() can unblock us */
99    main_queue.Push(NULL);
100    main_queue.Push(NULL);
101    main_mutex.Unlock();
102
103    // My timer callback
104    pp::Module::Get()->core()->CallOnMainThread(
105            DELTA_MS, pp::CompletionCallback(&TickCallback, this), PP_OK);
106
107    /* The gamepad interface */
108    m_pad_interface = static_cast<PPB_Gamepad const *>(
109            pp::Module::Get()->GetBrowserInterface(PPB_GAMEPAD_INTERFACE));
110
111    return true;
112}
113
114void * NaClInstance::MainRun(void *data)
115{
116    Args *arglist = main_queue.Pop();
117
118    /* Call the user's main() function. One of these will work. */
119    lol_nacl_main();
120    lol_nacl_main(arglist->m_argc, arglist->m_argv);
121    lol_nacl_main(arglist->m_argc, arglist->m_argv, arglist->m_env);
122
123    return NULL;
124}
125
126void NaClInstance::MainSignal()
127{
128    /* FIXME: find something more elegant. */
129    main_queue.Pop();
130    main_queue.Pop();
131}
132
133void NaClInstance::HandleMessage(const pp::Var& message)
134{
135    if (!message.is_string())
136        return;
137    /* FIXME: do some shit here */
138}
139
140void NaClInstance::DidChangeView(const pp::Rect& position, const pp::Rect& clip)
141{
142    if (position.size().width() == m_size.x &&
143        position.size().height() == m_size.y)
144        return;  // Size didn't change, no need to update anything.
145
146    m_size = ivec2(position.size().width(), position.size().height());
147
148    if (m_opengl_ctx == NULL)
149        m_opengl_ctx.reset(new OpenGLContext(this));
150    m_opengl_ctx->InvalidateContext(this);
151    m_opengl_ctx->ResizeContext(position.size());
152    if (!m_opengl_ctx->MakeContextCurrent(this))
153        return;
154
155    Video::Setup(m_size);
156    DrawSelf();
157}
158
159bool NaClInstance::HandleInputEvent(const pp::InputEvent& event)
160{
161    switch (event.GetType())
162    {
163    case PP_INPUTEVENT_TYPE_MOUSEDOWN:
164        Input::SetMouseButton(pp::MouseInputEvent(event).GetButton());
165        break;
166    case PP_INPUTEVENT_TYPE_MOUSEUP:
167        Input::UnsetMouseButton(pp::MouseInputEvent(event).GetButton());
168        break;
169    case PP_INPUTEVENT_TYPE_MOUSEMOVE:
170        Input::SetMousePos(ivec2(pp::MouseInputEvent(event).GetPosition().x(), m_opengl_ctx->GetSize().height() - 1 - pp::MouseInputEvent(event).GetPosition().y()));
171        break;
172    default:
173        break;
174    }
175    return true;
176}
177
178void NaClInstance::DrawSelf()
179{
180    if (m_opengl_ctx == NULL)
181        return;
182
183    m_opengl_ctx->MakeContextCurrent(this);
184    Ticker::TickDraw();
185    m_opengl_ctx->FlushContext();
186}
187
188}  // namespace lol
189
Note: See TracBrowser for help on using the repository browser.