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

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