2 Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
12 /********************************************************************************
14 * Test of the overlay used for moved pictures, test more closed to real life. *
15 * Running trojan moose :) Coded by Mike Gorchak. *
17 ********************************************************************************/
24 #include <emscripten/emscripten.h>
32 #define MOOSEFRAME_SIZE (MOOSEPIC_W * MOOSEPIC_H)
33 #define MOOSEFRAMES_COUNT 10
35 SDL_Color MooseColors[84] = {
142 Uint8 MooseFrame[MOOSEFRAMES_COUNT][MOOSEFRAME_SIZE*2];
143 SDL_Texture *MooseTexture;
144 SDL_Rect displayrect;
148 SDL_Renderer *renderer;
151 SDL_bool done = SDL_FALSE;
152 Uint32 pixel_format = SDL_PIXELFORMAT_YV12;
155 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
163 /* All RGB2YUV conversion code and some other parts of code has been taken from testoverlay.c */
165 /* NOTE: These RGB conversion functions are not intended for speed,
170 RGBtoYUV(Uint8 * rgb, int *yuv, int monochrome, int luminance)
173 #if 1 /* these are the two formulas that I found on the FourCC site... */
174 yuv[0] = (int)(0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2]);
178 yuv[0] = (int)(0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16;
183 #if 1 /* these are the two formulas that I found on the FourCC site... */
184 yuv[0] = (int)(0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2]);
185 yuv[1] = (int)((rgb[2] - yuv[0]) * 0.565 + 128);
186 yuv[2] = (int)((rgb[0] - yuv[0]) * 0.713 + 128);
188 yuv[0] = (0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16;
189 yuv[1] = 128 - (0.148 * rgb[0]) - (0.291 * rgb[1]) + (0.439 * rgb[2]);
190 yuv[2] = 128 + (0.439 * rgb[0]) - (0.368 * rgb[1]) - (0.071 * rgb[2]);
194 if (luminance != 100) {
195 yuv[0] = yuv[0] * luminance / 100;
202 ConvertRGBtoYV12(Uint8 *rgb, Uint8 *out, int w, int h,
203 int monochrome, int luminance)
211 op[2] = op[1] + w*h/4;
212 for (y = 0; y < h; ++y) {
213 for (x = 0; x < w; ++x) {
214 RGBtoYUV(rgb, yuv, monochrome, luminance);
216 if (x % 2 == 0 && y % 2 == 0) {
226 ConvertRGBtoNV12(Uint8 *rgb, Uint8 *out, int w, int h,
227 int monochrome, int luminance)
235 for (y = 0; y < h; ++y) {
236 for (x = 0; x < w; ++x) {
237 RGBtoYUV(rgb, yuv, monochrome, luminance);
239 if (x % 2 == 0 && y % 2 == 0) {
249 PrintUsage(char *argv0)
251 SDL_Log("Usage: %s [arg] [arg] [arg] ...\n", argv0);
253 SDL_Log("Where 'arg' is any of the following options:\n");
255 SDL_Log(" -fps <frames per second>\n");
256 SDL_Log(" -nodelay\n");
257 SDL_Log(" -format <fmt> (one of the: YV12, IYUV, YUY2, UYVY, YVYU)\n");
258 SDL_Log(" -scale <scale factor> (initial scale of the overlay)\n");
259 SDL_Log(" -help (shows this help)\n");
261 SDL_Log("Press ESC to exit, or SPACE to freeze the movie while application running.\n");
270 while (SDL_PollEvent(&event)) {
271 switch (event.type) {
272 case SDL_WINDOWEVENT:
273 if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
274 SDL_RenderSetViewport(renderer, NULL);
275 displayrect.w = window_w = event.window.data1;
276 displayrect.h = window_h = event.window.data2;
279 case SDL_MOUSEBUTTONDOWN:
280 displayrect.x = event.button.x - window_w / 2;
281 displayrect.y = event.button.y - window_h / 2;
283 case SDL_MOUSEMOTION:
284 if (event.motion.state) {
285 displayrect.x = event.motion.x - window_w / 2;
286 displayrect.y = event.motion.y - window_h / 2;
290 if (event.key.keysym.sym == SDLK_SPACE) {
294 if (event.key.keysym.sym != SDLK_ESCAPE) {
303 #ifndef __EMSCRIPTEN__
308 i = (i + 1) % MOOSEFRAMES_COUNT;
310 SDL_UpdateTexture(MooseTexture, NULL, MooseFrame[i], MOOSEPIC_W*SDL_BYTESPERPIXEL(pixel_format));
312 SDL_RenderClear(renderer);
313 SDL_RenderCopy(renderer, MooseTexture, NULL, &displayrect);
314 SDL_RenderPresent(renderer);
316 #ifdef __EMSCRIPTEN__
318 emscripten_cancel_main_loop();
324 main(int argc, char **argv)
334 Uint32 pixel_format = SDL_PIXELFORMAT_NV12;
336 Uint32 pixel_format = SDL_PIXELFORMAT_YV12;
340 /* Enable standard application logging */
341 SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
343 if (SDL_Init(SDL_INIT_VIDEO) < 0) {
344 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
349 if (strcmp(argv[1], "-fps") == 0) {
353 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
354 "The -fps option requires an argument [from 1 to 1000], default is 12.\n");
357 if ((fps < 0) || (fps > 1000)) {
358 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
359 "The -fps option must be in range from 1 to 1000, default is 12.\n");
365 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
366 "The -fps option requires an argument [from 1 to 1000], default is 12.\n");
369 } else if (strcmp(argv[1], "-nodelay") == 0) {
373 } else if (strcmp(argv[1], "-scale") == 0) {
375 scale = atoi(argv[2]);
377 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
378 "The -scale option requires an argument [from 1 to 50], default is 5.\n");
381 if ((scale < 0) || (scale > 50)) {
382 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
383 "The -scale option must be in range from 1 to 50, default is 5.\n");
389 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
390 "The -fps option requires an argument [from 1 to 1000], default is 12.\n");
393 } else if ((strcmp(argv[1], "-help") == 0)
394 || (strcmp(argv[1], "-h") == 0)) {
398 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unrecognized option: %s.\n", argv[1]);
404 RawMooseData = (Uint8 *) malloc(MOOSEFRAME_SIZE * MOOSEFRAMES_COUNT);
405 if (RawMooseData == NULL) {
406 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Can't allocate memory for movie !\n");
411 /* load the trojan moose images */
412 handle = SDL_RWFromFile("moose.dat", "rb");
413 if (handle == NULL) {
414 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Can't find the file moose.dat !\n");
419 SDL_RWread(handle, RawMooseData, MOOSEFRAME_SIZE, MOOSEFRAMES_COUNT);
423 /* Create the window and renderer */
424 window_w = MOOSEPIC_W * scale;
425 window_h = MOOSEPIC_H * scale;
426 window = SDL_CreateWindow("Happy Moose",
427 SDL_WINDOWPOS_UNDEFINED,
428 SDL_WINDOWPOS_UNDEFINED,
430 SDL_WINDOW_RESIZABLE);
432 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create window: %s\n", SDL_GetError());
437 renderer = SDL_CreateRenderer(window, -1, 0);
439 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create renderer: %s\n", SDL_GetError());
444 MooseTexture = SDL_CreateTexture(renderer, pixel_format, SDL_TEXTUREACCESS_STREAMING, MOOSEPIC_W, MOOSEPIC_H);
446 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create texture: %s\n", SDL_GetError());
450 /* Uncomment this to check vertex color with a YUV texture */
451 /* SDL_SetTextureColorMod(MooseTexture, 0xff, 0x80, 0x80); */
453 for (i = 0; i < MOOSEFRAMES_COUNT; i++) {
454 Uint8 MooseFrameRGB[MOOSEFRAME_SIZE*3];
459 frame = RawMooseData + i * MOOSEFRAME_SIZE;
460 for (j = 0; j < MOOSEFRAME_SIZE; ++j) {
461 rgb[0] = MooseColors[frame[j]].r;
462 rgb[1] = MooseColors[frame[j]].g;
463 rgb[2] = MooseColors[frame[j]].b;
466 switch (pixel_format) {
467 case SDL_PIXELFORMAT_YV12:
468 ConvertRGBtoYV12(MooseFrameRGB, MooseFrame[i], MOOSEPIC_W, MOOSEPIC_H, 0, 100);
470 case SDL_PIXELFORMAT_NV12:
471 ConvertRGBtoNV12(MooseFrameRGB, MooseFrame[i], MOOSEPIC_W, MOOSEPIC_H, 0, 100);
474 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unsupported pixel format\n");
481 /* set the start frame */
486 fpsdelay = 1000 / fps;
491 displayrect.w = window_w;
492 displayrect.h = window_h;
494 /* Ignore key up events, they don't even get filtered */
495 SDL_EventState(SDL_KEYUP, SDL_IGNORE);
497 /* Loop, waiting for QUIT or RESIZE */
498 #ifdef __EMSCRIPTEN__
499 emscripten_set_main_loop(loop, nodelay ? 0 : fps, 1);
506 SDL_DestroyRenderer(renderer);
511 /* vi: set ts=4 sw=4 expandtab: */