/xbmc/screensavers/rsxs-0.9/src/solarwinds/solarwinds.cc

http://github.com/xbmc/xbmc · C++ · 331 lines · 246 code · 45 blank · 40 comment · 17 complexity · 27f5a8e92731291d9ebb445d185ce6ae MD5 · raw file

  1. /*
  2. * Really Slick XScreenSavers
  3. * Copyright (C) 2002-2006 Michael Chapman
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. *
  18. *****************************************************************************
  19. *
  20. * This is a Linux port of the Really Slick Screensavers,
  21. * Copyright (C) 2002 Terence M. Welsh, available from www.reallyslick.com
  22. */
  23. #include <common.hh>
  24. #include <color.hh>
  25. #include <hack.hh>
  26. #include <solarwinds.hh>
  27. #include <vector.hh>
  28. #include <wind.hh>
  29. namespace Hack {
  30. unsigned int numWinds = 1;
  31. unsigned int numEmitters = 30;
  32. unsigned int numParticles = 2000;
  33. GeometryType geometry = LIGHTS_GEOMETRY;
  34. float size = 50.0f;
  35. float windSpeed = 20.0f;
  36. float emitterSpeed = 15.0f;
  37. float particleSpeed = 10.0f;
  38. float blur = 40.0f;
  39. };
  40. namespace Hack {
  41. enum Arguments {
  42. ARG_WINDS = 1,
  43. ARG_PARTICLES,
  44. ARG_EMITTERS,
  45. ARG_SIZE,
  46. ARG_SPEED,
  47. ARG_EMITTERSPEED,
  48. ARG_WINDSPEED,
  49. ARG_BLUR,
  50. ARG_LIGHTS_GEOMETRY = 0x100, ARG_POINTS_GEOMETRY, ARG_LINES_GEOMETRY
  51. };
  52. std::vector<Wind> _winds;
  53. error_t parse(int, char*, struct argp_state*);
  54. };
  55. error_t Hack::parse(int key, char* arg, struct argp_state* state) {
  56. switch (key) {
  57. case ARG_WINDS:
  58. if (Common::parseArg(arg, numWinds, 1u, 10u))
  59. argp_failure(state, EXIT_FAILURE, 0,
  60. "number of solar winds must be between 1 and 10");
  61. return 0;
  62. case ARG_PARTICLES:
  63. if (Common::parseArg(arg, numParticles, 1u, 10000u))
  64. argp_failure(state, EXIT_FAILURE, 0,
  65. "particles per wind must be between 1 and 10000");
  66. return 0;
  67. case ARG_EMITTERS:
  68. if (Common::parseArg(arg, numEmitters, 1u, 1000u))
  69. argp_failure(state, EXIT_FAILURE, 0,
  70. "emitters per wind must be between 1 and 1000");
  71. return 0;
  72. case ARG_SIZE:
  73. if (Common::parseArg(arg, size, 1.0f, 100.0f))
  74. argp_failure(state, EXIT_FAILURE, 0,
  75. "particle size must be between 1 and 100");
  76. return 0;
  77. case ARG_SPEED:
  78. if (Common::parseArg(arg, particleSpeed, 1.0f, 100.0f))
  79. argp_failure(state, EXIT_FAILURE, 0,
  80. "particle speed must be between 1 and 100");
  81. return 0;
  82. case ARG_EMITTERSPEED:
  83. if (Common::parseArg(arg, emitterSpeed, 1.0f, 100.0f))
  84. argp_failure(state, EXIT_FAILURE, 0,
  85. "emitter speed must be between 1 and 100");
  86. return 0;
  87. case ARG_WINDSPEED:
  88. if (Common::parseArg(arg, windSpeed, 1.0f, 100.0f))
  89. argp_failure(state, EXIT_FAILURE, 0,
  90. "wind speed must be between 1 and 100");
  91. return 0;
  92. case ARG_BLUR:
  93. if (Common::parseArg(arg, blur, 0.0f, 100.0f))
  94. argp_failure(state, EXIT_FAILURE, 0,
  95. "motion blur must be between 1 and 100");
  96. return 0;
  97. case ARG_LIGHTS_GEOMETRY:
  98. geometry = LIGHTS_GEOMETRY;
  99. return 0;
  100. case ARG_POINTS_GEOMETRY:
  101. geometry = POINTS_GEOMETRY;
  102. return 0;
  103. case ARG_LINES_GEOMETRY:
  104. geometry = LINES_GEOMETRY;
  105. return 0;
  106. default:
  107. return ARGP_ERR_UNKNOWN;
  108. }
  109. }
  110. const struct argp* Hack::getParser() {
  111. static struct argp_option options[] = {
  112. { NULL, 0, NULL, 0, "Wind options:" },
  113. { "winds", ARG_WINDS, "NUM", 0, "Number of solar winds (1-10, default = 1)" },
  114. { "particles", ARG_PARTICLES, "NUM", 0,
  115. "Particles per wind (1-10000, default = 2000)" },
  116. { "emitters", ARG_EMITTERS, "NUM", 0,
  117. "Emitters per wind (1-1000, default = 30)" },
  118. { "windspeed", ARG_WINDSPEED, "NUM", 0, "Wind speed (1-100, default = 20)" },
  119. { NULL, 0, NULL, 0, "Particle options:" },
  120. { "size", ARG_SIZE, "NUM", 0, "Particle size (1-100, default = 50)" },
  121. { "lights", ARG_LIGHTS_GEOMETRY, NULL, 0,
  122. "Particle geometry (default = lights)" },
  123. { "points", ARG_POINTS_GEOMETRY, NULL, OPTION_ALIAS },
  124. { "lines", ARG_LINES_GEOMETRY, NULL, OPTION_ALIAS },
  125. { "speed", ARG_SPEED, "NUM", 0, "Particle speed (1-100, default = 10)" },
  126. { NULL, 0, NULL, 0, "Emitter options:" },
  127. { "emitterspeed", ARG_EMITTERSPEED, "NUM", 0,
  128. "Emitter speed (1-100, default = 15)" },
  129. { NULL, 0, NULL, 0, "Other options:" },
  130. { "blur", ARG_BLUR, "NUM", 0, "Motion blur (0-100, default = 40)" },
  131. {}
  132. };
  133. static struct argp parser = {
  134. options, parse, NULL, "Another color and movement particle effect."
  135. };
  136. return &parser;
  137. }
  138. std::string Hack::getShortName() { return "solarwinds"; }
  139. std::string Hack::getName() { return "Solar Winds"; }
  140. void Hack::start() {
  141. /*
  142. glViewport(0, 0, Common::width, Common::height);
  143. glMatrixMode(GL_PROJECTION);
  144. glLoadIdentity();
  145. gluPerspective(90.0, Common::aspectRatio, 1.0, 10000);
  146. glTranslatef(0.0, 0.0, -15.0);
  147. glMatrixMode(GL_MODELVIEW);
  148. glLoadIdentity();
  149. */
  150. glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  151. glClear(GL_COLOR_BUFFER_BIT);
  152. if (geometry == LIGHTS_GEOMETRY)
  153. glBlendFunc(GL_ONE, GL_ONE);
  154. else
  155. // Necessary for point and line smoothing (I don't know why)
  156. glBlendFunc(GL_SRC_ALPHA, GL_ONE);
  157. glEnable(GL_BLEND);
  158. Wind::init();
  159. // Initialize surfaces
  160. _winds.resize(numWinds);
  161. // Clear the GL error
  162. glGetError();
  163. }
  164. void Hack::reshape() {
  165. glViewport(0, 0, Common::width, Common::height);
  166. glMatrixMode(GL_PROJECTION);
  167. glLoadIdentity();
  168. gluPerspective(90.0, Common::aspectRatio, 1.0, 10000);
  169. glTranslatef(0.0, 0.0, -15.0);
  170. glMatrixMode(GL_MODELVIEW);
  171. glLoadIdentity();
  172. }
  173. void Hack::tick() {
  174. glMatrixMode(GL_PROJECTION);
  175. glPushMatrix();
  176. glLoadIdentity();
  177. gluPerspective(90.0, Common::aspectRatio, 1.0, 10000);
  178. glTranslatef(0.0, 0.0, -15.0);
  179. glMatrixMode(GL_MODELVIEW);
  180. glPushMatrix();
  181. glLoadIdentity();
  182. glEnable(GL_TEXTURE_2D);
  183. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  184. if (!blur) {
  185. glClear(GL_COLOR_BUFFER_BIT);
  186. } else {
  187. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  188. glColor4f(0.0f, 0.0f, 0.0f, 0.5f - (blur * 0.0049f));
  189. glBegin(GL_QUADS);
  190. glVertex3f(-40.0f, -17.0f, 0.0f);
  191. glVertex3f(40.0f, -17.0f, 0.0f);
  192. glVertex3f(40.0f, 17.0f, 0.0f);
  193. glVertex3f(-40.0f, 17.0f, 0.0f);
  194. glEnd();
  195. if (geometry == LIGHTS_GEOMETRY)
  196. glBlendFunc(GL_ONE, GL_ONE);
  197. else
  198. // Necessary for point and line smoothing (I don't know why)
  199. // Maybe it's just my video card...
  200. glBlendFunc(GL_SRC_ALPHA, GL_ONE);
  201. }
  202. // Update surfaces
  203. stdx::call_all(_winds, &Wind::update);
  204. // Common::flush();
  205. glMatrixMode(GL_PROJECTION);
  206. glPopMatrix();
  207. glMatrixMode(GL_MODELVIEW);
  208. glPopMatrix();
  209. // Clear the GL error
  210. glGetError();
  211. }
  212. void Hack::stop() {}
  213. void Hack::keyPress(char c, const KeySym&) {
  214. switch (c) {
  215. case 3: case 27:
  216. case 'q': case 'Q':
  217. Common::running = false;
  218. break;
  219. }
  220. }
  221. void Hack::keyRelease(char, const KeySym&) {}
  222. void Hack::pointerMotion(int, int) {}
  223. void Hack::buttonPress(unsigned int) {}
  224. void Hack::buttonRelease(unsigned int) {}
  225. void Hack::pointerEnter() {}
  226. void Hack::pointerLeave() {}
  227. #define _LINUX
  228. #include "../../../addons/include/xbmc_scr_dll.h"
  229. extern "C" {
  230. ADDON_STATUS ADDON_Create(void* hdl, void* props)
  231. {
  232. if (!props)
  233. return ADDON_STATUS_UNKNOWN;
  234. SCR_PROPS* scrprops = (SCR_PROPS*)props;
  235. Common::width = scrprops->width;
  236. Common::height = scrprops->height;
  237. Common::aspectRatio = float(Common::width) / float(Common::height);
  238. Common::resources = new ResourceManager;
  239. return ADDON_STATUS_OK;
  240. }
  241. void Start()
  242. {
  243. Hack::start();
  244. }
  245. void Render()
  246. {
  247. Hack::tick();
  248. }
  249. void ADDON_Stop()
  250. {
  251. Hack::stop();
  252. }
  253. void ADDON_Destroy()
  254. {
  255. delete Common::resources;
  256. }
  257. ADDON_STATUS ADDON_GetStatus()
  258. {
  259. return ADDON_STATUS_OK;
  260. }
  261. bool ADDON_HasSettings()
  262. {
  263. return false;
  264. }
  265. unsigned int ADDON_GetSettings(ADDON_StructSetting ***sSet)
  266. {
  267. return 0;
  268. }
  269. ADDON_STATUS ADDON_SetSetting(const char *settingName, const void *settingValue)
  270. {
  271. return ADDON_STATUS_OK;
  272. }
  273. void ADDON_FreeSettings()
  274. {
  275. }
  276. void ADDON_Announce(const char *flag, const char *sender, const char *message, const void *data)
  277. {
  278. }
  279. void GetInfo(SCR_INFO *info)
  280. {
  281. }
  282. void Remove()
  283. {
  284. }
  285. }