Update 59

There is a lot of small things to do in the level 4, I am also adding maps because even if there is a lot of things to do, a lot of it is very easy. It’s time to make thing more challenging at least for some parts.

I was also thinking about maybe adding small cutscenes in the games. But how do you do that with SDL? I need a codec library to decode the video, something like FFmpeg but smaller, I only need to read one type of video. TheoraPlay seems nice for that, and there is an example using SDL. Wait a minute, the example only works for SDL 1.2? After spending some time with replacing old functions with new ones and using SDL_Texture instead of SDL_Surface, I came up with something working : Play video with SDL2 

In the game, I use SDL_gpu to render the display, so SDL_Renderer and SDL_Texture  need to be replaced with SDL_gpu stuff like GPU_Target and GPU_Image. But something is quite problematic : no YUV support well I don’t have a choice so I am trying with RGB.

The good new is TheoraPlay can decode these format :

THEORAPLAY_VIDFMT_YV12
/* NTSC colorspace, planar YCrCb 4:2:0 */
THEORAPLAY_VIDFMT_IYUV
/* NTSC colorspace, planar YCbCr 4:2:0 */
THEORAPLAY_VIDFMT_RGB
/* 24 bits packed pixel RGB */

THEORAPLAY_VIDFMT_RGBA
/* 32 bits packed pixel RGBA (full alpha). */

RGB is good enough for the test, how do I update the pixels, there is no SDL_LockTexture and SDL_UnlockTexture for SDL_gpu. But there is GPU_UpdateImageBytes which do the work. I can update all the pixels at the same time with RGB. With YUV there is 3 planes to update, multiple calls to memcpy are necessary :

SDL_LockTexture(texture, NULL, &pixels, &pitch);
const int w = video->width;
const int h = video->height;
const Uint8 *y = (const Uint8 *)video->pixels;
const Uint8 *u = y + (w * h);
const Uint8 *v = u + ((w / 2) * (h / 2));
Uint8 *dst = (Uint8*)pixels;
int i;

for (i = 0; i < h; i++, y += w, dst += pitch) {
	memcpy(dst, y, w);
}

for (i = 0; i < h / 2; i++,	u += w / 2, dst += pitch / 2) {
	memcpy(dst, u, w / 2);
}

for (i = 0; i < h / 2; i++,	v += w / 2,	dst += pitch / 2) {
	memcpy(dst, v, w / 2);
}

SDL_UnlockTexture(texture);

With RGB and SDL_gpu I can update everything with one call :

GPU_UpdateImageBytes(texture, NULL, video->pixels, video->width * texture->bytes_per_pixel);

Leave a Reply

Your email address will not be published. Required fields are marked *