新年二日になったので、初詣でに行ってきました。江戸総鎮守の神田明神です。
もう鳥居をくぐる前から人でごった返してたよ。手水場でも並んで御社殿に行くのにも並んだけど、何とかお参り出来ました。さらにおみくじにも並んで、巫女さんから手渡されたくじを見てみたら末吉でした。まぁこんなもんか。
とにかく人が多かったので、あんまり堪能せずに出てきたよ。人が引いた頃にまた来てみよう。お守りも買ってないし。
龍が如く見参! をクリアしました。プレイ時間は50時間ほどです。
以下ネタバレ
---
今作はいわゆる武蔵と小次郎のお話なんだけど、初っ端の隠密行動から裏切り、逃走劇など先の見えない展開でぐいぐい引き込まれたよ。まぁ祇園に来てからは今まで通りのお遣いシステムになったけどw
PS3になったお陰で、とにかくグラフィックが綺麗です。しかも360度見渡せます。人の顔は声を当ててる俳優の顔そのまんまだったりして、なかなかリアルです。ただ一般人が総じて不細工すぎる。わざとかなぁ。
本編とは関係ないサブイベントが大量にあるけど、前作までとは違い、HDDにインストールすればストレス無くプレイできるし、マップも細かく表示されるんでやり易かったです。しかもそれぞれのサブイベントもよく作り込んであって面白かったです。やり残したのもたくさんあるけどね。
アクションについては大量の技を習得したけど、あんまり使いこなしてなかったな。ついでに言うと武器が作れるんだけど、製法書が見づらくてあんまり作らなかったよ。
とにかく自由度が高いので、攻略法を見ないと完全制覇は無理かも…ミニゲームもほとんどやってないし。
ただ残念だったのはラスト。唐突に吉野太夫を身請けして夫婦となった武蔵は、吉野に何も言わずに遥を助けに巌流島に行ってしまう。
そこで因縁の佐々木小次郎を倒し、ついでに黒幕の南海坊天海も倒したけど、敵の軍勢が迫ってきたので幼女に「好きだー」と告白して敵陣に突っ込んで死亡。
なんか生き残ってた小次郎や真島さんが大坂夏の陣を挑みながら武蔵を思い出す、みたいなエンディングでした。なにこれバッドエンド?
そんな感じで、最後が俺的に残念でしたが、全体的に面白かったです。
次回は、そのうち龍が如く3をやる予定ですが、まずはコール オブ デューティ4やろうかな。
朝8:30くらいに会場に到着。今回は矢絣の風呂敷をテーブルに敷きました。後は簡単な説明の紙を立て掛け、作品を並べてディスプレイ完了。
カイロを2つも装備したのに会場内は物凄く寒く、また徹夜明けで眠かったので、なかなか過酷な感じでした(汗) まあ時間が経つにつれて暖かくはなったけどね。
今回は場所が良かったのか、結構人の流れが多い気がしたな。お陰で手に取ってくれる人や話しかけてくれる人もいつもより多かったよ。そういえば巫女装束の女性が「別に巫女なんて興味ないんだからねっ」と言ってウチの作品を買っていってくれましたw
会場でも説明しましたが今回のはまだ未完成品で、しかもバグが残ってます。ギリギリまで粘ったんだけどバグ取れなかったよ。そのうちちゃんと出来たらサイトに差分をアップします。
そんな訳で、来てくれた皆さんありがとうございました。
今日は秋葉原で飲みました。
秋葉原で飲むのは久しぶりな気がする。クジラ料理が幾つかあったので注文しようとしたら「くじらベーコンしかありません」って言われたよ。まぁ仕方ない。
飲みながらビジネスの話とかしたり。請け仕事は単価が下がる一方だから、やっぱり独立系のビジネス立ち上げなきゃなぁとかそんな。
今年の飲み会はこれで最後かなぁ。
今日は取引先の忘年会に参加しました。
飲み屋に行く途中メチャクチャ混んでました。休日前で忘年会シーズンだからなぁ。店の中も順番待ちの人達で溢れかえってたよ。みんな大変だ。
内容はコースメニューのすき焼きでした。すき焼きも久しぶりだなぁ。ただ残念ながら、人数の割に量は少なかった。
帰り。なんかホームで男に声を掛けられたよ。ほろ酔いなその男、雑談を交わしつつも「株に興味ない?」と聞いてくる。胡散臭ぇ(笑) でもいちおうメアド教えといたw どんな素性の男やら。
しかし帰りは終電だったんでこれまた混んでたよ。疲れた。
続きです。今回はWaveファイルを読み込んで解析する処理です。
mmioというマルチメディア入出力関数があるので、それを使って解析すればOKです。
前回のCAudioBaseクラスと今回のCAudioWaveクラスの上にCAudioクラスという緩衝材を入れてますが、ほとんどCAudioBaseと同じなので省略します。
これでようやく音が鳴るようになりました。次はまた当たり判定かなぁ。いい加減当たり判定もFIXしたいところ。
//----------------------------------------------------------------------------- // 生成 CAudioWave::CAudioWave() { m_pwfx=NULL; m_hmmio=NULL; m_pResourceBuffer=NULL; m_dwSize=0; } //----------------------------------------------------------------------------- // 解放 CAudioWave::~CAudioWave() { Close(); SAFE_DELETE_ARRAY(m_pwfx); } //----------------------------------------------------------------------------- // オープン HRESULT CAudioWave::Open(LPSTR strFileName, WAVEFORMATEX* pwfx) { HRESULT hr; if (strFileName==NULL) { return FALSE; } SAFE_DELETE_ARRAY(m_pwfx); // ファイルオープン m_hmmio=mmioOpen(strFileName, NULL, MMIO_ALLOCBUF | MMIO_READ); if (FAILED(hr=ReadMMIO())) { mmioClose(m_hmmio, 0); return FALSE; } if (FAILED(ResetFile())) { return FALSE; } // ファイルサイズ保持 m_dwSize=m_ck.cksize; return TRUE; } //----------------------------------------------------------------------------- // マルチメディア関数で読み込み HRESULT CAudioWave::ReadMMIO() { MMCKINFO ckIn; PCMWAVEFORMAT pcmWaveFormat; m_pwfx=NULL; if ((0!=mmioDescend(m_hmmio, &m_ckRiff, NULL, 0))) { return E_FAIL; } // Waveファイルかどうか if ((m_ckRiff.ckid!=FOURCC_RIFF) || (m_ckRiff.fccType!=mmioFOURCC('W', 'A', 'V', 'E'))) { return E_FAIL; } // FMTチャンク検索 ckIn.ckid=mmioFOURCC('f', 'm', 't', ' '); if (0!=mmioDescend(m_hmmio, &ckIn, &m_ckRiff, MMIO_FINDCHUNK)) { return E_FAIL; } // pcmWaveFormat取得 if (mmioRead(m_hmmio, (HPSTR)&pcmWaveFormat, sizeof(pcmWaveFormat))!=sizeof(pcmWaveFormat)) { return E_FAIL; } // 余分なBYTEがある? if (pcmWaveFormat.wf.wFormatTag==WAVE_FORMAT_PCM) { m_pwfx=(WAVEFORMATEX*)new CHAR[sizeof(WAVEFORMATEX)]; if (NULL==m_pwfx) { return E_FAIL; } // waveformatexコピー memcpy(m_pwfx, &pcmWaveFormat, sizeof(pcmWaveFormat)); m_pwfx->cbSize=0; } else { // 余分なBYTE読み込み WORD cbExtraBytes=0L; if (mmioRead(m_hmmio, (CHAR*)&cbExtraBytes, sizeof(WORD))!=sizeof(WORD)) { return E_FAIL; } m_pwfx=(WAVEFORMATEX*)new CHAR[sizeof(WAVEFORMATEX)+cbExtraBytes]; if (NULL==m_pwfx) { return E_FAIL; } // waveformatexコピー memcpy(m_pwfx, &pcmWaveFormat, sizeof(pcmWaveFormat)); m_pwfx->cbSize=cbExtraBytes; // 余分なBYTE読み込み if (mmioRead(m_hmmio, (CHAR*)(((BYTE*)&(m_pwfx->cbSize))+sizeof(WORD)), cbExtraBytes )!=cbExtraBytes) { SAFE_DELETE(m_pwfx); return E_FAIL; } } // FMTチャンクから出る if (0!=mmioAscend(m_hmmio, &ckIn, 0)) { SAFE_DELETE(m_pwfx); return E_FAIL; } return S_OK; } //----------------------------------------------------------------------------- // サイズ取得 DWORD CAudioWave::GetSize() { return m_dwSize; } //----------------------------------------------------------------------------- // ファイルリセット HRESULT CAudioWave::ResetFile() { if (m_hmmio==NULL) { return CO_E_NOTINITIALIZED; } // データ検索 if (-1==mmioSeek(m_hmmio, m_ckRiff.dwDataOffset+sizeof(FOURCC), SEEK_SET)) { return E_FAIL; } // データチャンク検索 m_ck.ckid=mmioFOURCC('d', 'a', 't', 'a'); if (0!=mmioDescend(m_hmmio, &m_ck, &m_ckRiff, MMIO_FINDCHUNK)) { return E_FAIL; } return S_OK; } //----------------------------------------------------------------------------- // ファイルから読み込み HRESULT CAudioWave::Read(BYTE* pBuffer, DWORD dwSizeToRead, DWORD* pdwSizeRead) { MMIOINFO mmioinfoIn; if (m_hmmio==NULL) { return CO_E_NOTINITIALIZED; } if (pBuffer==NULL || pdwSizeRead==NULL) { return E_INVALIDARG; } *pdwSizeRead=0; if (0!=mmioGetInfo(m_hmmio, &mmioinfoIn, 0)) { return E_FAIL; } UINT cbDataIn=dwSizeToRead; if (cbDataIn>m_ck.cksize) { cbDataIn=m_ck.cksize; } m_ck.cksize-=cbDataIn; for (DWORD cT=0; cT<cbDataIn; cT++) { // BYTEコピー if (mmioinfoIn.pchNext==mmioinfoIn.pchEndRead) { if (0!=mmioAdvance(m_hmmio, &mmioinfoIn, MMIO_READ)) { return E_FAIL; } if (mmioinfoIn.pchNext==mmioinfoIn.pchEndRead) { return E_FAIL; } } // コピー *((BYTE*)pBuffer+cT)=*((BYTE*)mmioinfoIn.pchNext); mmioinfoIn.pchNext++; } if (0!=mmioSetInfo(m_hmmio, &mmioinfoIn, 0)) { return E_FAIL; } *pdwSizeRead=cbDataIn; return S_OK; } //----------------------------------------------------------------------------- // ファイルを閉じる HRESULT CAudioWave::Close() { mmioClose(m_hmmio, 0); m_hmmio=NULL; SAFE_DELETE_ARRAY(m_pResourceBuffer); return S_OK; }
前にXACT3でWaveを再生する処理を書きましたが、いちいちWaveファイルを固めるのはメンドくさい。
てな訳で、改めてXAudio2でWaveを再生することにしました。まぁサンプルにそのものずばりな物があるので(XAudio2BasicSound)、それを元にゲームで使える様な物に作り替えます。
基本的な処理の流れは、COMを初期化してXAudio2を使えるようにする。マスターボイスを作ってその中にWaveから取り出したソースボイスを入れる。再生。といった感じです。
今回はXAudio2の部分CAudioBaseクラスだけ記述しました。Waveファイルからデータを取り出す処理は次回。
//-------------------------------------------------------------------------------------- // 生成 CAudioBase::CAudioBase() { for (int i=0; i<MAX_SOUND; i++) { pSourceVoice[i]=NULL; pXAudioBuffer[i]=NULL; pbWaveData[i]=NULL; } pXAudio2=NULL; pMasteringVoice=NULL; } //----------------------------------------------------------------------------- // 解放 CAudioBase::~CAudioBase() { Release(); // マスターボイス解放 if (pMasteringVoice!=NULL) { pMasteringVoice->DestroyVoice(); pMasteringVoice=NULL; } // XAudio解放 SAFE_RELEASE(pXAudio2); // COM解放 CoUninitialize(); } //-------------------------------------------------------------------------------------- // 初期化 BOOL CAudioBase::Init() { // COM初期化 CoInitializeEx(NULL, COINIT_MULTITHREADED); // デバッグモードの場合 UINT32 flags=0; #ifdef _DEBUG flags|=XAUDIO2_DEBUG_ENGINE; #endif // XAudio2生成 if (FAILED(XAudio2Create(&pXAudio2, flags))) { CoUninitialize(); return E_FAIL; } // マスターボイス生成 if (FAILED(pXAudio2->CreateMasteringVoice(&pMasteringVoice))) { SAFE_RELEASE(pXAudio2); CoUninitialize(); return E_FAIL; } return S_OK; } //----------------------------------------------------------------------------- // 解放 void CAudioBase::Release() { // ソースボイス解放 for (int i=0; i<MAX_SOUND; i++) { ReleaseSound(i); } } //----------------------------------------------------------------------------- // サウンド解放 void CAudioBase::ReleaseSound(int no) { if (pbWaveData[no]!=NULL) { SAFE_DELETE(pbWaveData[no]); } if (pXAudioBuffer[no]!=NULL) { SAFE_DELETE(pXAudioBuffer[no]); } if (pSourceVoice[no]!=NULL) { pSourceVoice[no]->DestroyVoice(); pSourceVoice[no]=NULL; } } //-------------------------------------------------------------------------------------- // ファイル読み込み int CAudioBase::LoadSound(LPSTR szFilename, int loop_flag) { int i; // 空いているWaveがあるか検索 for (i=0; i<MAX_SOUND; i++) { if (pSourceVoice[i]==NULL) { break; } } if (i>=MAX_SOUND) { return -1; } // Waveファイル読み込み CAudioWave wav; if (FAILED(wav.Open(szFilename, NULL))) { return -1; } // Waveファイルのフォーマット取得 WAVEFORMATEX* pwfx=wav.GetFormat(); // サイズ計算 DWORD cbWaveSize=wav.GetSize(); // メモリにデータを乗せる pbWaveData[i]=new BYTE[cbWaveSize]; if (FAILED(wav.Read(pbWaveData[i], cbWaveSize, &cbWaveSize))) { SAFE_DELETE_ARRAY(pbWaveData[i]); return -1; } // ソースボイス生成 if (FAILED(pXAudio2->CreateSourceVoice(&pSourceVoice[i], pwfx))) { SAFE_DELETE_ARRAY(pbWaveData[i]); return -1; } if (loop_flag!=0) { loop_flag=XAUDIO2_LOOP_INFINITE; } // オーディオバッファ設定 pXAudioBuffer[i]=new XAUDIO2_BUFFER; pXAudioBuffer[i]->Flags=XAUDIO2_END_OF_STREAM; pXAudioBuffer[i]->AudioBytes=cbWaveSize; pXAudioBuffer[i]->pAudioData=pbWaveData[i]; pXAudioBuffer[i]->PlayBegin=0; pXAudioBuffer[i]->PlayLength=0; pXAudioBuffer[i]->LoopBegin=0; pXAudioBuffer[i]->LoopLength=0; pXAudioBuffer[i]->LoopCount=loop_flag; if (FAILED(pSourceVoice[i]->SubmitSourceBuffer(pXAudioBuffer[i]))) { pSourceVoice[i]->DestroyVoice(); SAFE_DELETE_ARRAY(pbWaveData[i]); return -1; } return i; } //-------------------------------------------------------------------------------------- // サウンド再生 void CAudioBase::PlaySound(int no) { if (no==-1 || pSourceVoice[no]==NULL) { return; } StopSound(no); pSourceVoice[no]->FlushSourceBuffers(); pSourceVoice[no]->SubmitSourceBuffer(pXAudioBuffer[no]); HRESULT hr=pSourceVoice[no]->Start(0); } //-------------------------------------------------------------------------------------- // サウンド停止 void CAudioBase::StopSound(int no) { if (no==-1 || pSourceVoice[no]==NULL) { return; } pSourceVoice[no]->Stop(0); }
Thunderbirdがバージョン3.0になりました。見たらIMAPの高速化とかGmailとの連携強化とか書かれてたので、利用してみる事にしました。
ちなみにIMAPが何なのかはよくわかってませんw POPと違い、サーバー上のメールを直接操作出来るって事でいいのかな?
ThunderbirdでGmailのアカウントを設定すると、自動でIMAPのサーバに接続します。しかしGmailには16000通くらいメールがあったので、ダウンロード完了するまで30分くらいかかったよ。
で、未読既読がごちゃごちゃしてたので、全部既読にしようと全選択してから既読を選んだら…なんか完了するまで2時間くらいかかったよ(汗)
これは最初だけなのかな。その後は受信トレイとかクリックすると微妙に固まるけど、まぁ問題ないレベルでした。
Thunderbirdでメール送信したらGmailの送信済みメールに入るし、既読やアーカイブを指定したらそれも反映されるし、良いね。今まではいちいちGmailサイトに行ってやってたからなぁ。
複数のPCで全く同じ環境になるのは良いです。二重ダウンロードとか未読のまま忘れてしまうなんて事がなくなるし。
ただ、いちいちサーバに見に行ってるため、やっぱり重いのは気になるかな。
とにかくしばらく使ってみよう。
※機能を見直してたら「○日分のメッセージをローカルに同期する」って設定があるね。これで最近のだけ受け取れば良かったのか。
※これも後から知ったけど、Shift+Cで一括で既読にできます。ちゃんとマニュアル読まないとダメだね。
夕方くらいからスポーツクラブ。
しかし10分間走っても170kcalくらいしか消費しないんだよなぁ。ポテトチップス1袋食べたら400kcalとかいくし、なかなか大変だね。
そういえばもう筋肉痛にはならなくなったな。多少は鍛えられたかな。