SDL sense servidor X. Raspberry Pi

De Wikijoan
Dreceres ràpides: navegació, cerca

Contingut

Referències

llegir:

Raspberry Pi user config for the console

If you intend to use SDL on the raspberry pi without using X windows the SDL library will attempt to access the framebuffer directly. By default only the root user has access to the framebuffer device so we need to add the current user (i.e. what you logged in as) to this group.  To do this we need to add the user to the group video, input and audio groups (audio if we use it later) for a minimum you must have video and input.

sudo usermod -a -G video,input,audio [your username]


Once this is done logout and the user will be added to the group on the next login.

Efectivament he fet funcionar l'exemple SDLTest.c des de la consola (de moment de l'ordinador, no de la Raspberry Pi). Tot i que ha funcionat fent sudo... Amb la Rasspberry no cal fer sudo. He provat l'exemple SDLTest3.c i següents i han funcionat en la RP.

NOTA. Però dies més tard no han funcionat. El que és important és que DEPTH siguin 16bpp (en el codi BPP no s'utilitza...) (Pi has a 16 bit per pixel framebuffer). Utiltizar 16 ó 32 és la diferència entre que l'aplicació no es pengi o sí que es pengi, a més de no utilitzar el doble buffer. Per tant, dues regles importants per utilitzar SDL amb la RP sense entorn gràfic:

Per tal de communtar entre la consola i l'escriptori, faig Ctrl+Alt+F1 per anar a la consla, i des de la consolar faig Alt+xx per tornar a l'escriptori, on xx és un valor entre 1 i 6 i que puc saber fent la comanda w.

SDLTest1.c

fitxer SDLTest1.c:

//http://www.friedspace.com/cprogramming/sdlsurface.php
//$ gcc -o sdltest1 SDLTest1.c `sdl-config --cflags --libs`

#include <stdio.h>
#include <SDL.h>

#define WIDTH 1366
#define HEIGHT 768
#define BPP 4
#define DEPTH 32

void setpixel(SDL_Surface *screen, int x, int y, Uint8 r, Uint8 g, Uint8 b)
{
    Uint32 *pixmem32;
    Uint32 colour;  
 
    colour = SDL_MapRGB( screen->format, r, g, b );
  
    pixmem32 = (Uint32*) screen->pixels  + y + x;
    *pixmem32 = colour;
}


void DrawScreen(SDL_Surface* screen, int h)
{ 
    int x, y, ytimesw;
  
    if(SDL_MUSTLOCK(screen)) 
    {
        if(SDL_LockSurface(screen) < 0) return;
    }

    for(y = 0; y < screen->h; y++ ) 
    {
        ytimesw = y*screen->pitch/BPP;
        for( x = 0; x < screen->w; x++ ) 
        {
            setpixel(screen, x, ytimesw, (x*x)/256+3*y+h, (y*y)/256+x+h, h);
        }
    }

    if(SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen);
  
    SDL_Flip(screen); 
}


int main(int argc, char* argv[])
{
    SDL_Surface *screen;
    SDL_Event event;
  
    int keypress = 0;
    int h=0; 
  
    if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1;
   
    if (!(screen = SDL_SetVideoMode(WIDTH, HEIGHT, DEPTH, SDL_DOUBLEBUF | SDL_FULLSCREEN|SDL_HWSURFACE)))
    //if (!(screen = SDL_SetVideoMode(WIDTH, HEIGHT, DEPTH, SDL_FULLSCREEN|SDL_SWSURFACE)))
    {
        SDL_Quit();
        return 1;
    }
  
    while(!keypress) 
    {
         DrawScreen(screen,h++);
         while(SDL_PollEvent(&event)) 
         {      
              switch (event.type) 
              {
                  case SDL_QUIT:
	              keypress = 1;
	              break;
                  case SDL_KEYDOWN:
                       keypress = 1;
                       break;
              }
         }
    }

    SDL_Quit();
  
    return 0;
}

SDLTest2.c

fitxer SDLTest2.c

//g++ SDLTest2.c -o SDLTest2 `sdl-config --cflags --libs`

#include <SDL/SDL.h>
#include <cstdlib>
#include <iostream>
 
const int WINDOW_WIDTH = 1024;
const int WINDOW_HEIGHT = 720;
 
#if defined (DARWIN) || defined (WIN32)
  int SDL_main(int argc, char **argv)
#else
  int main(int argc, char **argv)
#endif
{
 if (SDL_Init( SDL_INIT_VIDEO ) !=0)
 {
  std::cerr <<"error initialising SDL exiting\n";
  exit(EXIT_FAILURE);
 }
 SDL_Surface* screen = SDL_SetVideoMode( WINDOW_WIDTH, WINDOW_HEIGHT, 0,SDL_HWSURFACE | SDL_DOUBLEBUF );
 if( screen == NULL)
 {
  std::cerr<<"error setting SDL Video Mode\n";
  exit(EXIT_FAILURE);
 }
 SDL_WM_SetCaption( "A Simple SDL Window", 0 );
 
 SDL_Event event;
 bool quit=false;
 while(!quit)
 {
  while ( SDL_PollEvent(&event) )
  {
   switch (event.type)
   {
    case SDL_QUIT : quit = true; break;
 
    case SDL_KEYDOWN:
    {
     switch( event.key.keysym.sym )
     {
      case SDLK_ESCAPE :  quit = true; break;
      default : break;
     }
    }
 
    default : break;
   }
  }
 } // end processing loop
 
 SDL_Quit();
 
 return EXIT_SUCCESS;
}

SDLTest3.c

fitxer SDLTest3.c:

//http://www.friedspace.com/cprogramming/sdlsurface.php
//$ gcc -o sdltest3 SDLTest3.c `sdl-config  --cflags --libs` -lSDL_image

#include <stdio.h>
#include <SDL.h>

#define WIDTH 1366
#define HEIGHT 768
#define BPP 4
#define DEPTH 32

SDL_Surface *IMG_Load(const char *file);

int main(int argc, char* argv[])
{
    SDL_Surface *screen;
    SDL_Event event;

    SDL_Surface *foto;
    foto = IMG_Load("/home/joan/Imatges/foto_nets.JPG");

    if (foto == NULL)
    {
       printf ( "IMG_Load: %s\n", SDL_GetError () );
       return 1;
    }


    int keypress = 0;
    int h=0; 
  
    if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1;
   
    if (!(screen = SDL_SetVideoMode(WIDTH, HEIGHT, DEPTH, SDL_FULLSCREEN|SDL_HWSURFACE)))
    //if (!(screen = SDL_SetVideoMode(WIDTH, HEIGHT, DEPTH, SDL_FULLSCREEN|SDL_SWSURFACE)))
    {
        SDL_Quit();
        return 1;
    }


   SDL_Rect rcDest = { 0, 0, 100, 100 };

   if (SDL_BlitSurface ( foto, NULL, screen, NULL )!= 0)
   //if (SDL_BlitSurface ( foto, &rcDest, screen, &rcDest )!= 0)
   {
       printf ( "problema: %s\n", SDL_GetError () );
       return 1;
   }

   SDL_FreeSurface ( foto );

    SDL_Flip(screen);

    while(!keypress) 
    {
    
         //DrawScreen(screen,h++);
         while(SDL_PollEvent(&event)) 
         {      
              switch (event.type) 
              {
                  case SDL_QUIT:
	              keypress = 1;
	              break;
                  case SDL_KEYDOWN:
                       keypress = 1;
                       break;
              }
         }
    }

    SDL_Quit();
  
    return 0;
}

Per tant, ja he demostrat com es pot utilitzar SDL i fer servir elements gràfics sense carregar el servidor X. I això pot servir per a fer un front-end per a MAME basat en SDL.

Funciona amb la Rasspberry Pi. No cal fer sudo. El que és important, NO ficar l'opció SDL_DOUBLEBUF |

sdltest4.c

//http://www.friedspace.com/cprogramming/sdlsurface.php
//$ gcc -o sdltest sdltest4.c `sdl-config  --cflags --libs` -lSDL_image

#include <stdio.h>
#include <SDL.h>

#define DEPTH 16 //canvio a 16 perquè ho vull utilitzar amb la RP (Pi has a 16 bit per pixel framebuffer)

SDL_Surface *IMG_Load(const char *file);

int main(int argc, char* argv[])
{
    SDL_Surface *screen;
    SDL_Event event;

    SDL_Surface *foto;
    foto = IMG_Load("img/nens_negres.jpg");

    if (foto == NULL)
    {
       printf ( "IMG_Load: %s\n", SDL_GetError () );
       return 1;
    }


    int keypress = 0;
    int h=0; 
  
    if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1;
   
    const SDL_VideoInfo* screenInfo = SDL_GetVideoInfo();
    int currentResHeight = (int)screenInfo->current_h;
    int currentResWidth = (int)screenInfo->current_w;
    printf("%d\n",currentResWidth);
    printf("%d\n",currentResHeight);

    if (!(screen = SDL_SetVideoMode(currentResWidth, currentResHeight, DEPTH, SDL_FULLSCREEN|SDL_SWSURFACE)))
    //if (!(screen = SDL_SetVideoMode(currentResWidth, currentResHeight, DEPTH, SDL_FULLSCREEN|SDL_HWSURFACE)))
    {
        SDL_Quit();
        return 1;
    }


   SDL_Rect rcDest = { 0, 0, 100, 100 };

   if (SDL_BlitSurface ( foto, NULL, screen, NULL )!= 0)
   //if (SDL_BlitSurface ( foto, &rcDest, screen, &rcDest )!= 0)
   {
       printf ( "problema: %s\n", SDL_GetError () );
       return 1;
   }

    SDL_FreeSurface ( foto );

    SDL_Flip(screen);

    while(!keypress) 
    {
    
         //DrawScreen(screen,h++);
         while(SDL_PollEvent(&event)) 
         {      
              switch (event.type) 
              {
                  case SDL_QUIT:
	              keypress = 1;
	              break;
                  case SDL_KEYDOWN:
                       keypress = 1;
                       break;
              }
         }
    }

    SDL_Quit();
  
    return 0;
}

milloncete-0.0.5.c

En aquest exemple hi ha un sprite que es mou, i mentre es mou puc fer sonar varis canals de música amb sdl_mixer. Tot això amb fluidesa.


creat per Joan Quintana Compte, febrer 2014

Eines de l'usuari
Espais de noms
Variants
Accions
Navegació
IES Jaume Balmes
Màquines recreatives
CNC
Informàtica musical
joanillo.org Planet
Eines