25f2964ea7ef1d1b18027fc15152613091b5f580
[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         // Enter key on acess returns \n, but SDL returns \r
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_UP:   ret = KEYSYM_UPARROW;   break;
83         case SDLK_DOWN: ret = KEYSYM_DOWNARROW; break;
84         case SDLK_LEFT: ret = KEYSYM_LEFTARROW; break;
85         case SDLK_RIGHT:ret = KEYSYM_RIGHTARROW;break;
86         case SDLK_CAPSLOCK:     ret = KEYSYM_CAPS;      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_RALT: ret = KEYSYM_RIGHTALT;  break;
102         case SDLK_LSUPER:       ret = KEYSYM_LEFTGUI;   break;
103         default:
104                 printf("Unhandled key code %i\n", Sym);
105                 break;
106         }
107         
108         gUI_Keymap[shiftState][Sym] = ret;
109         return ret;
110 }
111
112 void UI_MainLoop(void)
113 {
114         SDL_Event       event;
115         Uint32  acess_sym;
116
117         for( ;; )
118         {
119                 while(SDL_PollEvent(&event))
120                 {
121                         switch(event.type)
122                         {
123                         case SDL_QUIT:
124                                 AcessNative_Exit();
125                                 return ;
126                                 
127                         case SDL_KEYDOWN:
128                                 acess_sym = UI_GetAcessKeyFromSDL(event.key.keysym.sym);
129                                 
130                                 if( gUI_KeyboardCallback ) {
131                                         gUI_KeyboardCallback(KEY_ACTION_RAWSYM|acess_sym);
132                                         gUI_KeyboardCallback(KEY_ACTION_PRESS|event.key.keysym.unicode);
133                                 }
134                                 break;
135                         
136                         case SDL_KEYUP:
137                                 acess_sym = UI_GetAcessKeyFromSDL(event.key.keysym.sym);
138                                 
139                                 if( gUI_KeyboardCallback ) {
140                                         gUI_KeyboardCallback(KEY_ACTION_RAWSYM|acess_sym);
141                                         gUI_KeyboardCallback(KEY_ACTION_RELEASE|0);
142                                 }
143                                 break;
144
145                         case SDL_USEREVENT:
146                                 SDL_UpdateRect(gScreen, 0, 0, giUI_Width, giUI_Height);
147                                 SDL_Flip(gScreen);
148                                 break;          
149         
150                         default:
151                                 break;
152                         }
153                 }
154         }
155 }
156
157 void UI_BlitBitmap(int DstX, int DstY, int SrcW, int SrcH, Uint32 *Bitmap)
158 {
159         SDL_Surface     *tmp;
160         SDL_Rect        dstRect;
161         
162 //      printf("UI_BlitBitmap: Blit to (%i,%i) from %p (%ix%i 32bpp bitmap)\n",
163 //              DstX, DstY, Bitmap, SrcW, SrcH);
164         
165         tmp = SDL_CreateRGBSurfaceFrom(Bitmap, SrcW, SrcH, 32, SrcW*4,
166                 0xFF0000, 0x00FF00, 0x0000FF, 0xFF000000);
167         SDL_SetAlpha(tmp, 0, SDL_ALPHA_OPAQUE);
168         
169         dstRect.x = DstX;       dstRect.y = DstY;
170         dstRect.w = -1; dstRect.h = -1;
171         
172         SDL_BlitSurface(tmp, NULL, gScreen, &dstRect);
173         //SDL_BlitSurface(tmp, NULL, gScreen, NULL);
174         
175         SDL_FreeSurface(tmp);
176 //      SDL_Flip(gScreen);
177 }
178
179 void UI_BlitFramebuffer(int DstX, int DstY, int SrcX, int SrcY, int W, int H)
180 {
181         SDL_Rect        srcRect;
182         SDL_Rect        dstRect;
183         
184         srcRect.x = SrcX;       srcRect.y = SrcY;
185         srcRect.w = W;  srcRect.h = H;
186         dstRect.x = DstX;       dstRect.y = DstY;
187         
188         SDL_BlitSurface(gScreen, &srcRect, gScreen, &dstRect); 
189 }
190
191 void UI_FillBitmap(int X, int Y, int W, int H, Uint32 Value)
192 {
193         SDL_Rect        dstRect;
194         
195         dstRect.x = X;  dstRect.y = Y;
196         dstRect.w = W;  dstRect.h = H;
197         
198 //      printf("UI_FillBitmap: gScreen = %p\n", gScreen);
199         SDL_FillRect(gScreen, &dstRect, Value);
200 }
201
202 void UI_Redraw(void)
203 {
204         // TODO: Keep track of changed rectangle
205 //      SDL_UpdateRect(gScreen, 0, 0, giUI_Width, giUI_Height);
206         SDL_Event       e;
207
208         e.type = SDL_USEREVENT;
209         e.user.code = 0;
210         e.user.data1 = 0;
211         e.user.data2 = 0;       
212
213         SDL_PushEvent( &e );
214 }

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