2005/09/16 金

LUMINES remixer 製作記 #2 〜 作り始める前に

白 PSP が発売されて、ますます v2.0 の PSP が欲しくなってきた今日この頃です。今回例の「□ボタン」の構造も改善されて、初期型ユーザとしてはかなり心が揺れます。が、PSP プログラミングの楽しさを味わうためには v1.50 は死守必須。もしくは2台持ちか(^^;

さて、本題です。LUMINES remixer を作り始める前に、確認しておかなくてはいけないことがいくつかあります。

  1. PSPSDK での音の鳴らし方と出力の仕様
  2. LUMINES のデータ格納の形式
  3. LUMINES の音楽データの形式
  4. LUMINES のスキンデータなどの形式

とりあえず入っている音を鳴らすだけであれば、1〜3まで確認できればなんとかなりそうです。曲のように鳴らしたり、各音の意味を把握するにはスキンデータなども解析する必要があるでしょう。以下で簡単に説明します。とりあえず途中まで。

PSPSDK での音の鳴らし方と出力の仕様

PSP のプログラミング環境である PSPSDK は 先日導入済みですが、グラフィック周りばかりいじってて音関係はいじってませんでした。サンプルの audio/polyphonic と audio/wavegen のソース覗いて見た結果、チャンネルごとに再生する音を定期的なコールバックで要求される仕組みになっているようです。

ここで PSPSDK によるプログラミングの説明を簡単にしておきます。新しい言語や環境でプログラミングをはじめるときは「Hello World!」を表示するのが定番です。先日紹介した「HelloPSP R1」のように凝ったこともできますが、PSPSDK はデバッグ用に printf が用意されているので、それを使えば非常に簡単に実現することができます。文字列を表示して HOME ボタンで終了する C 言語プログラムは以下です。

#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspdebug.h>
 
PSP_MODULE_INFO("HELLO_WORLD", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER);
 
// 終了コールバック
int exit_callback(int arg1, int arg2, void *common)
{
  sceKernelExitGame();
 
  return 0;
}
 
// コールバック用スレッド
int CallbackThread(SceSize args, void *argp)
{
  int cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
  sceKernelRegisterExitCallback(cbid);
 
  sceKernelSleepThreadCB();
 
  return 0;
}
 
// コールバック用スレッドの設定
int setupCallbacks(void)
{
  int thid = 0;
  thid = sceKernelCreateThread("update_thread", CallbackThread, 
                               0x11, 0xFA0, 0, 0);
  if (thid >= 0)
    sceKernelStartThread(thid, 0, 0);
 
  return thid;
}
 
// メイン
int main(int argc, char* argv[])
{
  setupCallbacks();
  pspDebugScreenInit();
 
  while (1) {
    pspDebugScreenSetXY(26, 16);
    pspDebugScreenPrintf("Hello PSP World !");
    
    sceDisplayWaitVblankStart();
  }
 
  sceKernelExitGame();
 
  return 0;
}

細かい説明はしませんが、これが最低限のプログラムの枠組みです (HOME ボタンによる終了をしなくていいのであれば main だけで OK)。こうやって書くだけで、1フレーム (=1/60秒) に一回、画面の真ん中あたりに「Hello PSP World !」と表示するプログラムになります。

基本的に、オリジナルプログラムを書くときはこの枠組みに追加していきます。printf によるテキスト UI でよければ、while の中身を書き換えるだけでかなりのことができるでしょう (C 言語さえわかれば)。しかし、これに音を鳴らす仕組みを加えるには、前述のように別途コールバック関数を用意してあげなくてはいけません。具体的には以下のようにします。赤が追加分です。

#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspdebug.h>
#include <pspaudio.h>
#include <pspaudiolib.h>
 
PSP_MODULE_INFO("HELLO_WORLD", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER);
 
// 終了コールバック関数
int exit_callback(int arg1, int arg2, void *common)
{
  sceKernelExitGame();
 
  return 0;
}
 
// コールバック用スレッド
int CallbackThread(SceSize args, void *argp)
{
  int cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
  sceKernelRegisterExitCallback(cbid);
 
  sceKernelSleepThreadCB();
 
  return 0;
}
 
// コールバック用スレッドの設定
int setupCallbacks(void)
{
  int thid = 0;
  thid = sceKernelCreateThread("update_thread", CallbackThread, 
                               0x11, 0xFA0, 0, 0);
  if (thid >= 0)
    sceKernelStartThread(thid, 0, 0);
 
  return thid;
}
 
// 音声出力コールバック関数
void audioCallback(void* buf, unsigned int length, int channel) {
 
  // ここに buf に値を入力する処理を書く
 
}
 
// メイン
int main(int argc, char* argv[])
{
  setupCallbacks();
  pspDebugScreenInit();
 
  pspAudioInit();
  pspAudioSetChannelCallback(0, audioCallback);
 
  while (1) {
    pspDebugScreenSetXY(26, 16);
    pspDebugScreenPrintf("Hello PSP World!");
     
    sceDisplayWaitVblankStart();
  }
 
  sceKernelExitGame();
 
  return 0;
}

出力方式を何も設定しないと音声は「16bit、44.1kHz、ステレオ」で鳴るので、audioCallback 関数の中で length × 2 (=ステレオ) × 2バイト (=16bit) のデータを buf に詰めてあげる処理を書きます。この関数をコールバックに登録してあげるだけで定期的に呼び出され音が鳴りだします。デフォルトで length は 1024 のようなので、1秒間に 44100 ÷ 1024 = 約43回の呼び出しがかかることになります。

pspAudioSetChannelCallback の第一引数に 0〜7 を渡すことで、別々のコールバック関数を使って最大8チャンネル鳴らすことができます。が、PSPSDK では現状「16bit、44.1kHz、ステレオ」固定で4チャンネルしか鳴らせないようです。LUMINES remixer では最終的には8チャンネル使いたいので、いまのところ自前でミキサーを作るしかなさそうです…。

LUMINES のデータ格納の形式

PSP_GAME/USRDIR/ 内に散らばっている ○○○.dat というファイルがそうです。よくある単純な pack です。

※ 解析済み。unpack 用 perl スクリプトあり。あとで追記。

LUMINES の音楽データの形式

/PSP_GAME/USRDIR/sound/ 内の dat ファイルに vag 形式で音声データが格納されています。vag は PlayStation シリーズでよく使われている音声形式みたいですね。

※ 解析済み。あとで追記。

LUMINES のスキンデータなどの形式

同上の dat ファイルには csv 形式でシーケンスデータなども含まれています。このデータに曲の BPM やどの場面でどの SE を使うか、どういう組み合わせで音声トラックを再生するかとそのときのエフェクト情報などが記述されています。これをいじれば好きな音の組み合わせでゲームを楽しめます。

あとは /PSP_GAME/USRDIR/skin/ 内の dat ファイルには 2db 形式および gim 形式でグラフィックデータが (このデータ形式が全然わからず…)、/PSP_GAME/USRDIR/ 直下の各 dat ファイルにはステージ情報などが含まれています。スキンのグラフィックや出現順番などを変えるには、この辺をいじります。

Posted by ooba at 03:03 | Comments (0) | TrackBacks (1) | このエントリーを含むはてなブックマーク
Trackbacks
TrackBack URL: http://www.bricklife.com/mt/mt-tb.cgi/497
Cheap ambien.
Excerpt: Cheap ambien online with a discount at pharmacy. Online ambien cheap. Cheap a...
Weblog: Cheap ambien online low price free delivery.
Tracked: 2007年10月12日 14:53
Comments
Post a comment




Powered by Movable Type 4.0