Report no pressed keys -- now it properly plays the input.
[synaesthesia.git] / sdlwrap.cc
blobae78cc424fc2a013f9b96ad22502c30f4983f94a
1 /* Synaesthesia - program to display sound graphically
2 Copyright (C) 1997 Paul Francis Harrison
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 2 of the License, or (at your
7 option) any later version.
9 This program is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 675 Mass Ave, Cambridge, MA 02139, USA.
18 The author may be contacted at:
19 pfh@yoyo.cc.monash.edu.au
21 27 Bond St., Mt. Waverley, 3149, Melbourne, Australia
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <stdint.h>
27 #include <time.h>
28 #include <string.h>
29 #include "syna.h"
31 #if HAVE_SDL
33 #include "SDL.h"
35 static SDL_Surface *surface;
36 static SDL_Color sdlPalette[256];
37 static bool fullscreen;
38 static int scaling; //currently only supports 1, 2
40 static void createSurface() {
41 Uint32 videoflags = SDL_HWSURFACE | SDL_DOUBLEBUF |
42 SDL_RESIZABLE | (fullscreen?SDL_FULLSCREEN:0);
45 /* Get available fullscreen modes */
46 SDL_Rect **modes = SDL_ListModes(0, videoflags);
48 bool any = false;
50 if(modes == (SDL_Rect **)-1){
51 /* All resolutions ok */
52 any = true;
53 } else {
54 /* Is there a resolution that will fit the display nicely */
55 for(int i=0;modes[i];i++)
56 if (modes[i]->w < outWidth*2 || modes[i]->h < outHeight*2)
57 any = true;
60 scaling = (any?1:2);
62 surface = SDL_SetVideoMode(outWidth*scaling, outHeight*scaling, 8, videoflags);
63 SDL_SetColors(surface, sdlPalette, 0, 256);
65 if (!surface)
66 error("setting video mode");
69 void SdlScreen::setPalette(unsigned char *palette) {
70 for(int i=0;i<256;i++) {
71 sdlPalette[i].r = palette[i*3+0];
72 sdlPalette[i].g = palette[i*3+1];
73 sdlPalette[i].b = palette[i*3+2];
76 SDL_SetColors(surface, sdlPalette, 0, 256);
79 bool SdlScreen::init(int xHint,int yHint,int width,int height,bool fullscreen)
81 Uint32 videoflags;
83 outWidth = width;
84 outHeight = height;
85 ::fullscreen = fullscreen;
87 /* Initialize SDL */
88 if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
89 char str[1000];
90 printf(str, "Could not initialize SDL library: %s\n",SDL_GetError());
91 return false;
94 SDL_WM_SetCaption("Synaesthesia","synaesthesia");
96 createSurface();
98 SDL_EnableUNICODE(1);
99 SDL_ShowCursor(0);
101 return true;
104 void SdlScreen::end(void) {
105 SDL_Quit();
108 void SdlScreen::toggleFullScreen(void) {
109 fullscreen = !fullscreen;
110 createSurface();
113 void SdlScreen::inputUpdate(int &mouseX,int &mouseY,int &mouseButtons,char &keyHit) {
114 SDL_Event event;
115 bool resized = false;
117 keyHit = 0;
119 while ( SDL_PollEvent(&event) > 0 ) {
120 switch (event.type) {
121 case SDL_MOUSEBUTTONUP:
122 case SDL_MOUSEBUTTONDOWN:
123 if ( event.button.state == SDL_PRESSED )
124 mouseButtons |= 1 << event.button.button;
125 else
126 mouseButtons &= ~( 1 << event.button.button );
127 mouseX = event.button.x / scaling;
128 mouseY = event.button.y / scaling;
129 break;
130 case SDL_MOUSEMOTION :
131 mouseX = event.motion.x / scaling;
132 mouseY = event.motion.y / scaling;
133 break;
134 case SDL_ACTIVEEVENT :
135 /* Lost focus, hide mouse */
136 if (!event.active.gain) {
137 mouseX = outWidth;
138 mouseY = outHeight;
140 case SDL_KEYDOWN:
141 ///* Ignore key releases */
142 //if ( event.key.state == SDL_RELEASED ) {
143 // break;
145 /* Ignore ALT-TAB for windows */
146 if ( (event.key.keysym.sym == SDLK_LALT) ||
147 (event.key.keysym.sym == SDLK_TAB) ) {
148 break;
151 if (event.key.keysym.unicode > 255)
152 break;
154 keyHit = event.key.keysym.unicode;
155 return;
156 case SDL_VIDEORESIZE:
157 event.resize.w &= ~3;
158 allocOutput(event.resize.w,event.resize.h);
159 createSurface();
160 break;
161 case SDL_QUIT:
162 keyHit = 'q';
163 return;
164 default:
165 break;
170 void SdlScreen::show(void) {
171 attempt(SDL_LockSurface(surface),"locking screen for output.");
173 if (scaling == 1) {
174 register uint32_t *ptr2 = (uint32_t*)output;
175 uint32_t *ptr1 = (uint32_t*)( surface->pixels );
176 int i = outWidth*outHeight/sizeof(*ptr2);
178 do {
179 // Asger Alstrup Nielsen's (alstrup@diku.dk)
180 // optimized 32 bit screen loop
181 register unsigned int const r1 = *(ptr2++);
182 register unsigned int const r2 = *(ptr2++);
184 //if (r1 || r2) {
185 #ifdef LITTLEENDIAN
186 register unsigned int const v =
187 ((r1 & 0x000000f0ul) >> 4)
188 | ((r1 & 0x0000f000ul) >> 8)
189 | ((r1 & 0x00f00000ul) >> 12)
190 | ((r1 & 0xf0000000ul) >> 16);
191 *(ptr1++) = v |
192 ( ((r2 & 0x000000f0ul) << 12)
193 | ((r2 & 0x0000f000ul) << 8)
194 | ((r2 & 0x00f00000ul) << 4)
195 | ((r2 & 0xf0000000ul)));
196 #else
197 register unsigned int const v =
198 ((r2 & 0x000000f0ul) >> 4)
199 | ((r2 & 0x0000f000ul) >> 8)
200 | ((r2 & 0x00f00000ul) >> 12)
201 | ((r2 & 0xf0000000ul) >> 16);
202 *(ptr1++) = v |
203 ( ((r1 & 0x000000f0ul) << 12)
204 | ((r1 & 0x0000f000ul) << 8)
205 | ((r1 & 0x00f00000ul) << 4)
206 | ((r1 & 0xf0000000ul)));
207 #endif
208 //} else ptr1++;
209 } while (--i);
211 } else {
212 // SDL has no standard image scaling routine (!)
213 uint8_t *pixels = (uint8_t*)(surface->pixels);
214 for(int y=0;y<outHeight;y++) {
215 uint32_t *p1 = (uint32_t*)(output+y*outWidth*2);
216 uint32_t *p2 = (uint32_t*)(pixels+y*2*outWidth*2);
217 uint32_t *p3 = (uint32_t*)(pixels+(y*2+1)*outWidth*2);
218 for(int x=0;x<outWidth;x+=2) {
219 uint32_t v = *(p1++);
220 v = ((v&0x000000f0) >> 4)
221 | ((v&0x0000f000) >> 8)
222 | ((v&0x00f00000) >> 4)
223 | ((v&0xf0000000) >> 8);
224 v |= v<<8;
225 *(p2++) = v;
226 *(p3++) = v;
231 SDL_UnlockSurface(surface);
233 //SDL_UpdateRect(surface, 0, 0, 0, 0);
234 SDL_Flip(surface);
237 #endif