PageRenderTime 38ms CodeModel.GetById 13ms app.highlight 21ms RepoModel.GetById 1ms app.codeStats 0ms

/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
 25#include <color.hh>
 26#include <hack.hh>
 27#include <solarwinds.hh>
 28#include <vector.hh>
 29#include <wind.hh>
 30
 31namespace Hack {
 32	unsigned int numWinds = 1;
 33	unsigned int numEmitters = 30;
 34	unsigned int numParticles = 2000;
 35	GeometryType geometry = LIGHTS_GEOMETRY;
 36	float size = 50.0f;
 37	float windSpeed = 20.0f;
 38	float emitterSpeed = 15.0f;
 39	float particleSpeed = 10.0f;
 40	float blur = 40.0f;
 41};
 42
 43namespace Hack {
 44	enum Arguments {
 45		ARG_WINDS = 1,
 46		ARG_PARTICLES,
 47		ARG_EMITTERS,
 48		ARG_SIZE,
 49		ARG_SPEED,
 50		ARG_EMITTERSPEED,
 51		ARG_WINDSPEED,
 52		ARG_BLUR,
 53		ARG_LIGHTS_GEOMETRY = 0x100, ARG_POINTS_GEOMETRY, ARG_LINES_GEOMETRY
 54	};
 55
 56	std::vector<Wind> _winds;
 57
 58	error_t parse(int, char*, struct argp_state*);
 59};
 60
 61error_t Hack::parse(int key, char* arg, struct argp_state* state) {
 62	switch (key) {
 63	case ARG_WINDS:
 64		if (Common::parseArg(arg, numWinds, 1u, 10u))
 65			argp_failure(state, EXIT_FAILURE, 0,
 66				"number of solar winds must be between 1 and 10");
 67		return 0;
 68	case ARG_PARTICLES:
 69		if (Common::parseArg(arg, numParticles, 1u, 10000u))
 70			argp_failure(state, EXIT_FAILURE, 0,
 71				"particles per wind must be between 1 and 10000");
 72		return 0;
 73	case ARG_EMITTERS:
 74		if (Common::parseArg(arg, numEmitters, 1u, 1000u))
 75			argp_failure(state, EXIT_FAILURE, 0,
 76				"emitters per wind must be between 1 and 1000");
 77		return 0;
 78	case ARG_SIZE:
 79		if (Common::parseArg(arg, size, 1.0f, 100.0f))
 80			argp_failure(state, EXIT_FAILURE, 0,
 81				"particle size must be between 1 and 100");
 82		return 0;
 83	case ARG_SPEED:
 84		if (Common::parseArg(arg, particleSpeed, 1.0f, 100.0f))
 85			argp_failure(state, EXIT_FAILURE, 0,
 86				"particle speed must be between 1 and 100");
 87		return 0;
 88	case ARG_EMITTERSPEED:
 89		if (Common::parseArg(arg, emitterSpeed, 1.0f, 100.0f))
 90			argp_failure(state, EXIT_FAILURE, 0,
 91				"emitter speed must be between 1 and 100");
 92		return 0;
 93	case ARG_WINDSPEED:
 94		if (Common::parseArg(arg, windSpeed, 1.0f, 100.0f))
 95			argp_failure(state, EXIT_FAILURE, 0,
 96				"wind speed must be between 1 and 100");
 97		return 0;
 98	case ARG_BLUR:
 99		if (Common::parseArg(arg, blur, 0.0f, 100.0f))
100			argp_failure(state, EXIT_FAILURE, 0,
101				"motion blur must be between 1 and 100");
102		return 0;
103	case ARG_LIGHTS_GEOMETRY:
104		geometry = LIGHTS_GEOMETRY;
105		return 0;
106	case ARG_POINTS_GEOMETRY:
107		geometry = POINTS_GEOMETRY;
108		return 0;
109	case ARG_LINES_GEOMETRY:
110		geometry = LINES_GEOMETRY;
111		return 0;
112	default:
113		return ARGP_ERR_UNKNOWN;
114	}
115}
116
117const struct argp* Hack::getParser() {
118	static struct argp_option options[] = {
119		{ NULL, 0, NULL, 0, "Wind options:" },
120		{ "winds", ARG_WINDS, "NUM", 0, "Number of solar winds (1-10, default = 1)" },
121		{ "particles", ARG_PARTICLES, "NUM", 0,
122			"Particles per wind (1-10000, default = 2000)" },
123		{ "emitters", ARG_EMITTERS, "NUM", 0,
124			"Emitters per wind (1-1000, default = 30)" },
125		{ "windspeed", ARG_WINDSPEED, "NUM", 0, "Wind speed (1-100, default = 20)" },
126		{ NULL, 0, NULL, 0, "Particle options:" },
127		{ "size", ARG_SIZE, "NUM", 0, "Particle size (1-100, default = 50)" },
128		{ "lights", ARG_LIGHTS_GEOMETRY, NULL, 0,
129			"Particle geometry (default = lights)" },
130		{ "points", ARG_POINTS_GEOMETRY, NULL, OPTION_ALIAS },
131		{ "lines", ARG_LINES_GEOMETRY, NULL, OPTION_ALIAS },
132		{ "speed", ARG_SPEED, "NUM", 0, "Particle speed (1-100, default = 10)" },
133		{ NULL, 0, NULL, 0, "Emitter options:" },
134		{ "emitterspeed", ARG_EMITTERSPEED, "NUM", 0,
135			"Emitter speed (1-100, default = 15)" },
136		{ NULL, 0, NULL, 0, "Other options:" },
137		{ "blur", ARG_BLUR, "NUM", 0, "Motion blur (0-100, default = 40)" },
138		{}
139	};
140	static struct argp parser = {
141		options, parse, NULL, "Another color and movement particle effect."
142	};
143	return &parser;
144}
145
146std::string Hack::getShortName() { return "solarwinds"; }
147std::string Hack::getName()      { return "Solar Winds"; }
148
149void Hack::start() {
150/*
151	glViewport(0, 0, Common::width, Common::height);
152
153	glMatrixMode(GL_PROJECTION);
154	glLoadIdentity();
155	gluPerspective(90.0, Common::aspectRatio, 1.0, 10000);
156	glTranslatef(0.0, 0.0, -15.0);
157	glMatrixMode(GL_MODELVIEW);
158	glLoadIdentity();
159*/
160
161	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
162	glClear(GL_COLOR_BUFFER_BIT);
163
164	if (geometry == LIGHTS_GEOMETRY)
165		glBlendFunc(GL_ONE, GL_ONE);
166	else
167		// Necessary for point and line smoothing (I don't know why)
168		glBlendFunc(GL_SRC_ALPHA, GL_ONE);
169	glEnable(GL_BLEND);
170	Wind::init();
171
172	// Initialize surfaces
173	_winds.resize(numWinds);
174
175        // Clear the GL error
176        glGetError();
177}
178
179void Hack::reshape() {
180	glViewport(0, 0, Common::width, Common::height);
181
182	glMatrixMode(GL_PROJECTION);
183	glLoadIdentity();
184	gluPerspective(90.0, Common::aspectRatio, 1.0, 10000);
185	glTranslatef(0.0, 0.0, -15.0);
186	glMatrixMode(GL_MODELVIEW);
187	glLoadIdentity();
188}
189
190void Hack::tick() {
191        glMatrixMode(GL_PROJECTION);
192        glPushMatrix();
193        glLoadIdentity();
194        gluPerspective(90.0, Common::aspectRatio, 1.0, 10000);
195        glTranslatef(0.0, 0.0, -15.0);
196        glMatrixMode(GL_MODELVIEW);
197        glPushMatrix();
198        glLoadIdentity();
199
200        glEnable(GL_TEXTURE_2D);
201        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
202
203	if (!blur) {
204		glClear(GL_COLOR_BUFFER_BIT);
205	} else {
206		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
207		glColor4f(0.0f, 0.0f, 0.0f, 0.5f - (blur * 0.0049f));
208		glBegin(GL_QUADS);
209			glVertex3f(-40.0f, -17.0f, 0.0f);
210			glVertex3f(40.0f, -17.0f, 0.0f);
211			glVertex3f(40.0f, 17.0f, 0.0f);
212			glVertex3f(-40.0f, 17.0f, 0.0f);
213		glEnd();
214		if (geometry == LIGHTS_GEOMETRY)
215			glBlendFunc(GL_ONE, GL_ONE);
216		else
217			// Necessary for point and line smoothing (I don't know why)
218			// Maybe it's just my video card...
219			glBlendFunc(GL_SRC_ALPHA, GL_ONE);
220	}
221
222	// Update surfaces
223	stdx::call_all(_winds, &Wind::update);
224
225	// Common::flush();
226
227        glMatrixMode(GL_PROJECTION);
228        glPopMatrix();
229        glMatrixMode(GL_MODELVIEW);
230        glPopMatrix();
231
232        // Clear the GL error
233        glGetError();
234}
235
236void Hack::stop() {}
237
238void Hack::keyPress(char c, const KeySym&) {
239	switch (c) {
240	case 3: case 27:
241	case 'q': case 'Q':
242		Common::running = false;
243		break;
244	}
245}
246
247void Hack::keyRelease(char, const KeySym&) {}
248void Hack::pointerMotion(int, int) {}
249void Hack::buttonPress(unsigned int) {}
250void Hack::buttonRelease(unsigned int) {}
251void Hack::pointerEnter() {}
252void Hack::pointerLeave() {}
253
254#define _LINUX
255#include "../../../addons/include/xbmc_scr_dll.h"
256
257extern "C" {
258
259ADDON_STATUS ADDON_Create(void* hdl, void* props)
260{
261  if (!props)
262    return ADDON_STATUS_UNKNOWN;
263
264  SCR_PROPS* scrprops = (SCR_PROPS*)props;
265
266  Common::width = scrprops->width;
267  Common::height = scrprops->height;
268  Common::aspectRatio = float(Common::width) / float(Common::height);
269  Common::resources = new ResourceManager;
270
271  return ADDON_STATUS_OK;
272}
273
274void Start()
275{
276  Hack::start();
277}
278
279void Render()
280{
281  Hack::tick();
282}
283
284void ADDON_Stop()
285{
286  Hack::stop();
287}
288
289void ADDON_Destroy()
290{
291  delete Common::resources;
292}
293
294ADDON_STATUS ADDON_GetStatus()
295{
296  return ADDON_STATUS_OK;
297}
298
299bool ADDON_HasSettings()
300{
301  return false;
302}
303
304unsigned int ADDON_GetSettings(ADDON_StructSetting ***sSet)
305{
306  return 0;
307}
308
309ADDON_STATUS ADDON_SetSetting(const char *settingName, const void *settingValue)
310{
311  return ADDON_STATUS_OK;
312}
313
314void ADDON_FreeSettings()
315{
316}
317
318void ADDON_Announce(const char *flag, const char *sender, const char *message, const void *data)
319{
320}
321
322void GetInfo(SCR_INFO *info)
323{
324}
325
326void Remove()
327{
328}
329
330}
331