life.c revision 7d4cd473f85ac64c3747c96c277f9e506a0d2246
1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/* Copyright (c) 2013 The Chromium Authors. All rights reserved.
2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * Use of this source code is governed by a BSD-style license that can be
3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * found in the LICENSE file.
4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) */
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <assert.h>
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <stdio.h>
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <stdlib.h>
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <string.h>
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ppapi/c/pp_resource.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ppapi/c/ppb_core.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ppapi/c/ppb_fullscreen.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ppapi/c/ppb_graphics_2d.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ppapi/c/ppb_image_data.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ppapi/c/ppb_input_event.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ppapi/c/ppb_instance.h"
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ppapi/c/ppb_view.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ppapi_simple/ps_event.h"
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ppapi_simple/ps_main.h"
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PPB_Core* g_pCore;
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PPB_Fullscreen* g_pFullscreen;
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PPB_Graphics2D* g_pGraphics2D;
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PPB_ImageData* g_pImageData;
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PPB_Instance* g_pInstance;
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PPB_View* g_pView;
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PPB_InputEvent* g_pInputEvent;
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PPB_KeyboardInputEvent* g_pKeyboardInput;
31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PPB_MouseInputEvent* g_pMouseInput;
32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PPB_TouchInputEvent* g_pTouchInput;
33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)struct {
35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  PP_Resource ctx;
36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  struct PP_Size size;
37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int bound;
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  uint8_t* cell_in;
39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  uint8_t* cell_out;
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} g_Context;
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const unsigned int kInitialRandSeed = 0xC0DE533D;
44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define MakeRGBA(r, g, b, a)  \
46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/*
50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * Given a count of cells in a 3x3 grid where cells are worth 1 except for
51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * the center which is worth 9, this is a color representation of how
52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * "alive" that cell is making for a more interesting representation than
53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * a binary alive or dead.
54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) */
55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint32_t kNeighborColors[] = {
56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MakeRGBA(0x00, 0x00, 0x00, 0xff),
57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MakeRGBA(0x00, 0x40, 0x00, 0xff),
58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MakeRGBA(0x00, 0x60, 0x00, 0xff),
59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MakeRGBA(0x00, 0x80, 0x00, 0xff),
60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MakeRGBA(0x00, 0xA0, 0x00, 0xff),
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MakeRGBA(0x00, 0xC0, 0x00, 0xff),
62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MakeRGBA(0x00, 0xE0, 0x00, 0xff),
63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MakeRGBA(0x00, 0x00, 0x00, 0xff),
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MakeRGBA(0x00, 0x40, 0x00, 0xff),
65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MakeRGBA(0x00, 0x60, 0x00, 0xff),
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MakeRGBA(0x00, 0x80, 0x00, 0xff),
67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MakeRGBA(0x00, 0xA0, 0x00, 0xff),
68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MakeRGBA(0x00, 0xC0, 0x00, 0xff),
69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MakeRGBA(0x00, 0xE0, 0x00, 0xff),
70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MakeRGBA(0x00, 0xFF, 0x00, 0xff),
71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MakeRGBA(0x00, 0xFF, 0x00, 0xff),
72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MakeRGBA(0x00, 0xFF, 0x00, 0xff),
73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    MakeRGBA(0x00, 0xFF, 0x00, 0xff),
74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/*
77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * These represent the new health value of a cell based on its neighboring
78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * values.  The health is binary: either alive or dead.
79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) */
80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const uint8_t kIsAlive[] = {
81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      0, 0, 0, 1, 0, 0, 0, 0, 0,  /* Values if the center cell is dead. */
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      0, 0, 1, 1, 0, 0, 0, 0, 0   /* Values if the center cell is alive. */
83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void UpdateContext(uint32_t width, uint32_t height) {
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (width != g_Context.size.width || height != g_Context.size.height) {
87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    size_t size = width * height;
88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    size_t index;
89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    free(g_Context.cell_in);
91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    free(g_Context.cell_out);
92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    /* Create a new context */
94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    g_Context.cell_in = (uint8_t*) malloc(size);
95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    g_Context.cell_out = (uint8_t*) malloc(size);
96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    memset(g_Context.cell_out, 0, size);
98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    for (index = 0; index < size; index++) {
99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      g_Context.cell_in[index] = rand() & 1;
100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  /* Recreate the graphics context on a view change */
104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_pCore->ReleaseResource(g_Context.ctx);
105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_Context.size.width = width;
106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_Context.size.height = height;
107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_Context.ctx =
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      g_pGraphics2D->Create(PSGetInstanceId(), &g_Context.size, PP_TRUE);
109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_Context.bound =
110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      g_pInstance->BindGraphics(PSGetInstanceId(), g_Context.ctx);
111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void DrawCell(int32_t x, int32_t y) {
114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int32_t width = g_Context.size.width;
115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int32_t height = g_Context.size.height;
116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!g_Context.cell_in) return;
118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (x > 0 && x < width - 1 && y > 0 && y < height - 1) {
120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    g_Context.cell_in[x - 1 + y * width] = 1;
121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    g_Context.cell_in[x + 1 + y * width] = 1;
122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    g_Context.cell_in[x + (y - 1) * width] = 1;
123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    g_Context.cell_in[x + (y + 1) * width] = 1;
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ProcessEvent(PSEvent* event) {
129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  switch(event->type) {
130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    /* If the view updates, build a new Graphics 2D Context */
131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case PSE_INSTANCE_DIDCHANGEVIEW: {
132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      struct PP_Rect rect;
133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      g_pView->GetRect(event->as_resource, &rect);
135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      UpdateContext(rect.size.width, rect.size.height);
136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      break;
137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case PSE_INSTANCE_HANDLEINPUT: {
140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      PP_InputEvent_Type type = g_pInputEvent->GetType(event->as_resource);
141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      PP_InputEvent_Modifier modifiers =
142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          g_pInputEvent->GetModifiers(event->as_resource);
143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      switch(type) {
145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        case PP_INPUTEVENT_TYPE_MOUSEDOWN: {
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          struct PP_Point location =
147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)              g_pMouseInput->GetPosition(event->as_resource);
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          DrawCell(location.x, location.y);
149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          break;
150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        }
151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        case PP_INPUTEVENT_TYPE_MOUSEMOVE: {
153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            struct PP_Point location =
154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                g_pMouseInput->GetPosition(event->as_resource);
155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            /* If the button is down, draw */
157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            if (modifiers & PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN) {
158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)              DrawCell(location.x, location.y);
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            }
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          break;
161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        }
162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        case PP_INPUTEVENT_TYPE_KEYDOWN: {
164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          PP_Bool fullscreen = g_pFullscreen->IsFullscreen(PSGetInstanceId());
165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          g_pFullscreen->SetFullscreen(PSGetInstanceId(),
166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                       fullscreen ? PP_FALSE : PP_TRUE);
167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          break;
168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        }
169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        default:
170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          break;
171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      }
172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      /* case PSE_INSTANCE_HANDLEINPUT */
173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      break;
174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    default:
177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      break;
178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void Stir(uint32_t width, uint32_t height) {
183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int i;
184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (g_Context.cell_in == NULL || g_Context.cell_out == NULL)
185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (i = 0; i < width; ++i) {
188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    g_Context.cell_in[i] = rand() & 1;
189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    g_Context.cell_in[i + (height - 1) * width] = rand() & 1;
190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (i = 0; i < height; ++i) {
192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    g_Context.cell_in[i * width] = rand() & 1;
193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    g_Context.cell_in[i * width + (width - 1)] = rand() & 1;
194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void Render() {
198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  struct PP_Size* psize = &g_Context.size;
199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  PP_ImageDataFormat format = g_pImageData->GetNativeImageDataFormat();
200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  /*
202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   * Create a buffer to draw into.  Since we are waiting until the next flush
203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   * chrome has an opportunity to cache this buffer see ppb_graphics_2d.h.
204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   */
205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  PP_Resource image =
206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      g_pImageData->Create(PSGetInstanceId(), format, psize, PP_FALSE);
207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  uint8_t* pixels = g_pImageData->Map(image);
208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  struct PP_ImageDataDesc desc;
210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  uint8_t* cell_temp;
211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  uint32_t x, y;
212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  /* If we somehow have not allocated these pointers yet, skip this frame. */
214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!g_Context.cell_in || !g_Context.cell_out) return;
215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  /* Get the stride. */
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_pImageData->Describe(image, &desc);
218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  /* Stir up the edges to prevent the simulation from reaching steady state. */
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Stir(desc.size.width, desc.size.height);
221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  /* Do neighbor summation; apply rules, output pixel color. */
223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (y = 1; y < desc.size.height - 1; ++y) {
224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    uint8_t *src0 = (g_Context.cell_in + (y - 1) * desc.size.width) + 1;
225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    uint8_t *src1 = src0 + desc.size.width;
226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    uint8_t *src2 = src1 + desc.size.width;
227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int count;
228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    uint32_t color;
229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    uint8_t *dst = (g_Context.cell_out + y * desc.size.width) + 1;
230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    uint32_t *pixel_line =  (uint32_t*) (pixels + y * desc.stride);
231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    for (x = 1; x < (desc.size.width - 1); ++x) {
233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      /* Build sum, weight center by 9x. */
234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      count = src0[-1] + src0[0] +     src0[1] +
235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)              src1[-1] + src1[0] * 9 + src1[1] +
236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)              src2[-1] + src2[0] +     src2[1];
237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      color = kNeighborColors[count];
238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      *pixel_line++ = color;
240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      *dst++ = kIsAlive[count];
241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ++src0;
242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ++src1;
243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ++src2;
244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  cell_temp = g_Context.cell_in;
248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_Context.cell_in = g_Context.cell_out;
249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_Context.cell_out = cell_temp;
250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  /* Unmap the range, we no longer need it. */
252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_pImageData->Unmap(image);
253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  /* Replace the contexts, and block until it's on the screen. */
255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_pGraphics2D->ReplaceContents(g_Context.ctx, image);
256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_pGraphics2D->Flush(g_Context.ctx, PP_BlockUntilComplete());
257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  /* Release the image data, we no longer need it. */
259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_pCore->ReleaseResource(image);
260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/*
263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * Starting point for the module.  We do not use main since it would
264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * collide with main in libppapi_cpp.
265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) */
2667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)int example_main(int argc, char *argv[]) {
267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  fprintf(stdout,"Started main.\n");
268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_pCore = (PPB_Core*)PSGetInterface(PPB_CORE_INTERFACE);
269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_pFullscreen = (PPB_Fullscreen*)PSGetInterface(PPB_FULLSCREEN_INTERFACE);
270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_pGraphics2D = (PPB_Graphics2D*)PSGetInterface(PPB_GRAPHICS_2D_INTERFACE);
271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_pInstance = (PPB_Instance*)PSGetInterface(PPB_INSTANCE_INTERFACE);
272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_pImageData = (PPB_ImageData*)PSGetInterface(PPB_IMAGEDATA_INTERFACE);
273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_pView = (PPB_View*)PSGetInterface(PPB_VIEW_INTERFACE);
274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_pInputEvent =
276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      (PPB_InputEvent*) PSGetInterface(PPB_INPUT_EVENT_INTERFACE);
277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_pKeyboardInput = (PPB_KeyboardInputEvent*)
278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      PSGetInterface(PPB_KEYBOARD_INPUT_EVENT_INTERFACE);
279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_pMouseInput =
280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      (PPB_MouseInputEvent*) PSGetInterface(PPB_MOUSE_INPUT_EVENT_INTERFACE);
281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  g_pTouchInput =
282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      (PPB_TouchInputEvent*) PSGetInterface(PPB_TOUCH_INPUT_EVENT_INTERFACE);
283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  PSEventSetFilter(PSE_ALL);
285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  while (1) {
286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    /* Process all waiting events without blocking */
287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    PSEvent* event;
288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    while ((event = PSEventTryAcquire()) != NULL) {
289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ProcessEvent(event);
290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      PSEventRelease(event);
291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    /* Render a frame, blocking until complete. */
294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (g_Context.bound) {
295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      Render();
296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
298868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return 0;
299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/*
302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * Register the function to call once the Instance Object is initialized.
303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * see: pappi_simple/ps_main.h
304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) */
305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)PPAPI_SIMPLE_REGISTER_MAIN(example_main);
306