Modules - Use short command annotation in makefile ([CC] not $(CC))
[tpg/acess2.git] / AcessNative / acesskernel_src / ui_sdl.c
1 /*
2  * Acess2 Native Kernel
3  * 
4  * SDL User Interface
5  */
6 #include <SDL/SDL.h>
7 #define const
8 #include "ui.h"
9 #undef const
10 #include <api_drv_keyboard.h>
11
12 // === IMPORTS ===
13 extern void     AcessNative_Exit(void);
14
15 // === PROTOTYPES ===
16  int    UI_Initialise(int MaxWidth, int MaxHeight);
17 void    UI_BlitBitmap(int DstX, int DstY, int SrcW, int SrcH, Uint32 *Bitmap);
18 void    UI_BlitFramebuffer(int DstX, int DstY, int SrcX, int SrcY, int W, int H);
19 void    UI_FillBitmap(int X, int Y, int W, int H, Uint32 Value);
20 void    UI_Redraw(void);
21
22 // === GLOBALS ===
23 SDL_Surface     *gScreen;
24 SDL_Thread      *gInputThread;
25  int    giUI_Width = 0;
26  int    giUI_Height = 0;
27  int    giUI_Pitch = 0;
28 tUI_KeybardCallback     gUI_KeyboardCallback;
29 Uint32  gUI_Keymap[2][SDLK_LAST];       // Upper/Lower case
30  int    gbUpdateTriggered = 0;
31
32 // === FUNCTIONS ===
33 int UI_Initialise(int MaxWidth, int MaxHeight)
34 {       
35         // Changed when the video mode is set
36         giUI_Width = MaxWidth;
37         giUI_Height = MaxHeight;
38         
39         // Set up video
40         SDL_Init(SDL_INIT_VIDEO);
41         printf("UI attempting %ix%i %ibpp\n", giUI_Width, giUI_Height, 32);
42         gScreen = SDL_SetVideoMode(giUI_Width, giUI_Height, 32, SDL_DOUBLEBUF);
43         if( !gScreen ) {
44                 fprintf(stderr, "Couldn't set %ix%i video mode: %s\n", giUI_Width, giUI_Height, SDL_GetError());
45                 SDL_Quit();
46                 exit(2);
47         }
48         SDL_WM_SetCaption("Acess2", "Acess2");
49         
50         giUI_Width = gScreen->w;
51         giUI_Height = gScreen->h;
52         giUI_Pitch = gScreen->pitch;
53
54         printf("UI window %ix%i %i bytes per line\n", giUI_Width, giUI_Height, giUI_Pitch);
55         
56         SDL_EnableUNICODE(1);
57
58         return 0;
59 }
60
61 Uint32 UI_GetAcessKeyFromSDL(SDLKey Sym)
62 {
63         Uint8   *keystate = SDL_GetKeyState(NULL);
64          int    shiftState = 0;
65         Uint32  ret = 0;
66         
67         if( keystate[SDLK_RSHIFT] || keystate[SDLK_LSHIFT] )
68                 shiftState = 1;
69         
70         // Fast return
71         if( gUI_Keymap[shiftState][Sym] )
72                 return gUI_Keymap[shiftState][Sym];
73
74         switch(Sym)
75         {
76         case SDLK_a ... SDLK_z:
77                 ret = Sym - SDLK_a + KEYSYM_a;
78                 break;
79         case SDLK_0 ... SDLK_9:
80                 ret = Sym - SDLK_0 + KEYSYM_0;
81                 break;
82         case SDLK_SLASH:        ret = KEYSYM_SLASH;     break;
83         case SDLK_CAPSLOCK:     ret = KEYSYM_CAPS;      break;
84         case SDLK_TAB:  ret = KEYSYM_TAB;       break;
85         case SDLK_UP:   ret = KEYSYM_UPARROW;   break;
86         case SDLK_DOWN: ret = KEYSYM_DOWNARROW; break;
87         case SDLK_LEFT: ret = KEYSYM_LEFTARROW; break;
88         case SDLK_RIGHT:ret = KEYSYM_RIGHTARROW;break;
89         case SDLK_F1:   ret = KEYSYM_F1;        break;
90         case SDLK_F2:   ret = KEYSYM_F2;        break;
91         case SDLK_F3:   ret = KEYSYM_F3;        break;
92         case SDLK_F4:   ret = KEYSYM_F4;        break;
93         case SDLK_F5:   ret = KEYSYM_F5;        break;
94         case SDLK_F6:   ret = KEYSYM_F6;        break;
95         case SDLK_F7:   ret = KEYSYM_F7;        break;
96         case SDLK_F8:   ret = KEYSYM_F8;        break;
97         case SDLK_F9:   ret = KEYSYM_F9;        break;
98         case SDLK_F10:  ret = KEYSYM_F10;       break;
99         case SDLK_F11:  ret = KEYSYM_F11;       break;
100         case SDLK_F12:  ret = KEYSYM_F12;       break;
101         case SDLK_RETURN:       ret = KEYSYM_RETURN;    break;
102         case SDLK_LALT:         ret = KEYSYM_LEFTALT;   break;
103         case SDLK_LCTRL:        ret = KEYSYM_LEFTCTRL;  break;
104         case SDLK_LSHIFT:       ret = KEYSYM_LEFTSHIFT; break;
105         case SDLK_LSUPER:       ret = KEYSYM_LEFTGUI;   break;
106         case SDLK_RALT:         ret = KEYSYM_RIGHTALT;  break;
107         case SDLK_RCTRL:        ret = KEYSYM_RIGHTCTRL; break;
108         case SDLK_RSHIFT:       ret = KEYSYM_RIGHTSHIFT;        break;
109         case SDLK_RSUPER:       ret = KEYSYM_RIGHTGUI;  break;
110         case SDLK_BACKSPACE:    ret = KEYSYM_BACKSP;    break;
111         default:
112                 printf("Unhandled key code %i\n", Sym);
113                 break;
114         }
115         
116         gUI_Keymap[shiftState][Sym] = ret;
117         return ret;
118 }
119
120 Uint32 UI_GetButtonBits(Uint8 sdlstate)
121 {
122         Uint32  rv = 0;
123         rv |= sdlstate & SDL_BUTTON(SDL_BUTTON_LEFT)    ? (1 << 0) : 0;
124         rv |= sdlstate & SDL_BUTTON(SDL_BUTTON_RIGHT)   ? (1 << 1) : 0;
125         rv |= sdlstate & SDL_BUTTON(SDL_BUTTON_MIDDLE)  ? (1 << 2) : 0;
126         rv |= sdlstate & SDL_BUTTON(SDL_BUTTON_X1)      ? (1 << 3) : 0;
127         rv |= sdlstate & SDL_BUTTON(SDL_BUTTON_X2)      ? (1 << 4) : 0;
128         return rv;
129 }
130
131 void UI_MainLoop(void)
132 {
133         SDL_Event       event;
134         Uint32  acess_sym;
135
136         while( SDL_WaitEvent(&event) )
137         {
138                 switch(event.type)
139                 {
140                 case SDL_QUIT:
141                         AcessNative_Exit();
142                         return ;
143                         
144                 case SDL_KEYDOWN:
145                         acess_sym = UI_GetAcessKeyFromSDL(event.key.keysym.sym);
146                         // Enter key on acess returns \n, but SDL returns \r
147                         if(event.key.keysym.sym == SDLK_RETURN)
148                                 event.key.keysym.unicode = '\n';                                
149
150                         if( gUI_KeyboardCallback ) {
151                                 gUI_KeyboardCallback(KEY_ACTION_RAWSYM|acess_sym);
152                                 gUI_KeyboardCallback(KEY_ACTION_PRESS|event.key.keysym.unicode);
153                         }
154                         break;
155                 
156                 case SDL_KEYUP:
157                         acess_sym = UI_GetAcessKeyFromSDL(event.key.keysym.sym);
158                         
159                         if( gUI_KeyboardCallback ) {
160                                 gUI_KeyboardCallback(KEY_ACTION_RAWSYM|acess_sym);
161                                 gUI_KeyboardCallback(KEY_ACTION_RELEASE|0);
162                         }
163                         break;
164
165                 case SDL_USEREVENT:
166                         if( gbUpdateTriggered )
167                         {
168                                 gbUpdateTriggered = 0;
169                                 SDL_UpdateRect(gScreen, 0, 0, giUI_Width, giUI_Height);
170                                 SDL_Flip(gScreen);
171                         }
172                         break;
173                 
174                 case SDL_MOUSEMOTION: {
175                         int abs[] = {event.motion.x, event.motion.y};
176                         int delta[] = {event.motion.xrel, event.motion.yrel};
177                         Mouse_HandleEvent(UI_GetButtonBits(SDL_GetMouseState(NULL, NULL)), delta, abs);
178                         break; }
179                 case SDL_MOUSEBUTTONUP:
180                 case SDL_MOUSEBUTTONDOWN: {
181                         int abs[] = {event.button.x, event.button.y};
182                         Mouse_HandleEvent(UI_GetButtonBits(SDL_GetMouseState(NULL, NULL)), NULL, abs);
183                         break; }
184
185                 default:
186                         break;
187                 }
188         }
189 }
190
191 void UI_BlitBitmap(int DstX, int DstY, int SrcW, int SrcH, Uint32 *Bitmap)
192 {
193         SDL_Surface     *tmp;
194         SDL_Rect        dstRect;
195         
196 //      printf("UI_BlitBitmap: Blit to (%i,%i) from %p (%ix%i 32bpp bitmap)\n",
197 //              DstX, DstY, Bitmap, SrcW, SrcH);
198         
199         tmp = SDL_CreateRGBSurfaceFrom(Bitmap, SrcW, SrcH, 32, SrcW*4,
200                 0xFF0000, 0x00FF00, 0x0000FF, 0xFF000000);
201         SDL_SetAlpha(tmp, 0, SDL_ALPHA_OPAQUE);
202         
203         dstRect.x = DstX;       dstRect.y = DstY;
204         dstRect.w = -1; dstRect.h = -1;
205         
206         SDL_BlitSurface(tmp, NULL, gScreen, &dstRect);
207         //SDL_BlitSurface(tmp, NULL, gScreen, NULL);
208         
209         SDL_FreeSurface(tmp);
210 //      SDL_Flip(gScreen);
211 }
212
213 void UI_BlitFramebuffer(int DstX, int DstY, int SrcX, int SrcY, int W, int H)
214 {
215         SDL_Rect        srcRect;
216         SDL_Rect        dstRect;
217         
218         srcRect.x = SrcX;       srcRect.y = SrcY;
219         srcRect.w = W;  srcRect.h = H;
220         dstRect.x = DstX;       dstRect.y = DstY;
221         
222         SDL_BlitSurface(gScreen, &srcRect, gScreen, &dstRect); 
223 }
224
225 void UI_FillBitmap(int X, int Y, int W, int H, Uint32 Value)
226 {
227         SDL_Rect        dstRect;
228         
229         dstRect.x = X;  dstRect.y = Y;
230         dstRect.w = W;  dstRect.h = H;
231         
232 //      printf("UI_FillBitmap: gScreen = %p\n", gScreen);
233         SDL_FillRect(gScreen, &dstRect, Value);
234 }
235
236 void UI_Redraw(void)
237 {
238         // TODO: Keep track of changed rectangle
239 //      SDL_UpdateRect(gScreen, 0, 0, giUI_Width, giUI_Height);
240         if( gbUpdateTriggered == 0 )
241         {
242                 gbUpdateTriggered = 1;
243                 SDL_Event       e;
244
245                 e.type = SDL_USEREVENT;
246                 e.user.code = 0;
247                 e.user.data1 = 0;
248                 e.user.data2 = 0;       
249
250                 SDL_PushEvent( &e );
251         }
252 }

UCC git Repository :: git.ucc.asn.au