Example #1
0
void UpdateContext(uint32_t width, uint32_t height) {
  if (width != g_Context.size.width || height != g_Context.size.height) {
    size_t size = width * height;
    size_t index;

    free(g_Context.cell_in);
    free(g_Context.cell_out);

    /* Create a new context */
    g_Context.cell_in = (uint8_t*) malloc(size);
    g_Context.cell_out = (uint8_t*) malloc(size);

    memset(g_Context.cell_out, 0, size);
    for (index = 0; index < size; index++) {
      g_Context.cell_in[index] = rand() & 1;
    }
  }

  /* Recreate the graphics context on a view change */
  g_pCore->ReleaseResource(g_Context.ctx);
  g_Context.size.width = width;
  g_Context.size.height = height;
  g_Context.ctx =
      g_pGraphics2D->Create(PSGetInstanceId(), &g_Context.size, PP_TRUE);
  g_Context.bound =
      g_pInstance->BindGraphics(PSGetInstanceId(), g_Context.ctx);
}
Example #2
0
void ProcessEvent(PSEvent* event) {
  switch(event->type) {
    /* If the view updates, build a new Graphics 2D Context */
    case PSE_INSTANCE_DIDCHANGEVIEW: {
      struct PP_Rect rect;

      g_pView->GetRect(event->as_resource, &rect);
      UpdateContext(rect.size.width, rect.size.height);
      break;
    }

    case PSE_INSTANCE_HANDLEINPUT: {
      PP_InputEvent_Type type = g_pInputEvent->GetType(event->as_resource);
      PP_InputEvent_Modifier modifiers =
          g_pInputEvent->GetModifiers(event->as_resource);

      switch(type) {
        case PP_INPUTEVENT_TYPE_MOUSEDOWN: {
          struct PP_Point location =
              g_pMouseInput->GetPosition(event->as_resource);
          DrawCell(location.x, location.y);
          break;
        }

        case PP_INPUTEVENT_TYPE_MOUSEMOVE: {
            struct PP_Point location =
                g_pMouseInput->GetPosition(event->as_resource);

            /* If the button is down, draw */
            if (modifiers & PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN) {
              DrawCell(location.x, location.y);
            }
          break;
        }

        case PP_INPUTEVENT_TYPE_KEYDOWN: {
          PP_Bool fullscreen = g_pFullscreen->IsFullscreen(PSGetInstanceId());
          g_pFullscreen->SetFullscreen(PSGetInstanceId(),
                                       fullscreen ? PP_FALSE : PP_TRUE);
          break;
        }
        default:
          break;
      }
      /* case PSE_INSTANCE_HANDLEINPUT */
      break;
    }

    default:
      break;
  }
}
Example #3
0
/** @internal @This allocates an nacl audio pipe.
 *
 * @param mgr common management structure
 * @param uprobe structure used to raise events
 * @param signature signature of the pipe allocator
 * @param args optional arguments
 * @return pointer to upipe or NULL in case of allocation error
 */
static struct upipe *upipe_nacl_audio_alloc(struct upipe_mgr *mgr,
                                            struct uprobe *uprobe,
                                            uint32_t signature, va_list args)
{
    if (signature != UPIPE_VOID_SIGNATURE)
        return NULL;
    struct upipe_nacl_audio *upipe_nacl_audio =
        malloc(sizeof(struct upipe_nacl_audio) +
               uqueue_sizeof(MAX_QUEUE_LENGTH));
    if (unlikely(upipe_nacl_audio == NULL))
        return NULL;

    if(unlikely(!uqueue_init(&upipe_nacl_audio->uqueue, MAX_QUEUE_LENGTH,
                             upipe_nacl_audio->uqueue_extra))) {
        free(upipe_nacl_audio);
        return NULL;
    }

    struct upipe *upipe = upipe_nacl_audio_to_upipe(upipe_nacl_audio);
    upipe_init(upipe, mgr, uprobe);

    upipe_nacl_audio_init_urefcount(upipe);
    upipe_nacl_audio_init_input(upipe);
    upipe_nacl_audio_init_upump_mgr(upipe);
    upipe_nacl_audio_init_upump(upipe);
    upipe_nacl_audio_init_uclock(upipe);
    upipe_nacl_audio->started = false;

    PPB_AudioConfig *audio_config_interface =
        (PPB_AudioConfig *)PSGetInterface(PPB_AUDIO_CONFIG_INTERFACE);
    upipe_nacl_audio->nb_samples =
        audio_config_interface->RecommendSampleFrameCount(PSGetInstanceId(),
                SAMPLE_RATE, NB_SAMPLES);
    upipe_nacl_audio->audio_config =
        audio_config_interface->CreateStereo16Bit(PSGetInstanceId(),
                SAMPLE_RATE, upipe_nacl_audio->nb_samples);

    upipe_nacl_audio->core_interface =
        (PPB_Core *)PSGetInterface(PPB_CORE_INTERFACE);
    upipe_nacl_audio->audio_interface =
        (PPB_Audio *)PSGetInterface(PPB_AUDIO_INTERFACE);
    upipe_nacl_audio->audio =
        upipe_nacl_audio->audio_interface->Create(PSGetInstanceId(),
                                upipe_nacl_audio->audio_config,
                                upipe_nacl_audio_worker, upipe);

    upipe_throw_ready(upipe);
    return upipe;
}
Example #4
0
static int
NACLAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) {
    PP_Instance instance = PSGetInstanceId();
    const PPB_Audio *ppb_audio = PSInterfaceAudio();
    const PPB_AudioConfig *ppb_audiocfg = PSInterfaceAudioConfig();
    
    private = (SDL_PrivateAudioData *) SDL_calloc(1, (sizeof *private));
Example #5
0
void Render() {
  struct PP_Size* psize = &g_Context.size;
  PP_ImageDataFormat format = PP_IMAGEDATAFORMAT_BGRA_PREMUL;

  PP_Resource image =
      g_pImageData->Create(PSGetInstanceId(), format, psize, PP_FALSE);
  uint8_t* pixels = g_pImageData->Map(image);

  struct PP_ImageDataDesc desc;
  uint8_t* cell_temp;
  uint32_t x, y;

  
  if (!g_Context.cell_in || !g_Context.cell_out) return;

  
  g_pImageData->Describe(image, &desc);

  
  Stir(desc.size.width, desc.size.height);

  
  for (y = 1; y < desc.size.height - 1; ++y) {
    uint8_t *src0 = (g_Context.cell_in + (y - 1) * desc.size.width) + 1;
    uint8_t *src1 = src0 + desc.size.width;
    uint8_t *src2 = src1 + desc.size.width;
    int count;
    uint32_t color;
    uint8_t *dst = (g_Context.cell_out + y * desc.size.width) + 1;
    uint32_t *pixel_line =  (uint32_t*) (pixels + y * desc.stride);

    for (x = 1; x < (desc.size.width - 1); ++x) {
      
      count = src0[-1] + src0[0] +     src0[1] +
              src1[-1] + src1[0] * 9 + src1[1] +
              src2[-1] + src2[0] +     src2[1];
      color = kNeighborColors[count];

      *pixel_line++ = color;
      *dst++ = kIsAlive[count];
      ++src0;
      ++src1;
      ++src2;
    }
  }

  cell_temp = g_Context.cell_in;
  g_Context.cell_in = g_Context.cell_out;
  g_Context.cell_out = cell_temp;

  
  g_pImageData->Unmap(image);

  
  g_pGraphics2D->ReplaceContents(g_Context.ctx, image);
  g_pGraphics2D->Flush(g_Context.ctx, PP_BlockUntilComplete());

  
  g_pCore->ReleaseResource(image);
}
Example #6
0
void network_error() {
  Json::Value writerRoot;
  writerRoot["result"] = 1;
  writerRoot["type"] = "network error";
  Json::StyledWriter writer;
  std::string msg(writer.write(writerRoot));
  struct PP_Var var = PSInterfaceVar()->VarFromUtf8(msg.data(), msg.length());
  PSInterfaceMessaging()->PostMessage(PSGetInstanceId(), var);
  PSInterfaceVar()->Release(var);
}
Example #7
0
struct PP_Var nspawn_send_request(struct PP_Var req_var) {
  /*
   * naclprocess.js is required in order send requests to JavaScript.
   * If NACL_PROCESS is not set in the environment then we assume it is
   * not present and exit early. Without this check we would block forever
   * waiting for a response for the JavaScript side.
   *
   * Only check this once per process, as some programs (emacs)
   * engage in manipulation of the environment that may not be safely
   * read at all times.
   */
  static int checked_for_nacl_process = 0;
  if (!checked_for_nacl_process) {
    const char* naclprocess = getenv("NACL_PROCESS");
    if (naclprocess == NULL) {
      fprintf(stderr, "nspawn_send_request called without NACL_PROCESS set\n");
      return PP_MakeNull();
    }
    checked_for_nacl_process = 1;
  }

  int64_t id = get_request_id();
  char req_id[64];
  sprintf(req_id, "%lld", id);
  nspawn_dict_setstring(req_var, "id", req_id);

  struct NaClSpawnReply reply;
  pthread_mutex_init(&reply.mu, NULL);
  pthread_cond_init(&reply.cond, NULL);
  PSEventRegisterMessageHandler(req_id, &handle_reply, &reply);

  PSInterfaceMessaging()->PostMessage(PSGetInstanceId(), req_var);
  nspawn_var_release(req_var);

  pthread_mutex_lock(&reply.mu);
  /*
   * Wait for response for JavaScript.  This can block for an unbounded amount
   * of time (e.g. waiting for a response to waitpid).
   */
  int error = pthread_cond_wait(&reply.cond, &reply.mu);
  pthread_mutex_unlock(&reply.mu);

  pthread_cond_destroy(&reply.cond);
  pthread_mutex_destroy(&reply.mu);

  PSEventRegisterMessageHandler(req_id, NULL, &reply);

  if (error != 0) {
    fprintf(stderr, "nspawn_send_request: pthread_cond_timedwait: %s\n",
          strerror(error));
    return PP_MakeNull();
  }

  return reply.result_var;
}
Example #8
0
int
nacl_main(int argc, char *argv[])
{
    int status;
    PSEvent* ps_event;
    PP_Resource event;  
    struct PP_Rect rect;
    int ready = 0;
    const PPB_View *ppb_view = PSInterfaceView();
    
    /* This is started in a worker thread by ppapi_simple! */
    
    /* Wait for the first PSE_INSTANCE_DIDCHANGEVIEW event before starting the app */
    
    PSEventSetFilter(PSE_INSTANCE_DIDCHANGEVIEW);
    while (!ready) {
        /* Process all waiting events without blocking */
        while (!ready && (ps_event = PSEventWaitAcquire()) != NULL) {
            event = ps_event->as_resource;
            switch(ps_event->type) {
                /* From DidChangeView, contains a view resource */
                case PSE_INSTANCE_DIDCHANGEVIEW:
                    ppb_view->GetRect(event, &rect);
                    NACL_SetScreenResolution(rect.size.width, rect.size.height, 0);
                    ready = 1;
                    break;
                default:
                    break;
            }
            PSEventRelease(ps_event);
        }
    }
    
    /* Do a default httpfs mount on /, 
     * apps can override this by unmounting / 
     * and remounting with the desired configuration
     */
    nacl_io_init_ppapi(PSGetInstanceId(), PSGetInterface);
    
    umount("/");
    mount(
        "",  /* source */
        "/",  /* target */
        "httpfs",  /* filesystemtype */
        0,  /* mountflags */
        "");  /* data specific to the html5fs type */
    
    /* Everything is ready, start the user main function */
    SDL_SetMainReady();
    status = SDL_main(argc, argv);

    return 0;
}
Example #9
0
int NACL_VideoInit(_THIS) {
    SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata;
    SDL_DisplayMode mode;

    SDL_zero(mode);
    mode.format = driverdata->format;
    mode.w = driverdata->w;
    mode.h = driverdata->h;
    mode.refresh_rate = 0;
    mode.driverdata = NULL;
    if (SDL_AddBasicVideoDisplay(&mode) < 0) {
        return -1;
    }

    SDL_AddDisplayMode(&_this->displays[0], &mode);
    
    PSInterfaceInit();
    driverdata->instance = PSGetInstanceId();
    driverdata->ppb_graphics = PSInterfaceGraphics3D();
    driverdata->ppb_message_loop = PSInterfaceMessageLoop();
    driverdata->ppb_core = PSInterfaceCore();
    driverdata->ppb_fullscreen = PSInterfaceFullscreen();
    driverdata->ppb_instance = PSInterfaceInstance();
    driverdata->ppb_image_data = PSInterfaceImageData();
    driverdata->ppb_view = PSInterfaceView();
    driverdata->ppb_var = PSInterfaceVar();
    driverdata->ppb_input_event = (PPB_InputEvent*) PSGetInterface(PPB_INPUT_EVENT_INTERFACE);
    driverdata->ppb_keyboard_input_event = (PPB_KeyboardInputEvent*) PSGetInterface(PPB_KEYBOARD_INPUT_EVENT_INTERFACE);
    driverdata->ppb_mouse_input_event = (PPB_MouseInputEvent*) PSGetInterface(PPB_MOUSE_INPUT_EVENT_INTERFACE);
    driverdata->ppb_wheel_input_event = (PPB_WheelInputEvent*) PSGetInterface(PPB_WHEEL_INPUT_EVENT_INTERFACE);
    driverdata->ppb_touch_input_event = (PPB_TouchInputEvent*) PSGetInterface(PPB_TOUCH_INPUT_EVENT_INTERFACE);
    
    
    driverdata->message_loop = driverdata->ppb_message_loop->Create(driverdata->instance);
    
    PSEventSetFilter(PSE_ALL);
    
    /* We're done! */
    return 0;
}
Example #10
0
void Render() {
  struct PP_Size* psize = &g_Context.size;
  PP_ImageDataFormat format = PP_IMAGEDATAFORMAT_BGRA_PREMUL;

  /*
   * Create a buffer to draw into.  Since we are waiting until the next flush
   * chrome has an opportunity to cache this buffer see ppb_graphics_2d.h.
   */
  PP_Resource image =
      g_pImageData->Create(PSGetInstanceId(), format, psize, PP_FALSE);
  uint8_t* pixels = g_pImageData->Map(image);

  struct PP_ImageDataDesc desc;
  uint8_t* cell_temp;
  uint32_t x, y;

  /* If we somehow have not allocated these pointers yet, skip this frame. */
  if (!g_Context.cell_in || !g_Context.cell_out) return;

  /* Get the stride. */
  g_pImageData->Describe(image, &desc);

  /* Stir up the edges to prevent the simulation from reaching steady state. */
  Stir(desc.size.width, desc.size.height);

  /* Do neighbor summation; apply rules, output pixel color. */
  for (y = 1; y < desc.size.height - 1; ++y) {
    uint8_t *src0 = (g_Context.cell_in + (y - 1) * desc.size.width) + 1;
    uint8_t *src1 = src0 + desc.size.width;
    uint8_t *src2 = src1 + desc.size.width;
    int count;
    uint32_t color;
    uint8_t *dst = (g_Context.cell_out + y * desc.size.width) + 1;
    uint32_t *pixel_line =  (uint32_t*) (pixels + y * desc.stride);

    for (x = 1; x < (desc.size.width - 1); ++x) {
      /* Jitter and sum neighbors. */
      count = src0[-1] + src0[0] + src0[1] +
              src1[-1] +         + src1[1] +
              src2[-1] + src2[0] + src2[1];
      /* Include center cell. */
      count = count + count + src1[0];
      /* Use table lookup indexed by count to determine pixel & alive state. */
      color = kNeighborColors[count];
      *pixel_line++ = color;
      *dst++ = kIsAlive[count];
      ++src0;
      ++src1;
      ++src2;
    }
  }

  cell_temp = g_Context.cell_in;
  g_Context.cell_in = g_Context.cell_out;
  g_Context.cell_out = cell_temp;

  /* Unmap the range, we no longer need it. */
  g_pImageData->Unmap(image);

  /* Replace the contexts, and block until it's on the screen. */
  g_pGraphics2D->ReplaceContents(g_Context.ctx, image);
  g_pGraphics2D->Flush(g_Context.ctx, PP_BlockUntilComplete());

  /* Release the image data, we no longer need it. */
  g_pCore->ReleaseResource(image);
}
Example #11
0
static int NACL_Available(void) {
    return PSGetInstanceId() != 0;
}
Example #12
0
int ProcessProperties(void) {
  /* Reset verbosity if passed in */
  const char* verbosity = getenv("PS_VERBOSITY");
  if (verbosity)
    PSInstanceSetVerbosity(atoi(verbosity));

  /* Enable NaCl IO to map STDIN, STDOUT, and STDERR */
  nacl_io_init_ppapi(PSGetInstanceId(), PSGetInterface);

  s_tty_prefix = getenv("PS_TTY_PREFIX");
  if (s_tty_prefix) {
    s_tty_fd = open("/dev/tty", O_WRONLY);
    if (s_tty_fd >= 0) {
      PSEventRegisterMessageHandler(s_tty_prefix, MessageHandlerInput, NULL);
      const char* tty_resize = getenv("PS_TTY_RESIZE");
      if (tty_resize)
        PSEventRegisterMessageHandler(tty_resize, MessageHandlerResize, NULL);

      char* tty_rows = getenv("PS_TTY_ROWS");
      char* tty_cols = getenv("PS_TTY_COLS");
      if (tty_rows && tty_cols) {
        char* end = tty_rows;
        int rows = strtol(tty_rows, &end, 10);
        if (*end != '\0' || rows < 0) {
          PSInstanceError("Invalid value for PS_TTY_ROWS: %s\n", tty_rows);
        } else {
          end = tty_cols;
          int cols = strtol(tty_cols, &end, 10);
          if (*end != '\0' || cols < 0)
            PSInstanceError("Invalid value for PS_TTY_COLS: %s\n", tty_cols);
          else
            HandleResize(cols, rows);
        }
      } else if (tty_rows || tty_cols) {
        PSInstanceError("PS_TTY_ROWS and PS_TTY_COLS must be set together\n");
      }

      struct tioc_nacl_output handler;
      handler.handler = TtyOutputHandler;
      handler.user_data = NULL;
      ioctl(s_tty_fd, TIOCNACLOUTPUT, &handler);
    } else {
      PSInstanceError("Failed to open /dev/tty.\n");
    }
  }

  /* Set default values */
  setenv("PS_STDIN", "/dev/stdin", 0);
  setenv("PS_STDOUT", "/dev/stdout", 0);
  setenv("PS_STDERR", "/dev/console3", 0);

  int fd0 = open(getenv("PS_STDIN"), O_RDONLY);
  dup2(fd0, 0);

  int fd1 = open(getenv("PS_STDOUT"), O_WRONLY);
  dup2(fd1, 1);

  int fd2 = open(getenv("PS_STDERR"), O_WRONLY);
  dup2(fd2, 2);

  PSEventRegisterMessageHandler("jspipe1", MessageHandlerInput, NULL);
  PSEventRegisterMessageHandler("jspipe2", MessageHandlerInput, NULL);
  PSEventRegisterMessageHandler("jspipe3", MessageHandlerInput, NULL);

  s_exit_message = getenv("PS_EXIT_MESSAGE");

  /* If PS_EXIT_MESSAGE is set in the environment then we perform a handshake
   * with JavaScript when program exits. */
  if (s_exit_message != NULL)
    nacl_io_set_exit_callback(ExitHandshake, NULL);

  /* Set line buffering on stdout and stderr */
#if !defined(WIN32)
  setvbuf(stderr, NULL, _IOLBF, 0);
  setvbuf(stdout, NULL, _IOLBF, 0);
#endif
  return 1;
}
Example #13
0
int my_main(int argc, char *argv[])
{
	SDL_NACL_SetInstance(PSGetInstanceId(), 640, 480);
	umount("/");
	mount("", "/", "memfs", 0, NULL);
	mount("", "/http", "httpfs", 0, "manifest=/manifest.txt");
	mount("", "/save", "html5fs", 0, "type=PERSISTENT");

	CopyFile("/http/font.ttf", "/font.ttf");
	CopyFile("/http/sprites.sif", "/sprites.sif");
	CopyFile("/http/tilekey.dat", "/tilekey.dat");
	ExtractGameZip("/save/cavestoryen.zip");

	mkdir("/pxt", 0666);

	PSEventSetFilter(PSE_INSTANCE_HANDLEINPUT | PSE_INSTANCE_DIDCHANGEFOCUS);

#else
int main(int argc, char *argv[])
{
#endif
bool inhibit_loadfade = false;
bool error = false;
bool freshstart;

	//SetLogFilename("debug.txt");
	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
	{
		staterr("ack, sdl_init failed: %s.", SDL_GetError());
		return 1;
	}
	atexit(SDL_Quit);
	
	// start up inputs first thing because settings_load may remap them
	input_init();
	
	// load settings, or at least get the defaults,
	// so we know the initial screen resolution.
	settings_load();
	
	if (Graphics::init(settings->resolution)) { staterr("Failed to initilize graphics."); return 1; }
	if (font_init()) { staterr("Failed to load font."); return 1; }
	
	//speed_test();
	//return 1;
	
	#ifdef CONFIG_DATA_EXTRACTOR
	if (!settings->files_extracted)
	{
		if (extract_main())
		{
			Graphics::close();
			font_close();
			return 0;
		}
		else
		{
			settings->files_extracted = true;
			settings_save();
		}
	}
	#endif
	
	if (check_data_exists())
	{
		return 1;
	}
	
	//Graphics::ShowLoadingScreen();
	if (sound_init()) { fatal("Failed to initilize sound."); return 1; }
	if (trig_init()) { fatal("Failed trig module init."); return 1; }
	
	if (tsc_init()) { fatal("Failed to initilize script engine."); return 1; }
	if (textbox.Init()) { fatal("Failed to initialize textboxes."); return 1; }
	if (Carets::init()) { fatal("Failed to initialize carets."); return 1; }
	
	if (game.init()) return 1;
	game.setmode(GM_NORMAL);
	// set null stage just to have something to do while we go to intro
	game.switchstage.mapno = 0;
	
	//#define REPLAY
	#ifdef REPLAY
		game.switchstage.mapno = START_REPLAY;
		//Replay::set_ffwd(6000);
		//Replay::set_stopat(3500);
		game.switchstage.param = 1;
	#else
		//game.switchstage.mapno = LOAD_GAME;
		//game.pause(GP_OPTIONS);
		
		if (settings->skip_intro && file_exists(GetProfileName(settings->last_save_slot)))
			game.switchstage.mapno = LOAD_GAME;
		else
			game.setmode(GM_INTRO);
	#endif
	
	// for debug
	if (game.paused) { game.switchstage.mapno = 0; game.switchstage.eventonentry = 0; }
	if (game.switchstage.mapno == LOAD_GAME) inhibit_loadfade = true;
	
	game.running = true;
	freshstart = true;
	
	stat("Entering main loop...");
	#ifdef __SDLSHIM__
		set_console_visible(false);
	#endif
	
	//speed_test();
	//return 1;
	
	while(game.running)
	{
		// SSS/SPS persists across stage transitions until explicitly
		// stopped, or you die & reload. It seems a bit risky to me,
		// but that's the spec.
		if (game.switchstage.mapno >= MAPNO_SPECIALS)
		{
			StopLoopSounds();
		}
		
		// enter next stage, whatever it may be
		if (game.switchstage.mapno == LOAD_GAME || \
			game.switchstage.mapno == LOAD_GAME_FROM_MENU)
		{
			if (game.switchstage.mapno == LOAD_GAME_FROM_MENU)
				freshstart = true;
			
			stat("= Loading game =");
			if (game_load(settings->last_save_slot))
			{
				fatal("savefile error");
				goto ingame_error;
			}
			
			Replay::OnGameStarting();
			
			if (!inhibit_loadfade) fade.Start(FADE_IN, FADE_CENTER);
			else inhibit_loadfade = false;
		}
		else if (game.switchstage.mapno == START_REPLAY)
		{
			stat(">> beginning replay '%s'", GetReplayName(game.switchstage.param));
			
			StopScripts();
			if (Replay::begin_playback(GetReplayName(game.switchstage.param)))
			{
				fatal("error starting playback");
				goto ingame_error;
			}
		}
		else
		{
			if (game.switchstage.mapno == NEW_GAME || \
				game.switchstage.mapno == NEW_GAME_FROM_MENU)
			{
				bool show_intro = (game.switchstage.mapno == NEW_GAME_FROM_MENU);
				InitNewGame(show_intro);
			}
			
			// slide weapon bar on first intro to Start Point
			if (game.switchstage.mapno == STAGE_START_POINT && \
				game.switchstage.eventonentry == 91)
			{
				freshstart = true;
			}
			
			// switch maps
			if (load_stage(game.switchstage.mapno)) goto ingame_error;
			
			player->x = (game.switchstage.playerx * TILE_W) << CSF;
			player->y = (game.switchstage.playery * TILE_H) << CSF;
		}
		
		// start the level
		if (game.initlevel()) return 1;
		
		if (freshstart)
			weapon_introslide();
		
		gameloop();
		game.stageboss.OnMapExit();
		freshstart = false;
	}
	
shutdown: ;
	Replay::close();
	game.close();
	Carets::close();
	
	Graphics::close();
	input_close();
	font_close();
	sound_close();
	tsc_close();
	textbox.Deinit();
#ifdef __native_client__
        pp::Instance(PSGetInstanceId()).PostMessage(pp::Var("quit"));
        while(1);
#endif
	return error;
	
ingame_error: ;
	stat("");
	stat(" ************************************************");
	stat(" * An in-game error occurred. Game shutting down.");
	stat(" ************************************************");
	error = true;
	goto shutdown;
}
Example #14
0
// PostUpdateMessage() helper function for sendimg small messages to JS.
void SimpleTemplate::PostUpdateMessage(const char* message_name, double value) {
  pp::VarDictionary message;
  message.Set("message", message_name);
  message.Set("value", value);
  PSInterfaceMessaging()->PostMessage(PSGetInstanceId(), message.pp_var());
}