main.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. #include "../Winamp/IN2.h"
  2. #include "api__in_mod.h"
  3. #include "../nu/ServiceBuilder.h"
  4. #include "resource.h"
  5. #include <strsafe.h>
  6. #include "MODPlayer.h"
  7. #include "../nu/AutoWide.h"
  8. #include <libopenmpt/libopenmpt.h>
  9. static MODPlayer *player;
  10. DWORD CALLBACK MODThread(LPVOID param);
  11. extern In_Module plugin;
  12. HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
  13. int g_duration=0;
  14. int paused = 0;
  15. static HANDLE play_thread = 0;
  16. static const wchar_t *MOD_PLUGIN_VERSION = L"3.05";
  17. // {B6CB4A7C-A8D0-4c55-8E60-9F7A7A23DA0F}
  18. static const GUID playbackConfigGroupGUID =
  19. {
  20. 0xb6cb4a7c, 0xa8d0, 0x4c55, { 0x8e, 0x60, 0x9f, 0x7a, 0x7a, 0x23, 0xda, 0xf }
  21. };
  22. static wchar_t plugin_name[256];
  23. /* Wasabi services */
  24. api_application *WASABI_API_APP=0;
  25. api_config *AGAVE_API_CONFIG=0;
  26. api_language *WASABI_API_LNG = 0;
  27. static int Init()
  28. {
  29. if (!IsWindow(plugin.hMainWindow)) {
  30. return IN_INIT_FAILURE;
  31. }
  32. ServiceBuild(plugin.service, AGAVE_API_CONFIG, AgaveConfigGUID);
  33. ServiceBuild(plugin.service, WASABI_API_APP, applicationApiServiceGuid);
  34. ServiceBuild(plugin.service, WASABI_API_LNG, languageApiGUID);
  35. // need to have this initialised before we try to do anything with localisation features
  36. WASABI_API_START_LANG(plugin.hDllInstance, InModMPTLangGUID);
  37. StringCbPrintfW(plugin_name,sizeof(plugin_name),WASABI_API_LNGSTRINGW(IDS_NULLSOFT_MOD), MOD_PLUGIN_VERSION);
  38. plugin.description = (char *)plugin_name;
  39. static char fileExtensionsString[2048] = "";
  40. char* end = fileExtensionsString;
  41. size_t remaining=sizeof(fileExtensionsString);
  42. const char *extensions = openmpt_get_supported_extensions();
  43. char *next_token;
  44. for (const char *extension = strtok_s((char *)extensions, ";", &next_token); extension; extension = strtok_s(NULL, ";", &next_token)) {
  45. StringCbCopyExA(end, remaining, extension, &end, &remaining, 0);
  46. const char *tracker = openmpt_get_tracker_name(extension);
  47. StringCbCopyExA(end+1, remaining-1, tracker, &end, &remaining, 0);
  48. openmpt_free_string(tracker);
  49. end++; remaining--;
  50. }
  51. plugin.FileExtensions = fileExtensionsString;
  52. *end = 0;
  53. openmpt_free_string(extensions);
  54. return IN_INIT_SUCCESS;
  55. }
  56. static void Quit()
  57. {
  58. ServiceRelease(plugin.service, AGAVE_API_CONFIG, AgaveConfigGUID);
  59. ServiceRelease(plugin.service, WASABI_API_APP, applicationApiServiceGuid);
  60. ServiceRelease(plugin.service, WASABI_API_LNG, languageApiGUID);
  61. }
  62. static int InfoBox(const wchar_t *file, HWND hwndParent)
  63. {
  64. return INFOBOX_UNCHANGED;
  65. }
  66. static int IsOurFile(const wchar_t *file)
  67. {
  68. return 0;
  69. }
  70. static void GetFileInfo(const wchar_t *file, wchar_t *title, int *length_in_ms)
  71. {
  72. }
  73. static int Play(const wchar_t *file)
  74. {
  75. g_duration=-1000;
  76. player = new MODPlayer(file);
  77. play_thread = CreateThread(0, 0, MODThread, player, 0, 0);
  78. SetThreadPriority(play_thread, (int)AGAVE_API_CONFIG->GetInt(playbackConfigGroupGUID, L"priority", THREAD_PRIORITY_HIGHEST));
  79. return 0; // success
  80. }
  81. static void Pause()
  82. {
  83. paused = 1;
  84. plugin.outMod->Pause(1);
  85. }
  86. static void UnPause()
  87. {
  88. paused = 0;
  89. plugin.outMod->Pause(0);
  90. }
  91. static int IsPaused()
  92. {
  93. return paused;
  94. }
  95. static void Stop()
  96. {
  97. if (player) {
  98. player->Kill();
  99. if (play_thread) {
  100. WaitForSingleObject(play_thread, INFINITE);
  101. }
  102. play_thread = 0;
  103. delete player;
  104. player=0;
  105. }
  106. }
  107. static int GetLength()
  108. {
  109. return g_duration;
  110. }
  111. static int GetOutputTime()
  112. {
  113. if (plugin.outMod && player) {
  114. return player->GetOutputTime();
  115. } else {
  116. return 0;
  117. }
  118. }
  119. static void SetOutputTime(int time_in_ms)
  120. {
  121. if (player) {
  122. player->Seek(time_in_ms);
  123. }
  124. }
  125. static void SetVolume(int _volume)
  126. {
  127. plugin.outMod->SetVolume(_volume);
  128. }
  129. static void SetPan(int _pan)
  130. {
  131. plugin.outMod->SetPan(_pan);
  132. }
  133. static void EQSet(int on, char data[10], int preamp)
  134. {
  135. }
  136. static int DoAboutMessageBox(HWND parent, wchar_t* title, wchar_t* message)
  137. {
  138. MSGBOXPARAMS msgbx = {sizeof(MSGBOXPARAMS),0};
  139. msgbx.lpszText = message;
  140. msgbx.lpszCaption = title;
  141. msgbx.lpszIcon = MAKEINTRESOURCE(102);
  142. msgbx.hInstance = GetModuleHandle(0);
  143. msgbx.dwStyle = MB_USERICON;
  144. msgbx.hwndOwner = parent;
  145. return MessageBoxIndirect(&msgbx);
  146. }
  147. static void About(HWND hwndParent)
  148. {
  149. wchar_t message[1024], text[1024];
  150. char license_trim[1024];
  151. WASABI_API_LNGSTRINGW_BUF(IDS_NULLSOFT_MOD_OLD,text,1024);
  152. const char *library_version = openmpt_get_string("library_version");
  153. const char *license = openmpt_get_string("license");
  154. // trim the license string
  155. StringCbCopyA(license_trim, sizeof(license_trim), license);
  156. char * trim = license_trim;
  157. for (int i=0;i<4;i++) {
  158. trim = strchr(trim, '\n');
  159. if (trim) {
  160. trim++;
  161. }
  162. }
  163. *trim=0;
  164. StringCchPrintfW(message, 1024,
  165. WASABI_API_LNGSTRINGW(IDS_ABOUT_TEXT),
  166. plugin.description,
  167. TEXT(__DATE__),
  168. library_version,
  169. license_trim
  170. );
  171. DoAboutMessageBox(hwndParent,text,message);
  172. }
  173. extern In_Module plugin =
  174. {
  175. IN_VER_RET, // defined in IN2.H
  176. "nullsoft(in_mod.dll)",
  177. 0, // hMainWindow (filled in by winamp)
  178. 0, // hDllInstance (filled in by winamp)
  179. "S3M\0Scream Tracker\0", // this is a double-null limited list. "EXT\0Description\0EXT\0Description\0" etc.
  180. 1, // is_seekable
  181. 1, // uses output plug-in system
  182. About, // TODO(benski) config
  183. About,
  184. Init,
  185. Quit,
  186. GetFileInfo,
  187. InfoBox,
  188. IsOurFile,
  189. Play,
  190. Pause,
  191. UnPause,
  192. IsPaused,
  193. Stop,
  194. GetLength,
  195. GetOutputTime,
  196. SetOutputTime,
  197. SetVolume,
  198. SetPan,
  199. 0,0,0,0,0,0,0,0,0, // visualization calls filled in by winamp
  200. 0,0, // dsp calls filled in by winamp
  201. EQSet,
  202. NULL, // setinfo call filled in by winamp
  203. 0, // out_mod filled in by winamp
  204. };
  205. // exported symbol. Returns output module.
  206. extern "C"
  207. {
  208. __declspec(dllexport) In_Module * winampGetInModule2()
  209. {
  210. return &plugin;
  211. }
  212. }