/*	
 *	ssbpLib.h
 *
 *	ssbpLibサポートモジュール
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2016-2017 Naoyuki Sawa
 *
 *	* Wed Apr 13 23:37:13 JST 2016 Naoyuki Sawa
 *	- 1st リリース
 *	  「ssbpLib」(https://github.com/SpriteStudio/ssbpLib/wiki)を、VC++6.0のCソースから使用するためのヘルパーDLLです。
 *	  VC++6.0ではC++対応が古過ぎてssbpLibのソースがコンパイル出来なかったので、VC++2015 update2でコンパイルしました。
 *	  作成したDLLは、VC++6.0からでも利用出来ます。
 *	- 自分で作成したファイルは、ssbpLib.h,ssbpLib.cppだけです。
 *	  ssbpLibフォルダ以下には、オリジナル版(https://github.com/SpriteStudio/ssbpLib/archive/1.2.3_SS5.6.1.zip)の、"ssbpLib-1.2.3_SS5.6.1/Players/ssbpLib/"フォルダ以下のファイルをそのまま入れてあります。
 *	  ただし、元ファイルは[UTF-8][LF]だったので、[SHIFT-JIS][CR+LF]に変換しました。文字コードを変換した事以外は、一切手を加えていません。
 *	  一部、関数の引数型でconstが不足していたり、気になる点は有ったのですが、致命的な問題は無いので敢えて手を加えずに、自分で実装したssbpLib.h,ssbpLib.cppの中で吸収しました。
 *	- ssbpLibフォルダ以下のモジュールのビルドでは、たくさんの警告が出ますが、元ソースには一切手を加えない方針なので、そのままとしました。
 *	  ssbpLib.cppのビルド時のみ、"ssbpLib/SS5PlayerPlatform.h"のインクルード内でなるべく警告が出ないように、プラグマで警告を抑制しました。
 *	- ssbpLib.cppの関数仕様は、基本的には、SS5Player.cppのメンバ関数の仕様をそのままに、C言語に変換したものです。
 *	  ただし、C言語で使えるようにするために、bool型の引数や戻り値は、int型に置き換えました。
 *	  また、アプリケーションの利便性のために、float型の引数や戻り値は、double型に置き換えました。float型は何かと使い辛いと思ったからです。
 *	- オリジナル版のライブラリを、keep/ssbpLib-1.2.3_SS5.6.1.zip に保存しておきました。
 *	* Fri Apr 15 21:07:28 JST 2016 Naoyuki Sawa
 *	- エラー処理を追加しました。
 *	  これまで、ssbpLibフォルダ以下の元ソースには一切手を加えない方針でしたが、止むを得ない理由によって、少しだけ手を加える事にしました。
 *	  止むを得ない理由とは、元ソースはエラー処理が十分でなく、ランタイムエラーが発生した時に原因が(あまりにも)わかりづらかったからです。
 *	  例えば、ResourceManager::addData()に、存在しないファイル名を指定した場合、リリースビルドでは一般保護例外で落ちてしまっていました。
 *	  そうなっていた理由は、エラーチェックがSS_ASSERT(),及び,SS_ASSERT2()だけで行われており、リリースビルドではどちらのマクロも無効化されるので、実質、エラーチェック無しになるからです。
 *	  ロジックエラーならばそれでもまあ良いのですが、リソースにかかわるエラー等はリリースビルドでも報告して欲しいので、以下の変更を行う事にしました。
 *	- SS_ASSERT()やSS_ASSERT2()等のエラーチェックマクロを、デバッグビルドでもリリースビルドでも有効にし、自前のエラー報告関数を呼び出すようにしました。
 *	  具体的には、fn_GetAddressの仕組みを利用して、アプリケーション側のvsyslogとvdieを呼び出すようにしました。
 *	  これらの関数が呼び出された時にどう処理するかは、アプリケーション次第です。
 *	  単純にvsyslogやvdieに引き渡す事も出来ますし、vdieの処理をダイアログを表示して停止するようにする事も出来ます。
 *	- 今回、ssbpLibフォルダ以下の元ソースを変更した箇所は、下記の二点だけです。
 *	  ・ssbpLib/SS5Player.h		'//{{2016/04/15'〜'//}}2016/04/15'で囲った部分 (二か所)
 *	  ・ssbpLib/SS5PlayerTypes.h	'//{{2016/04/15'〜'//}}2016/04/15'で囲った部分 (二か所)
 *	  二か所とも、変更内容は同じです。
 *	  何故かSS_ASSERT()やSS_ASSERT2()等のエラーチェックマクロが、全く同じ内容で二か所で定義されていたので、二か所とも同様に変更しました。
 *	- 上記の変更を行っていて、上記の二か所以外に、元ソースがSS_ASSERT()の使い方を間違っている箇所に気づきました。
 *	  ・ssbpLib\SS5Player.cpp  414行〜	＞SS_ASSERT(data != NULL, "Invalid data");
 *	  ・ssbpLib\SS5Player.cpp 1195行〜	＞SS_ASSERT(animeRef != NULL, msg.c_str());
 *	  正しくはSS_ASSERT2()を使うべきところ、間違ってSS_ASSERT()を使っており、エラーメッセージが出力されません。
 *	  マクロに対する引数不足ですが、VC++2015ではコンパイルエラーではなく警告止まりであり、ビルドは完了するようです。
 *	  上記の箇所も修正すべきかどうか悩んだのですが、そのままにしておく事にしました。
 *	  このままでも、ファイル名と行番号と条件式はエラーメッセージに出力されますので、エラー箇所の特定は出来るからです。
 *	- 今回の変更だけで、全てのエラーがvdie()に報告されるようになった訳では有りません。
 *	  例えば、Player::play()に対して、存在しないアニメーション名を指定すると、ssbpLib/SS5Player.cppの879行〜の
 *	  ＞AnimeRef* ref = _dic.at(animeName);
 *	  の処理の中でstd::out_of_range例外が投入され、捕捉されない例外となってアプリケーションが終了してしまいます。
 *	  これらにも対処するには、ssbpLib_Player_play()で例外を補足してvdie()に報告すれば良いのですが、ssbpLib_Player_play()だけでなく全ての関数でも対応するとなると少々手間がかかりそうです。
 *	  ひとまずこの対応は行わずに、しばらく様子を見てから、行うべきかどうか検討しようと思っています。
 *	* Fri Apr 15 23:25:13 JST 2016 Naoyuki Sawa
 *	- 上記で検討事項を、実施する事にしました。
 *	  少し使ってみたところ、やっぱり、捕捉されない例外となってアプリケーションが終了してしまうと、デバッグしづらいと思ったからです。
 *	  ssbpLib.cppモジュール内の、ssbpLibの各クラスのメンバ関数を呼び出している関数に、例外を補足してエラーとして報告する処理を追加しました。
 *	* Sun Apr 09 22:05:18 JST 2017 Naoyuki Sawa
 *	- コンパイラを、VS2015⇒VS2017に更新しました。
 *	  VS2017でソリューションを開くと自動変換が起動し、デフォルト設定のままで自動変換して、リビルドすると問題無くビルド出来ました。
 *	  引き続き使用しながら、検証しようと思います。
 *	* Tue Apr 18 21:46:46 JST 2017 Naoyuki Sawa
 *	- Visual Studio 2017をバージョンアップした事に伴い、当モジュールもリビルドしました。
 *	  当モジュールのソースコードには変更有りません。
 *	- 使用したコンパイラは、以下の通りです。
 *	  │Microsoft Visual Studio Community 2017 Version 15.1 (26403.7) Release	←バージョンアップ
 */
#ifndef __SSBPLIB_H__
#define __SSBPLIB_H__
#ifdef  __cplusplus
extern "C" {
#endif//__cplusplus
/*****************************************************************************
 *	
 *****************************************************************************/
#ifdef  SSBPLIB_BUILD
  #define SSBPLIB_DLLAPI __declspec (dllexport)
  typedef                 ResourceManager ssbpLib_ResourceManager;
//typedef                 ProjectData     ssbpLib_ProjectData;
//typedef                 ResourceSet     ssbpLib_ResourceSet;
  typedef                 Player          ssbpLib_Player;
//typedef                 ResluteState    ssbpLib_ResluteState;
//typedef                 Instance        ssbpLib_Instance;
//typedef                 CustomSprite    ssbpLib_CustomSprite;
#else //SSBPLIB_BUILD
  #define SSBPLIB_DLLAPI __declspec (dllimport)
  typedef struct _ssbpLib_ResourceManager ssbpLib_ResourceManager;
//typedef struct _ssbpLib_ProjectData     ssbpLib_ProjectData;
//typedef struct _ssbpLib_ResourceSet     ssbpLib_ResourceSet;
  typedef struct _ssbpLib_Player          ssbpLib_Player;
//typedef struct _ssbpLib_ResluteState    ssbpLib_ResluteState;
//typedef struct _ssbpLib_Instance        ssbpLib_Instance;
//typedef struct _ssbpLib_CustomSprite    ssbpLib_CustomSprite;
  #pragma comment(lib, "ssbpLib.lib")
#endif//SSBPLIB_BUILD
/*****************************************************************************
 *	
 *****************************************************************************/
SSBPLIB_DLLAPI void ssbpLib_Init(void* (*_fnGetAddress)(const char* pName));
/*****************************************************************************
 *	ResourceManager
 *****************************************************************************/
SSBPLIB_DLLAPI /*static*/ ssbpLib_ResourceManager* ssbpLib_ResourceManager_getInstance();
SSBPLIB_DLLAPI /*static*/ ssbpLib_ResourceManager* ssbpLib_ResourceManager_create();
SSBPLIB_DLLAPI void ssbpLib_ResourceManager_delete(ssbpLib_ResourceManager* obj);
/*---------------------------------------------------------------------------*/
SSBPLIB_DLLAPI void ssbpLib_ResourceManager_addData(ssbpLib_ResourceManager* obj, const char* ssbpFilepath, const char* imageBaseDir/*NULL可*/);				//戻り値は仕様上自明なので省略する事にした。もし戻り値を対応すると文字列の動的割り当てや呼び出し側での解放が必要になり使いづらくなってしまう。
SSBPLIB_DLLAPI void ssbpLib_ResourceManager_addDataWithKey(ssbpLib_ResourceManager* obj, const char* dataKey, const char* ssbpFilepath, const char* imageBaseDir/*NULL可*/);	//戻り値は仕様上自明なので省略する事にした。もし戻り値を対応すると文字列の動的割り当てや呼び出し側での解放が必要になり使いづらくなってしまう。
//SSBPLIB_DLLAPI void ssbpLib_ResourceManager_addData(ssbpLib_ResourceManager* obj, const char* dataKey, const ssbpLib_ProjectData* data, const char* imageBaseDir/*NULL可*/);	//戻り値は仕様上自明なので省略する事にした。もし戻り値を対応すると文字列の動的割り当てや呼び出し側での解放が必要になり使いづらくなってしまう。	//Cリンケージではオーバーロード出来ない。こちらのバージョンは使わないと思うので削除した。
SSBPLIB_DLLAPI void ssbpLib_ResourceManager_removeData(ssbpLib_ResourceManager* obj, const char* dataKey);
SSBPLIB_DLLAPI void ssbpLib_ResourceManager_removeAllData(ssbpLib_ResourceManager* obj);
//SSBPLIB_DLLAPI ssbpLib_ResourceSet* ssbpLib_ResourceManager_getData(ssbpLib_ResourceManager* obj, const char* dataKey);	//※TODO:ResourceManager::getData()を呼び出すと何故かリンクエラーになる問題が生じ未対応とした(現在の所アプリケーションから使う必要は無いと思うのでとりあえず…)。リンカバグの可能性も有ると思う。解決したら対応しろ。
SSBPLIB_DLLAPI int ssbpLib_ResourceManager_changeTexture(ssbpLib_ResourceManager* obj, const char* ssbpName, const char* ssceName, long texture);
SSBPLIB_DLLAPI int ssbpLib_ResourceManager_releseTexture(ssbpLib_ResourceManager* obj, const char* ssbpName);
SSBPLIB_DLLAPI int ssbpLib_ResourceManager_getMaxFrame(ssbpLib_ResourceManager* obj, const char* ssbpName, const char* animeName);
/*****************************************************************************
 *	Player
 *****************************************************************************/
SSBPLIB_DLLAPI /*static*/ ssbpLib_Player* ssbpLib_Player_create(ssbpLib_ResourceManager* resman/*NULL可*/);
SSBPLIB_DLLAPI void ssbpLib_Player_delete(ssbpLib_Player* obj);
/*---------------------------------------------------------------------------*/
SSBPLIB_DLLAPI void ssbpLib_Player_setResourceManager(ssbpLib_Player* obj, ssbpLib_ResourceManager* resman/*NULL可*/);
SSBPLIB_DLLAPI void ssbpLib_Player_releaseResourceManager(ssbpLib_Player* obj);
SSBPLIB_DLLAPI void ssbpLib_Player_setData(ssbpLib_Player* obj, const char* dataKey);
SSBPLIB_DLLAPI void ssbpLib_Player_releaseData(ssbpLib_Player* obj);
SSBPLIB_DLLAPI void ssbpLib_Player_releaseAnime(ssbpLib_Player* obj);
SSBPLIB_DLLAPI void ssbpLib_Player_play(ssbpLib_Player* obj, const char* ssaeName, const char* motionName, int loop, int startFrameNo);
//SSBPLIB_DLLAPI void ssbpLib_Player_play(ssbpLib_Player* obj, const char* animeName, int loop, int startFrameNo);	//Cリンケージではオーバーロード出来ない。こちらのバージョンは使わないと思うので削除した。
SSBPLIB_DLLAPI void ssbpLib_Player_motionBlendPlay(ssbpLib_Player* obj, const char* animeName, int loop, int startFrameNo, double blendTime);
SSBPLIB_DLLAPI void ssbpLib_Player_animePause(ssbpLib_Player* obj);
SSBPLIB_DLLAPI void ssbpLib_Player_animeResume(ssbpLib_Player* obj);
SSBPLIB_DLLAPI void ssbpLib_Player_stop(ssbpLib_Player* obj);
SSBPLIB_DLLAPI const char* ssbpLib_Player_getPlayPackName(ssbpLib_Player* obj);		//元関数の戻り値が一時的でない文字列への参照なので、その文字列ポインタを取り出して返しても安全です。
SSBPLIB_DLLAPI const char* ssbpLib_Player_getPlayAnimeName(ssbpLib_Player* obj);	//元関数の戻り値が一時的でない文字列への参照なので、その文字列ポインタを取り出して返しても安全です。
SSBPLIB_DLLAPI int ssbpLib_Player_getMaxFrame(ssbpLib_Player* obj);
SSBPLIB_DLLAPI int ssbpLib_Player_getFrameNo(ssbpLib_Player* obj);
SSBPLIB_DLLAPI void ssbpLib_Player_setFrameNo(ssbpLib_Player* obj, int frameNo);
SSBPLIB_DLLAPI double ssbpLib_Player_getStep(ssbpLib_Player* obj);
SSBPLIB_DLLAPI void ssbpLib_Player_setStep(ssbpLib_Player* obj, double step);
SSBPLIB_DLLAPI int ssbpLib_Player_getLoop(ssbpLib_Player* obj);
SSBPLIB_DLLAPI void ssbpLib_Player_setLoop(ssbpLib_Player* obj, int loop);
SSBPLIB_DLLAPI int ssbpLib_Player_getLoopCount(ssbpLib_Player* obj);
SSBPLIB_DLLAPI void ssbpLib_Player_clearLoopCount(ssbpLib_Player* obj);
SSBPLIB_DLLAPI void ssbpLib_Player_setFrameSkipEnabled(ssbpLib_Player* obj, int enabled);
SSBPLIB_DLLAPI int ssbpLib_Player_isFrameSkipEnabled(ssbpLib_Player* obj);
SSBPLIB_DLLAPI int ssbpLib_Player_getLabelToFrame(ssbpLib_Player* obj, const char* findLabelName);
SSBPLIB_DLLAPI const char* ssbpLib_Player_getPartName(ssbpLib_Player* obj, int partId);
SSBPLIB_DLLAPI int ssbpLib_Player_indexOfPart(ssbpLib_Player* obj, const char* partName);
//SSBPLIB_DLLAPI int ssbpLib_Player_getPartState(ssbpLib_Player* obj, ssbpLib_ResluteState& result, const char* name, int frameNo);	//アプリケーションから使う事は無いと思うので削除した。もし定義するならばResluteState構造体をアプリケーション側から参照出来るように定義する必要が生じる。
SSBPLIB_DLLAPI void ssbpLib_Player_setPartVisible(ssbpLib_Player* obj, const char* partsname, int flg);
SSBPLIB_DLLAPI void ssbpLib_Player_setPartCell(ssbpLib_Player* obj, const char* partsname, const char* sscename, const char* cellname);
SSBPLIB_DLLAPI void ssbpLib_Player_setPosition(ssbpLib_Player* obj, double x, double y);
SSBPLIB_DLLAPI void ssbpLib_Player_setRotation(ssbpLib_Player* obj, double x, double y, double z);
SSBPLIB_DLLAPI void ssbpLib_Player_setScale(ssbpLib_Player* obj, double x, double y);
SSBPLIB_DLLAPI void ssbpLib_Player_setAlpha(ssbpLib_Player* obj, int a);
SSBPLIB_DLLAPI void ssbpLib_Player_setColor(ssbpLib_Player* obj, int r, int g, int b);
//SSBPLIB_DLLAPI int ssbpLib_Player_changeInstanceAnime(ssbpLib_Player* obj, const char* partsname, const char* animeName, int overWrite, ssbpLib_Instance keyParam);	//アプリケーションから使う事は無いと思うので削除した。もし定義するならばInstance構造体をアプリケーション側から参照出来るように定義する必要が生じる。
//SSBPLIB_DLLAPI void ssbpLib_Player_setInstanceParam(ssbpLib_Player* obj, int overWrite, ssbpLib_Instance keyParam);	//アプリケーションから使う事は無いと思うので削除した。もし定義するならばInstance構造体をアプリケーション側から参照出来るように定義する必要が生じる。
//SSBPLIB_DLLAPI void ssbpLib_Player_getInstanceParam(ssbpLib_Player* obj, int* overWrite, ssbpLib_Instance* keyParam);	//アプリケーションから使う事は無いと思うので削除した。もし定義するならばInstance構造体をアプリケーション側から参照出来るように定義する必要が生じる。
SSBPLIB_DLLAPI void ssbpLib_Player_setFlip(ssbpLib_Player* obj, int flipX, int flipY);	//ssbpLib/SS5PlayerPlatform.cppのSSDrawSprite()にバグが有るのか(?)、flipXもflipYも正しく反映されないようだ。実質、この関数は使えない。反転描画を行いたい場合は、この関数ではなくssbpLib_Player_setScale()を使え。ssbpLib_Player_setScale()を使えば正しく反転描画が出来るので、この関数が使えなくても実用上は問題無い。
SSBPLIB_DLLAPI void ssbpLib_Player_setGameFPS(ssbpLib_Player* obj, double fps);
//SSBPLIB_DLLAPI ssbpLib_CustomSprite* ssbpLib_Player_getSpriteData(ssbpLib_Player* obj, int partIndex);	//アプリケーションから使う事は無いと思うので削除した。もし定義するならばCustomSprite構造体をアプリケーション側から参照出来るように定義する必要が生じる。
SSBPLIB_DLLAPI void ssbpLib_Player_update(ssbpLib_Player* obj, double dt);
SSBPLIB_DLLAPI void ssbpLib_Player_draw(ssbpLib_Player* obj);
#ifdef  __cplusplus
}//extern "C"
#endif//__cplusplus
#endif//__SSBPLIB_H__
