Results 1 to 9 of 9

Thread: SDL Threads

  1. #1

    SDL Threads

    Hi all. Im studying Threads. I tried to run some examples but one i didnt get.

    This example ok:
    Code:
    uses	
    	SDL;
    
      {$APPTYPE CONSOLE}
    var 	
    	thread: PSDL_Thread;
    	returnValue: Integer;
    
    function thread_func(): Integer;
    begin
    	// do threading here
    	WriteLn('Start Thread');
    	SDL_Delay(5000);
    	WriteLn('End Thread');
    
    	result := 1; // thread leaves and return this value
    end;
    
    begin
    	returnValue := 0;
    	thread := SDL_CreateThread(@thread_func, NIL);
    	
    	SDL_WaitThread(thread, returnValue);
    	WriteLn('Thread returns code ',returnValue);
    
    	SDL_Quit;
    	WriteLn('ByeBye ;)');
    end.
    But this, i get error. why? What is wrong? This example I ported from Lazy Foo's tutorial.
    Code:
    program teste;
    
    {$APPTYPE CONSOLE}
    
    uses
      sdl,
      sdlutils,
      sdl_image;
    
    
    const
       SCREEN_WIDTH = 640;
       SCREEN_HEIGHT = 480;
       SCREEN_BPP = 32;
    
    var
       screen,image: PSDL_Surface;
       event: TSDL_Event;
       thread: PSDL_Thread;
       quit: boolean = false;
    
    
    
    function load_image(filename: string; setcolorkey: boolean) : PSDL_Surface; overload;
    var
       optimizedImage, loadedImage: PSDL_Surface;
       r,g,b: uint8;
    
    begin
        loadedImage := IMG_Load(pchar(filename));
    
        if &#40;loadedImage <> nil&#41; then
        begin
            optimizedImage &#58;= SDL_DisplayFormat&#40;loadedimage&#41;;
            SDL_FreeSurface&#40;loadedimage&#41;;
            if &#40;optimizedImage <nil> 0&#41; do
            begin
                case event.type_ of
                   SDL_QUITEV&#58;
                        quit&#58;= true;
                end;
            end;
    		clean_up;
        end;
    
    end.
    Sorry my english.

  2. #2

    SDL Threads

    I dont know why the second code I posted is not completed. I think there are a bug in " [ code ] [ / code ]"

    The second code

    [pascal]
    program teste;

    {$APPTYPE CONSOLE}

    uses
    sdl,
    sdlutils,
    sdl_image;


    const
    SCREEN_WIDTH = 640;
    SCREEN_HEIGHT = 480;
    SCREEN_BPP = 32;

    var
    screen,image: PSDL_Surface;
    event: TSDL_Event;
    thread: PSDL_Thread;
    quit: boolean = false;



    procedure apply_surface(x, y: integer; source,destination: PSDL_Surface);
    var
    offset: SDL_Rect;

    begin
    //Get offsets
    offset.x := x;
    offset.y := y;

    //Blit
    SDL_BlitSurface( source, nil, destination, @offset );
    end;


    function init: boolean;
    begin
    //Initialize all SDL subsystems
    if( SDL_Init( SDL_INIT_EVERYTHING ) = -1 ) then
    begin
    result:= false;
    exit;
    end;

    //Set up the screen
    screen := SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );

    //If there was in error in setting up the screen
    if( screen = nil ) then
    begin
    result:= false;
    exit;
    end;

    //Set the window caption
    SDL_WM_SetCaption( 'Thread test', nil );

    //If everything initialized fine
    result:= true;
    end;


    function load_files: boolean;
    begin
    //Load the image
    image := load_image('image.png',true);

    //If there was an error in loading the image
    if( image = niL ) then
    begin
    result:= false;
    exit;
    end;

    //If everything loaded fine
    result:= true;
    end;

    procedure clean_up;
    begin
    //Stop the thread
    SDL_KillThread( thread );

    //Free the surface
    SDL_FreeSurface( image );

    //Quit SDL
    SDL_Quit();
    end;

    function my_thread(): integer;
    begin
    //While the program is not over
    while( quit = false ) do
    begin
    //Do the caption animation
    SDL_WM_SetCaption( 'Thread is running', nil );
    SDL_Delay( 250 );

    SDL_WM_SetCaption( 'Thread is running.', nil );
    SDL_Delay( 250 );

    SDL_WM_SetCaption( 'Thread is running..', nil );
    SDL_Delay( 250 );

    SDL_WM_SetCaption( 'Thread is running...', nil );
    SDL_Delay( 250 );
    end;

    result:= 0;
    end;


    begin
    //Initialize
    if (init = false ) then
    begin
    exit;
    end;

    //Load the files
    if( load_files = false ) then
    begin
    exit;
    end;

    //Create and run the thread
    thread := SDL_CreateThread(@my_thread, nil );

    //Apply the image to the screen
    apply_surface( 0, 0, image, screen);

    //Update the screen
    if( SDL_Flip( screen ) = -1 ) then
    begin
    exit;
    end;


    while (quit = false) do
    begin
    while (SDL_PollEvent(@event) > 0) do
    begin
    case event.type_ of
    SDL_QUITEV:
    quit:= true;
    end;
    end;
    clean_up;
    end;

    end.
    [/pascal]

  3. #3

    SDL Threads

    I founded the error.

    ops: ops: ops:

  4. #4

    SDL Threads

    Quote Originally Posted by maker3
    I founded the error.

    ops: ops: ops:
    The fact that your returning false from your thread method instead of 1 to let SDL know that you initialized the thread properly? If not, post your solution to help others out too

  5. #5

    SDL Threads

    Hi jdarling.

    The problem is the function clean_up. It must be out the while loop. ops:
    I dont know why I posted it there.

    [pascal]

    ...

    while (quit = false) do
    begin
    while (SDL_PollEvent(@event) > 0) do
    begin
    case event.type_ of
    SDL_QUITEV:
    quit:= true;
    end;
    end;
    end;
    clean_up;
    end.
    [/pascal]


    I have translated the "Fast Event Processing in SDL" (Bob Pendleton - about using Threads) from http://www.gameprogrammer.com/fastev...stevents1.html. But is not correct yet. I will post soon when I finish.

  6. #6

    SDL Threads

    I have already converted that code to pascal. I just havne't got round to adding it to the JEDI-SDL stuff yet... sorry ops:

    [pascal]
    unit FastEvents;

    interface

    uses SDL;

    const

    FASTEVENT_ERROR = -1;
    FASTEVENT_OK = 0;

    procedure Fast_PumpEvents;
    function Fast_PollEvent(Event: PSDL_Event): UInt32;
    function Fast_WaitEvent(Event: PSDL_Event): UInt32;
    function Fast_PushEvent(Event: PSDL_Event): UInt32;

    function Fast_GetError: string;

    implementation

    var
    EventLock: PSDL_Mutex;
    EventWait: PSDL_cond;
    EventTimer: PSDL_TimerID;
    Error: string;

    {------------------------------------------------------------------------------}
    {Thread Safe Pump Events}
    {------------------------------------------------------------------------------}
    procedure Fast_PumpEvents;
    begin
    SDL_LockMutex(eventLock);
    SDL_PumpEvents();
    SDL_UnlockMutex(eventLock);
    end;

    {------------------------------------------------------------------------------}
    {Poll Event Wrapper}
    {------------------------------------------------------------------------------}
    function Fast_PollEvent(Event: PSDL_Event): UInt32;
    begin
    SDL_LockMutex(eventLock);
    Result := SDL_PollEvent(event);
    SDL_UnlockMutex(eventLock);
    if (Result > 0) then
    begin
    SDL_CondSignal(eventWait);
    end
    end;

    {------------------------------------------------------------------------------}
    {Wait Event Wrapper}
    {------------------------------------------------------------------------------}
    function Fast_WaitEvent(Event: PSDL_Event): UInt32;
    begin
    Result := 0;
    SDL_LockMutex(eventLock);
    while (SDL_PollEvent(event) <= 0) do
    begin
    SDL_CondWait(eventWait, eventLock);
    end;
    SDL_UnlockMutex(eventLock);
    SDL_CondSignal(eventWait);
    end;

    {------------------------------------------------------------------------------}
    {Push Event Wrapper}
    {------------------------------------------------------------------------------}
    function Fast_PushEvent(Event: PSDL_Event): UInt32;
    begin
    SDL_LockMutex(EventLock);
    while (SDL_PushEvent(Event) <= 0) do
    begin
    SDL_CondWait(eventWait, eventLock);
    end;
    SDL_UnlockMutex(eventLock);
    SDL_CondSignal(eventWait);
    Result := 1;
    end;

    {------------------------------------------------------------------------------}
    {Get Error function }
    {------------------------------------------------------------------------------}
    function Fast_GetError: string;
    begin
    Result := Error;
    end;

    procedure Fast_SetError(const Value: string);
    begin
    Error := Value;
    end;

    {------------------------------------------------------------------------------}
    {Time Callback to wake up all waiting threads}
    {------------------------------------------------------------------------------}
    function timerCallback(interval: UInt32; param: Pointer): UInt32;
    cdecl;
    begin
    SDL_CondBroadcast(EventWait);
    Result := interval;
    end;

    {------------------------------------------------------------------------------}
    {Initialization- creates timers and mutexs}
    {------------------------------------------------------------------------------}
    function FastEventsInit: Integer;
    begin
    Result := FASTEVENT_ERROR;
    if (SDL_INIT_TIMER and SDL_WasInit(SDL_INIT_TIMER) = 0) then
    begin
    SDL_InitSubSystem(SDL_INIT_TIMER);
    end;
    EventLock := SDL_CreateMutex;
    if (EventLock = nil) then
    begin
    Fast_SetError('Fast Events: cannot create a mutex');
    Exit;
    end;
    EventWait := SDL_CreateCond();
    if (EventWait = nil) then
    begin
    Fast_SetError('Fast Events: cannot create a condition variable');
    Exit;
    end;
    EventTimer := SDL_AddTimer(10, timerCallback, nil);
    if (EventTimer = nil) then
    begin
    Fast_SetError('Fast Events: cannot add a timer');
    Exit;
    end;
    Result := FASTEVENT_OK;
    end;

    {------------------------------------------------------------------------------}
    {Clean Up}
    {------------------------------------------------------------------------------}
    procedure FastEventsQuit;
    begin
    SDL_DestroyMutex(eventLock);
    eventLock := nil;
    SDL_DestroyCond(eventWait);
    eventWait := nil;
    SDL_RemoveTimer(eventTimer);
    end;


    initialization

    FastEventsInit;

    finalization

    FastEventsQuit;

    end.
    [/pascal]
    <A HREF="http://www.myhpf.co.uk/banner.asp?friend=139328">
    <br /><IMG SRC="http://www.myhpf.co.uk/banners/60x468.gif" BORDER="0">
    <br /></A>

  7. #7

    SDL Threads

    Omg technomage oO

    Its great. I will look later.

    technomage, im looking for Network lib (UDP reliable) for my project too. I saw your article and I ask: SDL_net is a good alternative? Its not safe thread. There are another option? Indy is a good option? I would like to use one and implement the "UDP reliable". This same site there are the NET2, (a fast threaded event based networking - a second layer above SDL_net). But, I dont know where I may go. SDL_net? Indy? ...? I would like it can be to compiled in win / linux.

    Sorry my english.

  8. #8

    SDL Threads

    I have translated quickly the thread4 to us can test the fastevents. But I think there are something wrong with the fastevents translated. It crash on the finalization.


    fastevents.pas:
    [pascal]

    ...

    {------------------------------------------------------------------------------}
    {Clean Up}
    {------------------------------------------------------------------------------}
    procedure FastEventsQuit;
    begin
    SDL_DestroyMutex(eventLock);
    eventLock := nil;
    SDL_DestroyCond(eventWait);
    eventWait := nil; <= crash here
    SDL_RemoveTimer(eventTimer);
    end;
    [/pascal]


    Thread4.pas:
    [pascal]
    program thread4;

    {$APPTYPE CONSOLE}

    uses
    Sysutils,sdl,fastevents;

    var
    doneYet: integer = 0;
    num: integer = 0;

    type
    nameValue = record
    value: Uint32;
    name: string;
    end;

    const
    appFlags: array[0..2] of namevalue = (
    (valueDL_APPMOUSEFOCUS; name: 'SDL_APPMOUSEFOCUS'),
    (valueDL_APPINPUTFOCUS; name: 'SDL_APPINPUTFOCUS'),
    (valueDL_APPACTIVE; name: 'SDL_APPACTIVE')
    );
    numAppFlags = sizeof(appFlags) div sizeof(nameValue);


    procedure printSDLEvent(e: PSDL_Event);
    var
    sym: PSDL_keysym;
    i: integer;

    begin
    i:= 0;

    case (e.type_) of
    SDL_ACTIVEEVENT: //* Application loses/gains visibility */
    begin
    writeln('SDL_ACTIVEEVENT');
    writeln(' gain =', e.active.gain);
    writeln(' state =', e.active.state);
    for i := 0 to numAppFlags-1 do
    begin
    if (0 <> (appFlags[i].value and e.active.state)) then
    begin
    writeln(Format(' =%02x,%s', [appFlags[i].value, appFlags[i].name]));
    end;
    end;
    end;
    SDL_KEYDOWN: //* Keys pressed */
    begin
    sym := @e.key.keysym;
    writeln('SDL_KEYDOWN');
    writeln(' which =', e.key.which);
    writeln(' state =', e.key.state);
    writeln(' scancode=', sym.scancode);
    if (0 <sym> 0) then
    begin
    //* Is it a control-character? */
    if (sym.unicode <ord>unicode & 0xFF00))
    {
    printf("(%c)", sym->unicode);
    end;
    #endif*)
    end;
    end;
    writeln('');
    end;
    SDL_KEYUP: //* Keys released */
    begin
    sym := @e.key.keysym;
    writeln('SDL_KEYUP');
    writeln(' which =', e.key.which);
    writeln(' state =', e.key.state);
    writeln(' scancode=', sym.scancode);
    if (0 <sym>mod);
    writeln(' unicode =', sym.unicode);
    if (sym.unicode > 0) then
    begin
    //* Is it a control-character? */
    if (sym.unicode <ord>unicode & 0xFF00))
    end;
    printf("(%c)", sym->unicode);
    end;
    #endif*)
    end;
    end;
    writeln('');
    end;
    SDL_MOUSEMOTION: //* Mouse moved */
    begin
    writeln('SDL_MOUSEMOTION');
    writeln(' which =', e.motion.which);
    writeln(' state =', e.motion.state);
    writeln(Format(' abs x,y =%d,%d', [e.motion.x,e.motion.y]));
    writeln(Format(' rel x,y =%d,%d', [e.motion.xrel, e.motion.yrel]));
    end;
    SDL_MOUSEBUTTONDOWN: //* Mouse button pressed */
    begin
    writeln('SDL_MOUSEBUTTONDOWN');
    writeln(' which =', e.button.which);
    writeln(' button =', e.button.button);
    writeln(' state =', e.button.state);
    writeln(Format(' abs x,y =%d,%d', [e.motion.x, e.motion.y]));
    end;
    SDL_MOUSEBUTTONUP: //* Mouse button released */
    begin
    writeln('SDL_MOUSEBUTTONUP');
    writeln(' which =', e.button.which);
    writeln(' button =', e.button.button);
    writeln(' state =', e.button.state);
    writeln(Format(' abs x,y =%d,%d', [e.motion.x, e.motion.y]));
    end;
    (* case SDL_JOYAXISMOTION: /* Joystick axis motion */
    printf("SDL_JOYAXISMOTION\n");
    printf(" which =%d\n", (Uint32)e->jaxis.which);
    printf(" axis =%d\n", (Uint32)e->jaxis.axis);
    printf(" value =%d\n", (Sint32)e->jaxis.value);
    break;

    case SDL_JOYBALLMOTION: /* Joystick trackball motion */
    printf("SDL_JOYBALLMOTION\n");
    printf(" which =%d\n", (Uint32)e->jball.which);
    printf(" ball =%d\n", (Uint32)e->jball.ball);
    printf(" rel x,y =%d,%d\n", (Sint32)e->jball.xrel, (Sint32)e->jball.yrel);
    break;

    case SDL_JOYHATMOTION: /* Joystick hat position change */
    printf("SDL_JOYHATMOTION\n");
    printf(" which =%d\n", (Uint32)e->jhat.which);
    printf(" hat =%d\n", (Uint32)e->jhat.hat);
    printf(" value =%d\n", (Sint32)e->jhat.value);
    break;

    case SDL_JOYBUTTONDOWN: /* Joystick button pressed */
    printf("SDL_JOYBUTTONDOWN\n");
    printf(" which =%d\n", (Uint32)e->jbutton.which);
    printf(" button =%d\n", (Uint32)e->jbutton.button);
    printf(" state =%01x\n", (Uint32)e->jbutton.state);
    break;

    case SDL_JOYBUTTONUP: /* Joystick button released */
    printf("SDL_JOYBUTTONUP\n");
    printf(" which =%d\n", (Uint32)e->jbutton.which);
    printf(" button =%d\n", (Uint32)e->jbutton.button);
    printf(" state =%01x\n", (Uint32)e->jbutton.state);
    break;
    *)
    SDL_QUITEV: //* User-requested quit */
    writeln('SDL_QUIT');
    SDL_SYSWMEVENT: //* System specific event */
    writeln('SDL_SYSWMEVENT');
    SDL_VIDEORESIZE: //* User resized video mode */
    begin
    writeln('SDL_VIDEORESIZE');
    writeln(Format(' w,h =%d,%d', [e.resize.w, e.resize.h]));
    end;
    SDL_VIDEOEXPOSE: //* Screen needs to be redrawn */
    writeln('SDL_VIDEOEXPOSE');
    else
    begin
    if ((SDL_USEREVENT <= e.type_) and (e.type_ <SDL_NUMEVENTS> 0)) do
    begin
    ev.user.data1 := pointer(i);
    val := Fast_PushEvent(@ev);
    inc(num);
    //writeln('send=',num);
    inc(i);
    end;

    result:= 0;
    end;


    var
    count: integer = 0;
    rate: double = 0.0;
    start: Uint32 = 0;
    end_: Uint32 = 0;
    limit: Uint32 = (10 * 1000);
    thread: PSDL_Thread;
    ev: TSDL_Event;
    i: integer;
    sym: PSDL_keysym;

    begin


    (* if (2 <= argc)
    {
    limit = 1000 * atoi(argv[1]);
    end;
    *)
    limit := 1000 * 1;
    SDL_Init({SDL_INIT_EVENTTHREAD or} SDL_INIT_VIDEO or SDL_INIT_NOPARACHUTE);


    thread := SDL_CreateThread(@runThread, nil);

    start := SDL_GetTicks;
    while ((SDL_GetTicks() <start> 0)) do
    begin
    dec(num);
    // writeln('got=', num);
    // writeln('time=',SDL_GetTicks());
    case (ev.type_) of
    SDL_USEREVENT:
    begin
    i:= integer(ev.user.data1);
    // writeln(Format('count=%d data1=%d', [count,i]));
    inc(count);
    end;
    SDL_QUITEV:
    begin
    writeln('got here');
    exit; // this isn't supposed to happen
    end;
    else
    begin
    printSDLEvent(@ev);
    end;
    end;
    end;
    doneYet := 1;

    while (Fast_PollEvent(@ev) > 0) do // drain the que
    begin
    end;

    // SDL_WaitThread(@thread,nil); // wait for it to die
    SDL_WaitThread(@thread,i); // wait for it to die

    end_ := SDL_GetTicks();

    rate := count / ((end_ - start) / 1000);
    writeln('events/second=', rate);
    SDL_Quit;
    end.
    [/pascal]

  9. #9

    SDL Threads

    Mmm. Never had a crash on the projects I've used this on....

    better look at the translation again and see if there is anything I missed.
    <A HREF="http://www.myhpf.co.uk/banner.asp?friend=139328">
    <br /><IMG SRC="http://www.myhpf.co.uk/banners/60x468.gif" BORDER="0">
    <br /></A>

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •