source: trunk/src/platform/nacl/nacl_instance.cpp @ 1439

Last change on this file since 1439 was 1439, checked in by sam, 8 years ago

nacl: preliminary gamepad support in the NaCl backend.

  • Property svn:keywords set to Id
File size: 4.9 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#include <vector>
14
15#include <ppapi/cpp/rect.h>
16#include <ppapi/cpp/size.h>
17#include <ppapi/cpp/var.h>
18#include <ppapi/cpp/module.h>
19#include <ppapi/cpp/completion_callback.h>
20#include <ppapi/cpp/input_event.h>
21
22#include "core.h"
23#include "debug/quad.h"
24
25#include "platform/nacl/nacl_instance.h"
26#include "platform/nacl/opengl_context.h"
27
28/* One of these wrappers will be overridden by the user's version */
29void lol_nacl_main(void) __attribute__((weak));
30void lol_nacl_main(void) {}
31void lol_nacl_main(int argc, char **argv) __attribute__((weak));
32void lol_nacl_main(int argc, char **argv) {}
33void lol_nacl_main(int argc, char **argv, char **envp) __attribute__((weak));
34void lol_nacl_main(int argc, char **argv, char **envp) {}
35
36namespace lol
37{
38
39NaClInstance::NaClInstance(PP_Instance instance)
40    : pp::Instance(instance),
41      m_size(0, 0)
42{
43    RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE);
44}
45
46NaClInstance::~NaClInstance()
47{
48    // Destroy the cube view while GL context is current.
49    opengl_context_->MakeContextCurrent(this);
50}
51
52static double const DELTA_MS = 1000.0 / 60.0;
53
54void NaClInstance::TickCallback(void* data, int32_t result)
55{
56    NaClInstance *instance = (NaClInstance *)data;
57    instance->DrawSelf();
58
59    /* FIXME: only set if if Ticker isn't finished */
60    pp::Module::Get()->core()->CallOnMainThread(
61            DELTA_MS, pp::CompletionCallback(&TickCallback, data), PP_OK);
62
63    /* Propagate gamepad information */
64    PP_GamepadsSampleData all_pads_data;
65    instance->m_pad_interface->Sample(instance->pp_instance(), &all_pads_data);
66
67    for (int i = 0; i < all_pads_data.length; i++)
68    {
69        PP_GamepadSampleData const& pad_data = all_pads_data.items[i];
70
71        if (i >= instance->m_sticks.Count())
72        {
73            Stick *stick = Input::CreateStick();
74            instance->m_sticks.Push(stick);
75        }
76
77        instance->m_sticks[i]->SetAxisCount(pad_data.axes_length);
78        for (int j = 0; j < pad_data.axes_length; j++)
79            instance->m_sticks[i]->SetAxis(j, pad_data.axes[j]);
80
81        instance->m_sticks[i]->SetButtonCount(pad_data.buttons_length);
82        for (int j = 0; j < pad_data.buttons_length; j++)
83            instance->m_sticks[i]->SetButton(j, pad_data.buttons[j] > 0.5f);
84    }
85}
86
87bool NaClInstance::Init(uint32_t argc,
88                        const char* /* argn */[],
89                        const char* argv[])
90{
91    Ticker::Setup(60.0f);
92
93    /* Call the user's main() function. FIXME: run it in a thread */
94    char *env[] = { NULL };
95    lol_nacl_main();
96    lol_nacl_main(argc, const_cast<char **>(argv));
97    lol_nacl_main(argc, const_cast<char **>(argv), (char **)env);
98
99    // My timer callback
100    pp::Module::Get()->core()->CallOnMainThread(
101            DELTA_MS, pp::CompletionCallback(&TickCallback, this), PP_OK);
102
103    /* The gamepad interface */
104    m_pad_interface = static_cast<PPB_Gamepad const *>(
105            pp::Module::Get()->GetBrowserInterface(PPB_GAMEPAD_INTERFACE));
106
107    return true;
108}
109
110void NaClInstance::RunMain(uint32_t argc,
111                           const char* /* argn */[],
112                           const char* argv[])
113{
114
115}
116
117void NaClInstance::HandleMessage(const pp::Var& message)
118{
119    if (!message.is_string())
120        return;
121    /* FIXME: do some shit here */
122}
123
124void NaClInstance::DidChangeView(const pp::Rect& position, const pp::Rect& clip)
125{
126    if (position.size().width() == m_size.x &&
127        position.size().height() == m_size.y)
128        return;  // Size didn't change, no need to update anything.
129
130    m_size = ivec2(position.size().width(), position.size().height());
131
132    if (opengl_context_ == NULL)
133        opengl_context_.reset(new OpenGLContext(this));
134    opengl_context_->InvalidateContext(this);
135    opengl_context_->ResizeContext(position.size());
136    if (!opengl_context_->MakeContextCurrent(this))
137        return;
138
139    Video::Setup(m_size);
140    DrawSelf();
141}
142
143bool NaClInstance::HandleInputEvent(const pp::InputEvent& event)
144{
145    switch (event.GetType())
146    {
147    case PP_INPUTEVENT_TYPE_MOUSEDOWN:
148        Input::SetMouseButton(pp::MouseInputEvent(event).GetButton());
149        break;
150    case PP_INPUTEVENT_TYPE_MOUSEUP:
151        Input::UnsetMouseButton(pp::MouseInputEvent(event).GetButton());
152        break;
153    case PP_INPUTEVENT_TYPE_MOUSEMOVE:
154        Input::SetMousePos(ivec2(pp::MouseInputEvent(event).GetPosition().x(), opengl_context_->GetSize().height() - 1 - pp::MouseInputEvent(event).GetPosition().y()));
155        break;
156    default:
157        break;
158    }
159    return true;
160}
161
162void NaClInstance::DrawSelf()
163{
164    if (opengl_context_ == NULL)
165        return;
166
167    opengl_context_->MakeContextCurrent(this);
168    Ticker::TickDraw();
169    opengl_context_->FlushContext();
170}
171
172}  // namespace lol
173
Note: See TracBrowser for help on using the repository browser.