Add pointlog2svg utility for the thesis
[numtypysics.git] / PythonInput.cpp
blob6ddbddd99beb5c54790b366f14a9e9e778593965
2 /*
3 * Python Input Module for NumptyPhysics
4 * Copyright (c) 2009 Thomas Perl <thpinfo.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 3 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
18 #include "PythonInput.h"
19 #include "Multitouch.h"
21 #ifdef HAVE_PYTHON
23 #include <Python.h>
24 #include "SDL/SDL.h"
25 #include <SDL/SDL_mixer.h>
27 #include <iostream>
28 #include <string>
31 int PythonInput::m_width = 0;
33 static char* soundFiles[] = {
34 "scraping.ogg",
35 "blue.ogg",
36 "drag.ogg"
39 const int CHANNELS = 8;
41 class SoundManager
43 public:
44 enum SoundType {
45 SND_DRAW,
46 SND_DRAG,
47 SND_DELETE,
48 SND_MAX
51 SoundManager()
53 Mix_AllocateChannels(CHANNELS);
54 Mix_Chunk* tmp;
55 for (int i=0; i<SND_MAX; i++) {
56 tmp = Mix_LoadWAV(soundFiles[i]);
57 if (tmp == NULL) {
58 throw std::string("Cannot open sound file: ") + std::string(soundFiles[i]);
60 sounds[i] = tmp;
64 ~SoundManager()
66 for (int i=0; i<SND_MAX; i++) {
67 Mix_FreeChunk(sounds[i]);
71 void
72 playSound(SoundType s, int id, float x=1., bool single=false)
74 std::cerr << "x = " << x << std::endl;
75 Mix_PlayChannel(id%CHANNELS, sounds[s], single?0:10);
76 updatePosition(id, x);
79 void
80 updatePosition(int id, float x)
82 Mix_SetPanning(id%CHANNELS, 254*(1.-x), 254*(x));
85 void
86 stopSound(int id)
88 Mix_FadeOutChannel(id%CHANNELS, 100);
91 private:
92 Mix_Chunk* sounds[SND_MAX];
95 PyObject* PythonInput::create_module()
97 static PyMethodDef NumptyMethods[] = {
98 {"post_event", post_event, METH_O, "Post a new mouse event"},
99 {NULL, NULL, 0, NULL} /* Sentinel */
102 PyObject* module;
103 module = Py_InitModule("numptyphysics", NumptyMethods);
105 PyModule_AddIntConstant(module, "START_STROKE", SDL_NP_START_STROKE);
106 PyModule_AddIntConstant(module, "APPEND_STROKE", SDL_NP_APPEND_STROKE);
107 PyModule_AddIntConstant(module, "FINISH_STROKE", SDL_NP_FINISH_STROKE);
108 PyModule_AddIntConstant(module, "START_ROPE", SDL_NP_START_ROPE);
109 PyModule_AddIntConstant(module, "APPEND_ROPE", SDL_NP_APPEND_ROPE);
110 PyModule_AddIntConstant(module, "FINISH_ROPE", SDL_NP_FINISH_ROPE);
111 PyModule_AddIntConstant(module, "PREVIEW_CURSOR", SDL_NP_PREVIEW_CURSOR);
112 PyModule_AddIntConstant(module, "CANCEL_DRAW", SDL_NP_CANCEL_DRAW);
113 PyModule_AddIntConstant(module, "START_DRAG", SDL_NP_START_DRAG);
114 PyModule_AddIntConstant(module, "DRAG", SDL_NP_DRAG);
115 PyModule_AddIntConstant(module, "END_DRAG", SDL_NP_END_DRAG);
116 PyModule_AddIntConstant(module, "PAN", SDL_NP_PAN);
117 PyModule_AddIntConstant(module, "ZOOM", SDL_NP_ZOOM);
118 PyModule_AddIntConstant(module, "DELETE", SDL_NP_DELETE);
120 PyModule_AddIntConstant(module, "WIDTH", PythonInput::m_width);
121 PyModule_AddIntConstant(module, "HEIGHT", m_height);
122 PyModule_AddIntConstant(module, "MAX_CURSORS", MT_MAX_CURSORS);
124 return module;
127 PyObject* PythonInput::post_event(PyObject* self, PyObject* event)
129 static SoundManager sound;
131 int xpos = -1, ypos = -1;
132 int type = -1;
133 int cursor_id = -1;
134 PyObject *o = NULL;
135 SDL_Event e = {0};
137 assert(self == NULL);
139 /* Get X position */
140 o = PyObject_GetAttrString(event, "x");
141 if (PyInt_Check(o)) {
142 xpos = (int)PyInt_AsLong(o);
143 } else {
144 fprintf(stderr, "x not a number: ");
145 PyObject_Print(o, stderr, 0);
146 fprintf(stderr, "\n");
147 exit(1);
149 Py_DECREF(o);
151 /* Get Y position */
152 o = PyObject_GetAttrString(event, "y");
153 if (PyInt_Check(o)) {
154 ypos = (int)PyInt_AsLong(o);
155 } else {
156 fprintf(stderr, "y not a number: ");
157 PyObject_Print(o, stderr, 0);
158 fprintf(stderr, "\n");
159 exit(1);
161 Py_DECREF(o);
163 /* Get type */
164 o = PyObject_GetAttrString(event, "event_type");
165 if (PyInt_Check(o)) {
166 type = (int)PyInt_AsLong(o);
167 } else {
168 fprintf(stderr, "event_type is not an int: ");
169 PyObject_Print(o, stderr, 0);
170 fputc('\n', stderr);
171 exit(1);
173 Py_DECREF(o);
175 /* Get cursor_id */
176 o = PyObject_GetAttrString(event, "cursor_id");
177 if (PyInt_Check(o)) {
178 cursor_id = (int)PyInt_AsLong(o);
179 } else {
180 fprintf(stderr, "cursor_id is not an int: ");
181 PyObject_Print(o, stderr, 0);
182 fputc('\n', stderr);
183 exit(1);
185 Py_DECREF(o);
187 if (type == SDL_NP_START_STROKE) {
188 sound.playSound(sound.SND_DRAW, cursor_id, (float)xpos/(float)PythonInput::m_width);
189 queueStartStrokeEvent(cursor_id, xpos, ypos);
190 } else if (type == SDL_NP_FINISH_STROKE) {
191 sound.stopSound(cursor_id);
192 queueFinishStrokeEvent(cursor_id, xpos, ypos);
193 } else if (type == SDL_NP_APPEND_STROKE) {
194 sound.updatePosition(cursor_id, (float)xpos/(float)PythonInput::m_width);
195 queueAppendStrokeEvent(cursor_id, xpos, ypos);
196 } else if (type == SDL_NP_START_DRAG) {
197 sound.playSound(sound.SND_DRAG, cursor_id, (float)xpos/(float)PythonInput::m_width);
198 queueStartDragEvent(cursor_id, xpos, ypos);
199 } else if (type == SDL_NP_END_DRAG) {
200 sound.stopSound(cursor_id);
201 queueEndDragEvent(cursor_id, xpos, ypos);
202 } else if (type == SDL_NP_DRAG) {
203 sound.updatePosition(cursor_id, (float)xpos/(float)PythonInput::m_width);
204 queueDragEvent(cursor_id, xpos, ypos);
205 } else if (type == SDL_NP_PREVIEW_CURSOR) {
206 queuePreviewCursorEvent(cursor_id, xpos, ypos);
207 } else if (type == SDL_NP_DELETE) {
208 sound.playSound(sound.SND_DELETE, cursor_id, (float)xpos/(float)PythonInput::m_width, true);
209 queueDeleteEvent(xpos, ypos);
210 } else if (type == SDL_NP_CANCEL_DRAW) {
211 queueCancelDrawEvent(cursor_id);
212 } else {
213 fprintf(stderr, "Warning: unknown event type %d.\n", type);
214 exit(1);
217 //return PyErr_Format(PyExc_TypeError, "This function needs a bot class to work");
218 Py_RETURN_NONE;
221 #endif /* HAVE_PYTHON */