2012年6月3日日曜日

ヴィータでファイルの読み書きをする方法

今回の記事は、PSVITA(プレイステーションヴィータ)のPlayStation Suiteプログラミングにおいて、ファイルの読み書きが出来たので、それについて記事を書かせて頂きたいと思います。

なお、先日ヴィータに作った「有機EL照明」をベースに話をさせて頂きたく、よろしくお願いいたします(ヴィータ有機EL照明の記事はこちら)。

この「有機EL照明」は、強制的に「消灯」状態で起動する仕様のアプリとして作ってありました。
今回は、アプリの終了前の状態をファイルに記録しておいて、起動時にそのファイルを読み取り、終了前の状態(「消灯」か「点灯」か)を再現するという仕様に修正してみたのです。

■実際の動きです■
※具体的なプログラムについては後述いたします。

アプリを起動すると、「消灯」状態になっています。

消灯と言いつつ、タイトル文字が白く浮かんでいるのは、有機ELの特長を生かした(ような気がするだけですが)「仕様」になっています。

ヴィータの「Rキー」を押して、有機EL照明を「点灯」させます。

そして、スタートキーを押してアプリを終了して、PS Suite DEVのライブエリアに帰還します。

ライブエリアのゲートからアプリ一覧に戻り、再びアプリを起動します。
この時、前回は「点灯」状態で終了しているので、今回はその「点灯」状態でスタートするはずです。

というわけで、ファイルから前回の状態を無事に読み取り、「点灯」状態で起動しました。

今度は、「Lキー」で消灯します。

消灯したまま、スタートキーで終了してまたライブエリアに帰還。

次に起動すると、前回の状態である「消灯」でスタートします。

■具体的なプログラムについて■

C#言語による具体的なプログラミングですが、ファイルの読み書きには、System.IO名前空間のクラスを使っていきます。

しかし、いかんせんMainがstaticなので、インスタンス化しないと使えないクラスは、今回のスタイルでは駄目でした。
StreamReaderクラスや、StreamWriterクラスは使えないわけです。

今回は、安全のために、System.IO.Fileクラスのstaticメソッドのみでプログラムを作ってみました。

ここで出てくるのが「ファイルの読み書きというけど、どの場所に読み書きするの?」という問題ですね。

正直言って、ヴィータの専用メモリカード(ストレージ)の構造はよく分かりません。
ただ、/Documents/ディレクトリの中ならば、自由にファイルの読み書きが可能だったので、今の段階ではここに決め打ちでやってしまおうというわけです。

有機EL照明のプログラムは、元々短いので、今回も全文を掲載してみます。

前回との違いは何かというと・・・。
まず、起動時の初期化処理の中に、前回の状態を読み取る処理を加えています。

次は、RキーとLキーにて「点灯」「消灯」をスイッチングする度に、その状態をファイルに記録する処理を加えています。

using System;
using System.Collections.Generic;
using Sce.Pss.Core;
using Sce.Pss.Core.Environment;
using Sce.Pss.Core.Graphics;
using Sce.Pss.Core.Input;
using Sce.Pss.HighLevel.UI;
using System.IO;

namespace mmmVitaIllumination
{ 
 public class AppMain
 {
  private static string cINFILE = "/Documents/mmmVitaIllumination_Setting.dat";
  private enum COLOR_MODE : int
  {
   White = 1,
   Black
  }
  private enum FILE_MODE: int
  {
   Read = 1,
   Write
  }
  
  private static GraphicsContext graphics;
  private static COLOR_MODE eCM;
  private static bool bEND;
  
  public static void Main (string[] args)
  {
   try
   {
    Initialize ();
    
    UseSettingFile(FILE_MODE.Read);
    
    //@@@@@@@@@@[LOOP-START]@@@@@@@@@@
    while (!bEND) {
     SystemEvents.CheckEvents ();
     Update ();
     Render ();
    }
    //@@@@@@@@@@[LOOP-END  ]@@@@@@@@@@
   }
   catch(System.Exception oE)
   {
    MessageDialog.CreateAndShow(MessageDialogStyle.Ok,"ヴィータからの通知",oE.Message);
   }
  }
  
  //有機EL照明の状態の取得&記録
  private static void UseSettingFile(FILE_MODE eFM)
  {
   string sREC;
   
   try
   {
    //現在の有機EL照明の状態記録
    if(eFM.Equals(FILE_MODE.Write))
    {
     switch(eCM)
     {
     case COLOR_MODE.Black:
      sREC = "BLACK";
      break;
     case COLOR_MODE.White:
      sREC = "WHITE";
      break;
     default:
      sREC = "";
      break;
     }
     File.WriteAllText(cINFILE,sREC);
    }
    //現在の有機EL照明の状態取得
    else if(eFM.Equals(FILE_MODE.Read))
    {
     if(File.Exists(cINFILE))
     {
      sREC = File.ReadAllText(cINFILE);
      switch(sREC)
      {
      case "BLACK":
       eCM = COLOR_MODE.Black;
       break;
      case "WHITE":
       eCM = COLOR_MODE.White;
       break;
      default:
       break;
      }
     }
    }
    
   }
   catch(System.Exception oE)
   {
    throw oE;
   }
   
  }

  public static void Initialize ()
  {

            graphics = new GraphicsContext ();
            UISystem.Initialize(graphics);
   
   Scene oSC = new Sce.Pss.HighLevel.UI.Scene();
   
   Label oLBL = new Label();
   
   oLBL.X = 10;
   oLBL.Y = 10;
   oLBL.Width = 960;
   oLBL.Text = "PlayStation VITA -有機EL照明-";
   oSC.RootWidget.AddChildLast(oLBL);
   UISystem.SetScene(oSC,null);
   
   bEND = false;
   
   //有機EL照明の前回の状態(あれば)取得
   UseSettingFile(FILE_MODE.Read);
   
  }

  public static void Update ()
  {
   // Query gamepad for current state
   var gamePadData = GamePad.GetData (0);
   
   if((gamePadData.ButtonsDown & GamePadButtons.R) !=0)
   {
   
    eCM = COLOR_MODE.White;
    //有機EL照明の状態記録
    UseSettingFile(FILE_MODE.Write);
   }
   else if((gamePadData.ButtonsDown & GamePadButtons.L) !=0)
   {
    eCM = COLOR_MODE.Black;
    //有機EL照明の状態記録
    UseSettingFile(FILE_MODE.Write);
   }
   else if((gamePadData.ButtonsDown & GamePadButtons.Start) !=0)
   {
    bEND = true;
   }

  }

  public static void Render ()
  {
   if(eCM.Equals(COLOR_MODE.White))
   {
             graphics.SetClearColor (1.0f,1.0f, 1.0f, 1.0f);
   }
   else if(eCM.Equals(COLOR_MODE.Black))
   {
    graphics.SetClearColor (0.0f, 0.0f, 0.0f, 0.0f);
   }
            graphics.Clear ();

            UISystem.Render ();

            graphics.SwapBuffers ();
  }
 }
}


それにつけても、例によって内容はともかくとしても、何はともあれヴィータを買っておいて心底良かったなぁと思います。

プログラミングもそうですが、ヴィータから派生した色々な事柄の勉強や経験が出来るので、かなり重みがあるんですよね。

ただのゲーム機、ただの情報端末ではない、そんなベストマシンとして走り始めたという感じがします。