Mercurial > sdl-ios-xcode
diff test/threadwin.c @ 0:74212992fb08
Initial revision
author | Sam Lantinga <slouken@lokigames.com> |
---|---|
date | Thu, 26 Apr 2001 16:45:43 +0000 |
parents | |
children | cb40b26523a5 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/threadwin.c Thu Apr 26 16:45:43 2001 +0000 @@ -0,0 +1,307 @@ + +/* Test out the multi-threaded event handling functions */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "SDL.h" +#include "SDL_thread.h" + +/* Are we done yet? */ +static int done = 0; + +/* Is the cursor visible? */ +static int visible = 1; + +SDL_Surface *LoadIconSurface(char *file, Uint8 **maskp) +{ + SDL_Surface *icon; + Uint8 *pixels; + Uint8 *mask; + int mlen, i; + + *maskp = NULL; + + /* Load the icon surface */ + icon = SDL_LoadBMP(file); + if ( icon == NULL ) { + fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError()); + return(NULL); + } + + /* Check width and height */ + if ( (icon->w%8) != 0 ) { + fprintf(stderr, "Icon width must be a multiple of 8!\n"); + SDL_FreeSurface(icon); + return(NULL); + } + if ( icon->format->palette == NULL ) { + fprintf(stderr, "Icon must have a palette!\n"); + SDL_FreeSurface(icon); + return(NULL); + } + + /* Set the colorkey */ + SDL_SetColorKey(icon, SDL_SRCCOLORKEY, *((Uint8 *)icon->pixels)); + + /* Create the mask */ + pixels = (Uint8 *)icon->pixels; + printf("Transparent pixel: (%d,%d,%d)\n", + icon->format->palette->colors[*pixels].r, + icon->format->palette->colors[*pixels].g, + icon->format->palette->colors[*pixels].b); + mlen = icon->w*icon->h; + mask = (Uint8 *)malloc(mlen/8); + if ( mask == NULL ) { + fprintf(stderr, "Out of memory!\n"); + SDL_FreeSurface(icon); + return(NULL); + } + memset(mask, 0, mlen/8); + for ( i=0; i<mlen; ) { + if ( pixels[i] != *pixels ) + mask[i/8] |= 0x01; + ++i; + if ( (i%8) != 0 ) + mask[i/8] <<= 1; + } + *maskp = mask; + return(icon); +} + +int FilterEvents(const SDL_Event *event) +{ + static int reallyquit = 0; + + switch (event->type) { + + case SDL_ACTIVEEVENT: + /* See what happened */ + printf("App %s ", + event->active.gain ? "gained" : "lost"); + if ( event->active.state & SDL_APPACTIVE ) + printf("active "); + if ( event->active.state & SDL_APPMOUSEFOCUS ) + printf("mouse "); + if ( event->active.state & SDL_APPINPUTFOCUS ) + printf("input "); + printf("focus\n"); + + /* See if we are iconified or restored */ + if ( event->active.state & SDL_APPACTIVE ) { + printf("App has been %s\n", + event->active.gain ? + "restored" : "iconified"); + } + return(0); + + /* This is important! Queue it if we want to quit. */ + case SDL_QUIT: + if ( ! reallyquit ) { + reallyquit = 1; + printf("Quit requested\n"); + return(0); + } + printf("Quit demanded\n"); + return(1); + + /* Mouse and keyboard events go to threads */ + case SDL_MOUSEMOTION: + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + case SDL_KEYDOWN: + case SDL_KEYUP: + return(1); + + /* Drop all other events */ + default: + return(0); + } +} + +int HandleMouse(void *unused) +{ + SDL_Event events[10]; + int i, found; + Uint32 mask; + + /* Handle mouse events here */ + mask = (SDL_MOUSEMOTIONMASK|SDL_MOUSEBUTTONDOWNMASK|SDL_MOUSEBUTTONUPMASK); + while ( ! done ) { + found = SDL_PeepEvents(events, 10, SDL_GETEVENT, mask); + for ( i=0; i<found; ++i ) { + switch(events[i].type) { + /* We want to toggle visibility on buttonpress */ + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + if ( events[i].button.state == SDL_PRESSED ) { + visible = !visible; + SDL_ShowCursor(visible); + } + printf("Mouse button %d has been %s\n", + events[i].button.button, + (events[i].button.state == SDL_PRESSED) ? + "pressed" : "released"); + break; + /* Show relative mouse motion */ + case SDL_MOUSEMOTION: + printf("Mouse relative motion: {%d,%d}\n", + events[i].motion.xrel, events[i].motion.yrel); + break; + } + } + /* Give up some CPU to allow events to arrive */ + SDL_Delay(20); + } + return(0); +} + +int HandleKeyboard(void *unused) +{ + SDL_Event events[10]; + int i, found; + Uint32 mask; + + /* Handle mouse events here */ + mask = (SDL_KEYDOWNMASK|SDL_KEYUPMASK); + while ( ! done ) { + found = SDL_PeepEvents(events, 10, SDL_GETEVENT, mask); + for ( i=0; i<found; ++i ) { + switch(events[i].type) { + /* We want to toggle visibility on buttonpress */ + case SDL_KEYDOWN: + case SDL_KEYUP: + /* Allow hitting <ESC> to quit the app */ + if ( events[i].key.keysym.sym == SDLK_ESCAPE ) { + done = 1; + } + printf("Key '%c' has been %s\n", + events[i].key.keysym.unicode, + (events[i].key.state == SDL_PRESSED) ? + "pressed" : "released"); + break; + } + } + /* Give up some CPU to allow events to arrive */ + SDL_Delay(20); + } + return(0); +} + +int main(int argc, char *argv[]) +{ + SDL_Surface *screen; + SDL_Surface *icon; + Uint8 *icon_mask; + int i, parsed; + Uint8 *buffer; + SDL_Color palette[256]; + Uint32 init_flags; + Uint8 video_bpp; + Uint32 video_flags; + SDL_Thread *mouse_thread; + SDL_Thread *keybd_thread; + + /* Set the options, based on command line arguments */ + init_flags = SDL_INIT_VIDEO; + video_bpp = 8; + video_flags = SDL_SWSURFACE; + parsed = 1; + while ( parsed ) { + /* If the threaded option is enabled, and the SDL library hasn't + been compiled with threaded events enabled, then the mouse and + keyboard won't respond. + */ + if ( (argc >= 2) && (strcmp(argv[1], "-threaded") == 0) ) { + init_flags |= SDL_INIT_EVENTTHREAD; + argc -= 1; + argv += 1; + printf("Running with threaded events\n"); + } else + if ( (argc >= 2) && (strcmp(argv[1], "-fullscreen") == 0) ) { + video_flags |= SDL_FULLSCREEN; + argc -= 1; + argv += 1; + } else + if ( (argc >= 3) && (strcmp(argv[1], "-bpp") == 0) ) { + video_bpp = atoi(argv[2]); + argc -= 2; + argv += 2; + } else { + parsed = 0; + } + } + + /* Initialize SDL with the requested flags */ + if ( SDL_Init(init_flags) < 0 ) { + fprintf(stderr, + "Couldn't initialize SDL: %s\n", SDL_GetError()); + exit(1); + } + atexit(SDL_Quit); + + /* Set the icon -- this must be done before the first mode set */ + icon = LoadIconSurface("icon.bmp", &icon_mask); + if ( icon != NULL ) { + SDL_WM_SetIcon(icon, icon_mask); + } + if ( icon_mask != NULL ) + free(icon_mask); + + /* Initialize the display */ + screen = SDL_SetVideoMode(640, 480, video_bpp, video_flags); + if ( screen == NULL ) { + fprintf(stderr, "Couldn't set 640x480x%d video mode: %s\n", + video_bpp, SDL_GetError()); + exit(1); + } + printf("Running in %s mode\n", screen->flags & SDL_FULLSCREEN ? + "fullscreen" : "windowed"); + + /* Enable printable characters */ + SDL_EnableUNICODE(1); + + /* Set an event filter that discards everything but QUIT */ + SDL_SetEventFilter(FilterEvents); + + /* Create the event handling threads */ + mouse_thread = SDL_CreateThread(HandleMouse, NULL); + keybd_thread = SDL_CreateThread(HandleKeyboard, NULL); + + /* Set the surface pixels and refresh! */ + for ( i=0; i<256; ++i ) { + palette[i].r = 255-i; + palette[i].g = 255-i; + palette[i].b = 255-i; + } + SDL_SetColors(screen, palette, 0, 256); + if ( SDL_LockSurface(screen) < 0 ) { + fprintf(stderr, "Couldn't lock display surface: %s\n", + SDL_GetError()); + exit(2); + } + buffer = (Uint8 *)screen->pixels; + for ( i=0; i<screen->h; ++i ) { + memset(buffer,(i*255)/screen->h, + screen->w*screen->format->BytesPerPixel); + buffer += screen->pitch; + } + SDL_UnlockSurface(screen); + SDL_UpdateRect(screen, 0, 0, 0, 0); + + /* Loop, waiting for QUIT */ + while ( ! done ) { + if ( ! (init_flags & SDL_INIT_EVENTTHREAD) ) { + SDL_PumpEvents(); /* Needed when event thread is off */ + } + if ( SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, SDL_QUITMASK) ) { + done = 1; + } + /* Give up some CPU so the events can accumulate */ + SDL_Delay(20); + } + SDL_WaitThread(mouse_thread, NULL); + SDL_WaitThread(keybd_thread, NULL); + return(0); +}