summaryrefslogtreecommitdiffstats
path: root/native_client_sdk/src/examples/pong/pong.cc
diff options
context:
space:
mode:
Diffstat (limited to 'native_client_sdk/src/examples/pong/pong.cc')
-rw-r--r--native_client_sdk/src/examples/pong/pong.cc421
1 files changed, 0 insertions, 421 deletions
diff --git a/native_client_sdk/src/examples/pong/pong.cc b/native_client_sdk/src/examples/pong/pong.cc
deleted file mode 100644
index f650c76..0000000
--- a/native_client_sdk/src/examples/pong/pong.cc
+++ /dev/null
@@ -1,421 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <stdio.h>
-#include <cmath>
-#include <string>
-#include "ppapi/c/pp_file_info.h"
-#include "ppapi/c/ppb_file_io.h"
-#include "ppapi/cpp/completion_callback.h"
-#include "ppapi/cpp/file_io.h"
-#include "ppapi/cpp/file_ref.h"
-#include "ppapi/cpp/file_system.h"
-#include "ppapi/cpp/input_event.h"
-#include "ppapi/cpp/rect.h"
-#include "ppapi/cpp/var.h"
-
-#include "pong.h"
-#include "view.h"
-
-namespace {
-
-const uint32_t kSpaceBar = 0x20;
-const uint32_t kUpArrow = 0x26;
-const uint32_t kDownArrow = 0x28;
-
-const int32_t kMaxPointsAllowed = 256;
-const std::string kResetScoreMethodId = "resetScore";
-const uint32_t kUpdateDistance = 4;
-const int32_t kUpdateInterval = 17; // milliseconds
-
-} // namespace
-
-namespace pong {
-
-// Callbacks that are called asynchronously by the system as a result of various
-// pp::FileIO methods.
-namespace AsyncCallbacks {
-// Callback that is called as a result of pp::FileIO::Flush
-void FlushCallback(void*, int32_t) {
-}
-
-// Callback that is called as a result of pp::FileIO::SetLength
-void SetLengthCallback(void* data, int32_t result) {
- if (result != PP_OK)
- return;
- Pong* pong = static_cast<Pong*>(data);
- pong->file_io_->Flush(pp::CompletionCallback(FlushCallback, NULL));
-}
-
-// Callback that is called as a result of pp::FileIO::Write
-void WriteCallback(void* data, int32_t bytes_written) {
- if (bytes_written < 0)
- return; // error
- Pong* pong = static_cast<Pong*>(data);
- pong->offset_ += bytes_written;
- if (pong->offset_ == pong->bytes_buffer_.length()) {
- // Truncate the file.
- pong->file_io_->SetLength(pong->offset_,
- pp::CompletionCallback(SetLengthCallback, pong));
- } else {
- // Not all the bytes to be written have been written, so call
- // pp::FileIO::Write again.
- pong->file_io_->Write(pong->offset_, &pong->bytes_buffer_[pong->offset_],
- pong->bytes_buffer_.length() - pong->offset_,
- pp::CompletionCallback(WriteCallback, pong));
- }
-}
-
-// Callback that is called as a result of pp::FileSystem::Open
-void FileSystemOpenCallback(void* data, int32_t result) {
- if (result != PP_OK)
- return;
- Pong* pong = static_cast<Pong*>(data);
- pong->UpdateScoreFromFile();
-}
-
-// Callback that is called as a result of pp::FileIO::Read
-void ReadCallback(void* data, int32_t bytes_read) {
- if (bytes_read < 0)
- return; // error
- Pong* pong = static_cast<Pong*>(data);
- pong->bytes_to_read_ -= bytes_read;
- if (pong->bytes_to_read_ == 0) {
- // File has been read to completion. Parse the bytes to get the scores.
- pong->UpdateScoreFromBuffer();
- } else {
- pong->offset_ += bytes_read;
- pong->file_io_->Read(pong->offset_,
- &pong->bytes_buffer_[pong->offset_],
- pong->bytes_to_read_,
- pp::CompletionCallback(ReadCallback, pong));
- }
-}
-
-// Callback that is called as a result of pp::FileIO::Query
-void QueryCallback(void* data, int32_t result) {
- if (result != PP_OK)
- return;
- Pong* pong = static_cast<Pong*>(data);
- pong->bytes_to_read_ = pong->file_info_.size;
- pong->offset_ = 0;
- pong->bytes_buffer_.resize(pong->bytes_to_read_);
-
- // Check if there is anything to read.
- if (pong->bytes_to_read_ != 0) {
- pong->file_io_->Read(pong->offset_,
- &pong->bytes_buffer_[0],
- pong->bytes_to_read_,
- pp::CompletionCallback(ReadCallback, pong));
- }
-}
-
-// Callback that is called as a result of pp::FileIO::Open
-void FileOpenCallback(void*data, int32_t result) {
- if (result != PP_OK) {
- return;
- }
- Pong* pong = static_cast<Pong*>(data);
- // Query the file in order to get the file size.
- pong->file_io_->Query(&pong->file_info_, pp::CompletionCallback(QueryCallback,
- pong));
-}
-
-// Callback that is called as a result of pp::Core::CallOnMainThread
-void UpdateCallback(void* data, int32_t /*result*/) {
- Pong* pong = static_cast<Pong*>(data);
- pong->Update();
-}
-
-} // namespace AsyncCallbacks
-
-class UpdateScheduler {
- public:
- UpdateScheduler(int32_t delay, Pong* pong)
- : delay_(delay), pong_(pong) {}
- ~UpdateScheduler() {
- pp::Core* core = pp::Module::Get()->core();
- core->CallOnMainThread(delay_, pp::CompletionCallback(
- AsyncCallbacks::UpdateCallback, pong_));
- }
-
- private:
- int32_t delay_; // milliseconds
- Pong* pong_; // weak
-};
-
-Pong::Pong(PP_Instance instance)
- : pp::Instance(instance),
- bytes_to_read_(0),
- offset_(0),
- file_io_(NULL),
- file_ref_(NULL),
- file_system_(NULL),
- view_(NULL),
- delta_x_(0),
- delta_y_(0),
- player_score_(0),
- computer_score_(0) {
- // Request to receive input events.
- RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_KEYBOARD);
-}
-
-Pong::~Pong() {
- delete view_;
- file_io_->Close();
- delete file_io_;
- delete file_ref_;
- delete file_system_;
-}
-
-bool Pong::Init(uint32_t argc, const char* argn[], const char* argv[]) {
- view_ = new View(this);
- // Read the score from file.
- file_system_ = new pp::FileSystem(this, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
- file_ref_ = new pp::FileRef(*file_system_, "/pong_score");
- // We kick off a series of callbacks which open a file, query the file for
- // it's length in bytes, read the file contents, and then update the score
- // display based on the file contents.
- int32_t rv = file_system_->Open(
- 1024, pp::CompletionCallback(AsyncCallbacks::FileSystemOpenCallback,
- this));
- if (rv != PP_OK_COMPLETIONPENDING) {
- PostMessage(pp::Var("ERROR: Could not open local persistent file system."));
- return true;
- }
- UpdateScoreDisplay();
- UpdateScheduler(kUpdateInterval, this);
- return true;
-}
-
-void Pong::DidChangeView(const pp::View& view) {
- pp::Size view_size = view_->GetSize();
- const bool view_was_empty = view_size.IsEmpty();
- view_->UpdateView(view.GetRect(), view.GetClipRect(), this);
- if (view_was_empty)
- ResetPositions();
-}
-
-bool Pong::HandleInputEvent(const pp::InputEvent& event) {
- if (event.GetType() == PP_INPUTEVENT_TYPE_MOUSEUP) {
- // By notifying the browser mouse clicks are handled, the application window
- // is able to get focus and receive key events.
- return true;
- } else if (event.GetType() == PP_INPUTEVENT_TYPE_KEYUP) {
- pp::KeyboardInputEvent key = pp::KeyboardInputEvent(event);
- return view_->KeyUp(key);
- } else if (event.GetType() == PP_INPUTEVENT_TYPE_KEYDOWN) {
- pp::KeyboardInputEvent key = pp::KeyboardInputEvent(event);
- return view_->KeyDown(key);
- }
- return false;
-}
-
-
-void Pong::HandleMessage(const pp::Var& var_message) {
- if (!var_message.is_string())
- return;
- std::string message = var_message.AsString();
- if (message == kResetScoreMethodId) {
- ResetScore();
- }
-}
-
-void Pong::Update() {
- // Schedule another update
- UpdateScheduler(kUpdateInterval, this);
-
- const uint32_t key_code = view_->last_key_code();
- if (key_code == kSpaceBar) {
- ResetPositions();
- return;
- }
- if (ball_.right() < court_.x()) {
- ++computer_score_;
- if (computer_score_ > kMaxPointsAllowed) {
- ResetScore();
- } else {
- WriteScoreToFile();
- UpdateScoreDisplay();
- }
- ResetPositions();
- return;
- }
- if (ball_.x() > court_.right()) {
- ++player_score_;
- if (player_score_ > kMaxPointsAllowed) {
- ResetScore();
- } else {
- WriteScoreToFile();
- UpdateScoreDisplay();
- }
- ResetPositions();
- return;
- }
- // Update human controlled paddle
- if (key_code == kUpArrow) {
- left_paddle_.Offset(0, -kUpdateDistance);
- if (left_paddle_.y() - 1 < court_.y()) {
- left_paddle_.Offset(0, court_.y() - left_paddle_.y() + 1);
- }
- } else if (key_code == kDownArrow) {
- left_paddle_.Offset(0, kUpdateDistance);
- if (left_paddle_.bottom() + 1 > court_.bottom()) {
- left_paddle_.Offset(0, court_.bottom() - left_paddle_.bottom() - 1);
- }
- }
-
- // Update AI controlled paddle
- BallDirection direction = RightPaddleNextMove();
- if (direction == kUpDirection) {
- right_paddle_.Offset(0, -kUpdateDistance);
- if (right_paddle_.y() < court_.y() + 1) {
- right_paddle_.Offset(0, court_.y() - right_paddle_.y() + 1);
- }
- } else if (direction == kDownDirection) {
- right_paddle_.Offset(0, kUpdateDistance);
- if (right_paddle_.bottom() > court_.bottom() - 1) {
- right_paddle_.Offset(0, court_.bottom() - right_paddle_.bottom() - 1);
- }
- }
-
- // Bounce ball off bottom of screen
- if (ball_.bottom() >= court_.bottom() - 1) {
- ball_.Offset(0, court_.bottom() - ball_.bottom() - 1);
- delta_y_ = -delta_y_;
- }
- // Bounce ball off top of screen
- if (ball_.y() <= court_.y() + 1) {
- ball_.Offset(0, court_.y() - ball_.y() + 1);
- delta_y_ = -delta_y_;
- }
- // Bounce ball off human controlled paddle
- if (left_paddle_.Intersects(ball_)) {
- delta_x_ = abs(delta_x_);
- if (ball_.CenterPoint().y() <
- left_paddle_.y() + left_paddle_.height() / 5) {
- delta_y_ -= kUpdateDistance;
- if (delta_y_ == 0)
- delta_y_ = -kUpdateDistance;
- } else if (ball_.CenterPoint().y() >
- left_paddle_.bottom() - left_paddle_.height() / 5) {
- delta_y_ += kUpdateDistance;
- if (delta_y_ == 0)
- delta_y_ = kUpdateDistance;
- }
- }
- // Bounce ball off ai controlled paddle
- if (right_paddle_.Intersects(ball_)) {
- delta_x_ = -abs(delta_x_);
- if (ball_.CenterPoint().y() >
- right_paddle_.bottom() - right_paddle_.height() / 5) {
- delta_y_ += kUpdateDistance;
- if (delta_y_ == 0)
- delta_y_ = kUpdateDistance;
- } else if (ball_.CenterPoint().y() <
- right_paddle_.y() + right_paddle_.height() / 5) {
- delta_y_ -= kUpdateDistance;
- if (delta_y_ == 0)
- delta_y_ -= kUpdateDistance;
- }
- }
-
- // Move ball
- ball_.Offset(delta_x_, delta_y_);
-
- view_->set_ball_rect(ball_);
- view_->set_left_paddle_rect(left_paddle_);
- view_->set_right_paddle_rect(right_paddle_);
- view_->Draw();
-}
-
-void Pong::UpdateScoreFromBuffer() {
- size_t pos = bytes_buffer_.find_first_of(':');
- player_score_ = ::atoi(bytes_buffer_.substr(0, pos).c_str());
- computer_score_ = ::atoi(bytes_buffer_.substr(pos + 1).c_str());
- UpdateScoreDisplay();
-}
-
-void Pong::UpdateScoreFromFile() {
- file_io_ = new pp::FileIO(this);
- file_io_->Open(*file_ref_,
- PP_FILEOPENFLAG_READ | PP_FILEOPENFLAG_WRITE |
- PP_FILEOPENFLAG_CREATE,
- pp::CompletionCallback(AsyncCallbacks::FileOpenCallback,
- this));
-}
-
-void Pong::WriteScoreToFile() {
- if (file_io_ == NULL)
- return;
- // Write the score in <player score>:<computer score> format.
- char buffer[100];
- snprintf(&buffer[0], sizeof(buffer), "%d:%d", player_score_, computer_score_);
- bytes_buffer_ = std::string(&buffer[0]);
- offset_ = 0; // overwrite score in file.
- file_io_->Write(offset_,
- bytes_buffer_.c_str(),
- bytes_buffer_.length(),
- pp::CompletionCallback(AsyncCallbacks::WriteCallback, this));
-}
-
-void Pong::ResetPositions() {
- pp::Size court_size = view_->GetSize();
- pp::Rect court_rect(court_size);
- court_.SetRect(court_rect);
-
- pp::Rect rect;
- rect.set_width(20);
- rect.set_height(20);
- rect.set_x((court_rect.x() + court_rect.width()) / 2 - rect.width() / 2);
- rect.set_y(court_rect.y() + court_rect.height() - rect.height());
- ball_.SetRect(rect);
-
- const float paddle_width = 10;
- const float paddle_height = 99;
- const float paddle_pos_y =
- (court_rect.y() + court_rect.height()) / 2 - rect.height() / 2;
- rect.set_width(paddle_width);
- rect.set_height(paddle_height);
- rect.set_x(court_rect.x() + court_rect.width() / 5 + 1);
- rect.set_y(paddle_pos_y);
- left_paddle_.SetRect(rect);
-
- rect.set_width(paddle_width);
- rect.set_height(paddle_height);
- rect.set_x(court_rect.x() + 4 * court_rect.width() / 5 - rect.width() - 1);
- rect.set_y(paddle_pos_y);
- right_paddle_.SetRect(rect);
-
- delta_x_ = delta_y_ = kUpdateDistance;
-}
-
-void Pong::ResetScore() {
- player_score_ = 0;
- computer_score_ = 0;
- UpdateScoreDisplay();
-}
-
-Pong::BallDirection Pong::RightPaddleNextMove() const {
- static int32_t last_ball_y = 0;
- int32_t ball_y = ball_.CenterPoint().y();
- BallDirection ball_direction =
- ball_y < last_ball_y ? kUpDirection : kDownDirection;
- last_ball_y = ball_y;
-
- if (ball_y < right_paddle_.y())
- return kUpDirection;
- if (ball_y > right_paddle_.bottom())
- return kDownDirection;
- return ball_direction;
-}
-
-void Pong::UpdateScoreDisplay() {
- char buffer[100];
- snprintf(&buffer[0], sizeof(buffer), "You %d: Computer %d", player_score_,
- computer_score_);
- PostMessage(pp::Var(buffer));
-}
-
-} // namespace pong