EmscriptenSDL2
SDL2 auf RaspberryPi2 B kompilieren
SDL2 auf der RaspberryPI2 Rev. B
SDL2_ttf installieren :
sudo apt-get install libsdl2-ttf-2.0-0
g++ main.cpp -o main Timer.cpp -lSDL2 -lSDL2_image -lSDL2_ttf
g++ -Wall `sdl2-config --cflags` main.cpp Timer.cpp -o main -lSDL2 -lSDL2_image -lSDL2_ttf
emcc -O2 -s USE_SDL=2 -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS='["png","jpeg"]' -s USE_SDL_TTF=2 -s EXPORTED_FUNCTIONS='["_main"]' -s ASSERTIONS=1 main.cpp Timer.cpp -o main.html --preload-file assets
main.cpp:
/*
* g++ main.cpp -o main Timer.cpp -lSDL2 -lSDL_image -lSDL_ttf
*
* emcc -O2 -s USE_SDL=2 -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS='["png","jpeg"]' -s USE_SDL_TTF=2 -s EXPORTED_FUNCTIONS='["_main"]' -s ASSERTIONS=1 main.cpp Timer.cpp -o main.html --preload-file assets
*
*/
#include <string>
#include <stdio.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>
#include "Timer.h"
#ifdef __EMSCRIPTEN__
#include <emscripten/emscripten.h>
#endif
#define FRAMERATE 24
enum input_state
{
NOTHING_PRESSED = 0,
UP_PRESSED = 1,
DOWN_PRESSED = 1<<1,
LEFT_PRESSED = 1<<2,
RIGHT_PRESSED = 1<<3
};
Timer *timer;
SDL_Renderer *renderer;
SDL_Color textColor = { 0x00, 0x00, 0x00 };
/**
* Font that is used for rendering text, and
* a texture the text is rendered into
*/
TTF_Font *font;
SDL_Texture *text_tex;
int active_state;
void Quit(){
#ifdef __EMSCRIPTEN__
emscripten_cancel_main_loop();
#else
//exit(0);
#endif
TTF_Quit();
atexit(SDL_Quit);
exit(0);
}
void processInput()
{
// printf("processInput\n");
SDL_Event event;
if (SDL_PollEvent(&event)) {
switch (event.key.keysym.sym)
{
printf("keytype:%d\n",event.key.type);
case SDLK_ESCAPE:
Quit();
break;
case SDLK_UP:
if (event.key.type == SDL_KEYDOWN){
active_state |= UP_PRESSED;
printf("UP PRESSED");
}else if (event.key.type == SDL_KEYUP)
active_state ^= UP_PRESSED;
break;
case SDLK_DOWN:
if (event.key.type == SDL_KEYDOWN){
printf("DOWN PRESSED");
active_state |= DOWN_PRESSED;
}else if (event.key.type == SDL_KEYUP)
active_state ^= DOWN_PRESSED;
break;
case SDLK_LEFT:
if (event.key.type == SDL_KEYDOWN)
active_state |= LEFT_PRESSED;
else if (event.key.type == SDL_KEYUP)
active_state ^= LEFT_PRESSED;
break;
case SDLK_RIGHT:
if (event.key.type == SDL_KEYDOWN)
active_state |= RIGHT_PRESSED;
else if (event.key.type == SDL_KEYUP)
active_state ^= RIGHT_PRESSED;
break;
default:
break;
}
// printf("state%d\n",active_state);
}
}
char msg[201];
void update()
{
SDL_Surface *status_text_surface;
// SDL_Color fg={93,93,93,255};
sprintf(msg, "FPS %02f", timer->getFrameRate());
status_text_surface = TTF_RenderText_Blended(font, msg, textColor);
text_tex = SDL_CreateTextureFromSurface(renderer, status_text_surface);
SDL_FreeSurface(status_text_surface);
}
void render()
{
SDL_RenderClear( renderer );
SDL_QueryTexture(text_tex,
NULL, NULL, &dest.w, &dest.h);
dest.x = 0;
dest.y = 0;
SDL_RenderCopy (renderer, text_tex, NULL, &dest);
// printf("render\n");
SDL_RenderPresent( renderer);
};
void run(){
processInput();
update();
render();
timer->update();
SDL_Delay( ( 1000 / FRAMERATE ) - timer->getTicks() );
}
void createFont(){
font = TTF_OpenFont("assets/edosz.ttf", 30);
printf("Font:%p",&font);
//getchar();
//TTF_CloseFont( font );
SDL_Color color={0,0,0};
SDL_Surface *text_surface;
if(!(text_surface=TTF_RenderText_Blended(font,"Hello World!",color))) {
//handle error here, perhaps print TTF_GetError at least
printf("Oh My Goodness, an error : %s", TTF_GetError());
} else {
// SDL_BlitUpperSurface(text_surface,NULL,screen,NULL);
//perhaps we can reuse it, but I assume not for simplicity.
SDL_FreeSurface(text_surface);
}
};
int main(int arc, char* argv[] ) {
timer=new Timer();
SDL_Window *window;
SDL_Init(SDL_INIT_VIDEO);
atexit(SDL_Quit);
TTF_Init();
atexit(TTF_Quit);
createFont();
// SDL_Color fg = (SDL_Color){0,0,0,255};
// SDL_Surface *text_surface = TTF_RenderText_Blended(font, "HALLO", textColor);
// text_tex = SDL_CreateTextureFromSurface(renderer, text_surface);
// SDL_FreeSurface(text_surface);
//Mind you that (0,0) is on the top left of the window/screen, think a rect as the text's box, that way it would be very simple to understance
//Now since it's a texture, you have to put RenderCopy in your game loop area, the area where the whole code executes
SDL_CreateWindowAndRenderer(600, 400, 0, &window, &renderer);
// Set color of renderer to red
SDL_SetRenderDrawColor( renderer, 255, 0, 0, 255 );
#ifdef __EMSCRIPTEN__
printf("running emcc!\n");
emscripten_set_main_loop(run, -1, 1);
#else
printf("running c++!\n");
while(true){
run();
}
#endif
printf("hello, world!\n");
return 0;
}
Timer.h:
/*
* Timer.h
*
* Created on: 09.10.2017
* Author: robert
*/
#ifndef TIMER_H_
#define TIMER_H_
#define FRAME_VALUES 10
class Timer {
public:
Timer();
virtual ~Timer();
void update();
float getFrameRate();
Uint32 getTicks();
private:
// An array to store frame times:
Uint32 frametimes[FRAME_VALUES];
// Last calculated SDL_GetTicks
Uint32 frametimelast;
// total frames rendered
Uint32 framecount;
// the value you want
float framespersecond;
};
#endif /* TIMER_H_ */
Timer.cpp:
/*
* Timer.cpp
*
* Created on: 09.10.2017
* Author: robert
*/
#include <stdio.h>
#include <SDL2/SDL.h>
#include "Timer.h"
Timer::Timer() {
// TODO Auto-generated constructor stub
memset(frametimes, 0, sizeof(frametimes));
framecount = 0;
framespersecond = 0;
frametimelast = SDL_GetTicks();
}
Timer::~Timer() {
// TODO Auto-generated destructor stub
}
void Timer::update() {
Uint32 frametimesindex;
Uint32 getticks;
Uint32 count;
Uint32 i;
// frametimesindex is the position in the array. It ranges from 0 to FRAME_VALUES.
// This value rotates back to 0 after it hits FRAME_VALUES.
frametimesindex = framecount % FRAME_VALUES;
// store the current time
getticks = SDL_GetTicks();
// save the frame time value
frametimes[frametimesindex] = getticks - frametimelast;
// save the last frame time for the next fpsthink
frametimelast = getticks;
// increment the frame count
framecount++;
// Work out the current framerate
// The code below could be moved into another function if you don't need the value every frame.
// I've included a test to see if the whole array has been written to or not. This will stop
// strange values on the first few (FRAME_VALUES) frames.
if (framecount < FRAME_VALUES) {
count = framecount;
} else {
count = FRAME_VALUES;
}
// add up all the values and divide to get the average frame time.
framespersecond = 0;
for (i = 0; i < count; i++) {
framespersecond += frametimes[i];
}
framespersecond /= count;
// now to make it an actual frames per second value...
framespersecond = 1000.f / framespersecond;
}
Uint32 Timer::getTicks () {
return SDL_GetTicks()-frametimelast;
}
float Timer::getFrameRate() {
return this->framespersecond;
}