void sdl_system_cleanup() { SDL_DestroyRenderer(gRender); SDL_Quit(); }
static void SetVideoMode(void) { int w, h; int x, y; unsigned int rmask, gmask, bmask, amask; int unused_bpp; int window_flags = 0, renderer_flags = 0; SDL_DisplayMode mode; w = window_width; h = window_height; // In windowed mode, the window can be resized while the game is // running. window_flags = SDL_WINDOW_RESIZABLE; // Set the highdpi flag - this makes a big difference on Macs with // retina displays, especially when using small window sizes. window_flags |= SDL_WINDOW_ALLOW_HIGHDPI; if (fullscreen) { if (fullscreen_width == 0 && fullscreen_height == 0) { // This window_flags means "Never change the screen resolution! // Instead, draw to the entire screen by scaling the texture // appropriately". window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; } else { w = fullscreen_width; h = fullscreen_height; window_flags |= SDL_WINDOW_FULLSCREEN; } } I_GetWindowPosition(&x, &y, w, h); // Create window and renderer contexts. We set the window title // later anyway and leave the window position "undefined". If // "window_flags" contains the fullscreen flag (see above), then // w and h are ignored. if (screen == NULL) { screen = SDL_CreateWindow(NULL, x, y, w, h, window_flags); if (screen == NULL) { I_Error("Error creating window for video startup: %s", SDL_GetError()); } pixel_format = SDL_GetWindowPixelFormat(screen); SDL_SetWindowMinimumSize(screen, SCREENWIDTH, actualheight); I_InitWindowTitle(); I_InitWindowIcon(); } // The SDL_RENDERER_TARGETTEXTURE flag is required to render the // intermediate texture into the upscaled texture. renderer_flags = SDL_RENDERER_TARGETTEXTURE; if (SDL_GetCurrentDisplayMode(video_display, &mode) != 0) { I_Error("Could not get display mode for video display #%d: %s", video_display, SDL_GetError()); } // Turn on vsync if we aren't in a -timedemo if (!singletics && mode.refresh_rate > 0) { renderer_flags |= SDL_RENDERER_PRESENTVSYNC; } if (force_software_renderer) { renderer_flags |= SDL_RENDERER_SOFTWARE; renderer_flags &= ~SDL_RENDERER_PRESENTVSYNC; } if (renderer != NULL) { SDL_DestroyRenderer(renderer); } renderer = SDL_CreateRenderer(screen, -1, renderer_flags); if (renderer == NULL) { I_Error("Error creating renderer for screen window: %s", SDL_GetError()); } // Important: Set the "logical size" of the rendering context. At the same // time this also defines the aspect ratio that is preserved while scaling // and stretching the texture into the window. if (aspect_ratio_correct || integer_scaling) { SDL_RenderSetLogicalSize(renderer, SCREENWIDTH, actualheight); } // Force integer scales for resolution-independent rendering. #if SDL_VERSION_ATLEAST(2, 0, 5) SDL_RenderSetIntegerScale(renderer, integer_scaling); #endif // Blank out the full screen area in case there is any junk in // the borders that won't otherwise be overwritten. SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderClear(renderer); SDL_RenderPresent(renderer); // Create the 8-bit paletted and the 32-bit RGBA screenbuffer surfaces. if (screenbuffer == NULL) { screenbuffer = SDL_CreateRGBSurface(0, SCREENWIDTH, SCREENHEIGHT, 8, 0, 0, 0, 0); SDL_FillRect(screenbuffer, NULL, 0); } // Format of argbbuffer must match the screen pixel format because we // import the surface data into the texture. if (argbbuffer == NULL) { SDL_PixelFormatEnumToMasks(pixel_format, &unused_bpp, &rmask, &gmask, &bmask, &amask); argbbuffer = SDL_CreateRGBSurface(0, SCREENWIDTH, SCREENHEIGHT, 32, rmask, gmask, bmask, amask); SDL_FillRect(argbbuffer, NULL, 0); } if (texture != NULL) { SDL_DestroyTexture(texture); } // Set the scaling quality for rendering the intermediate texture into // the upscaled texture to "nearest", which is gritty and pixelated and // resembles software scaling pretty well. SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest"); // Create the intermediate texture that the RGBA surface gets loaded into. // The SDL_TEXTUREACCESS_STREAMING flag means that this texture's content // is going to change frequently. texture = SDL_CreateTexture(renderer, pixel_format, SDL_TEXTUREACCESS_STREAMING, SCREENWIDTH, SCREENHEIGHT); // Initially create the upscaled texture for rendering to screen CreateUpscaledTexture(true); }
int main(int argc, char *argv[]) { char *title; SDL_Window *window; Uint32 flags; int x, y, width, height, shutdown; SDL_Renderer *renderer; SDL_Event event; SDL_AudioDeviceID sdl_audio_dev; struct timespec start, last_print, now, elapsed; unsigned long total_elapsed_seconds; double fps; unsigned long int frame_count, frames_since_print; struct game_memory mem; struct pixel_buffer *virtual_win; struct pixel_buffer blit_buf; struct human_input input[2]; struct human_input *tmp_input; struct human_input *new_input; struct human_input *old_input; struct sdl_texture_buffer texture_buf; struct sdl_event_context event_ctx; struct audio_ring_buffer audio_ring_buf; struct audio_buffer audio_buf; pixel_buffer_init(&blit_buf); texture_buf.texture = NULL; texture_buf.pixel_buf = &blit_buf; flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC; if (SDL_Init(flags) != 0) { return 1; } height = 480; width = 640; mem.is_initialized = 0; mem.fixed_memory_size = 4 * 1024 * 1024; mem.transient_memory_size = 1 * 1024 * 1024; mem.fixed_memory = platform_alloc(mem.fixed_memory_size + mem.transient_memory_size); if (mem.fixed_memory == 0) { debug(0, "did not alloc game memory\n"); return 1; } mem.transient_memory = mem.fixed_memory + mem.fixed_memory_size; init_game(&mem, HANDMAIDEN_AUDIO_DEFAULT_VOLUME, HANDMAIDEN_AUDIO_START_VOLUME); virtual_win = NULL; update_pixel_buffer(&mem, &virtual_win); if (!virtual_win) { debug(0, "did not assign virtual_win\n"); } sdl_init_joysticks(&event_ctx); title = (argc > 1) ? argv[1] : "Handmaiden Hero"; x = SDL_WINDOWPOS_UNDEFINED; y = SDL_WINDOWPOS_UNDEFINED; flags = SDL_WINDOW_RESIZABLE; window = SDL_CreateWindow(title, x, y, width, height, flags); if (!window) { debug(0, "Could not SDL_CreateWindow\n"); return 2; } renderer = SDL_CreateRenderer(window, FIRST_SUPPORTING, NONE); if (!renderer) { return 3; } sdl_resize_texture_buf(window, renderer, &texture_buf); if (init_audio_ring_buffer(&audio_ring_buf)) { sdl_audio_dev = sdl_init_audio(&audio_ring_buf); } else { sdl_audio_dev = 0; } if (sdl_audio_dev && audio_ring_buf.buf_len) { audio_buf.stream_pos = 0; audio_buf.num_samples = 0; audio_buf.samples = (int *)platform_alloc(audio_ring_buf.buf_len); if (!audio_buf.samples) { debug(0, "could not allocate audio_buf.samples[%u]\n", audio_ring_buf.buf_len); audio_buf.buf_len = 0; } else { audio_buf.buf_len = audio_ring_buf.buf_len; } } /* start audio playing by setting "pause" to zero */ if (sdl_audio_dev && audio_buf.samples) { SDL_PauseAudioDevice(sdl_audio_dev, 0); } event_ctx.event = &event; event_ctx.texture_buf = &texture_buf; event_ctx.renderer = renderer; event_ctx.window = window; event_ctx.win_id = SDL_GetWindowID(window); clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); last_print.tv_sec = start.tv_sec; last_print.tv_nsec = start.tv_nsec; total_elapsed_seconds = 0; frames_since_print = 0; frame_count = 0; shutdown = 0; old_input = &input[0]; new_input = &input[1]; init_input(old_input); init_input(new_input); while (!shutdown) { tmp_input = new_input; new_input = old_input; old_input = tmp_input; init_input(new_input); while (SDL_PollEvent(&event)) { if ((shutdown = process_event(&event_ctx, new_input))) { break; } } process_joysticks(&event_ctx, old_input, new_input); if (shutdown || (shutdown = process_input(&mem, new_input))) { break; } update_pixel_buffer(&mem, &virtual_win); stretch_buffer(virtual_win, &blit_buf); sdl_blit_texture(renderer, &texture_buf); if (sdl_audio_dev && audio_buf.samples) { if ((audio_ring_buf.write_cursor - audio_ring_buf.play_cursor) < audio_ring_buf.buf_len) { SDL_LockAudio(); if (fill_ring_buf (&audio_ring_buf, &mem, &audio_buf) < 0) { shutdown = 1; } SDL_UnlockAudio(); } } frame_count++; frames_since_print++; clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &now); diff_timespecs(last_print, now, &elapsed); if (((elapsed.tv_sec * 1000000000) + elapsed.tv_nsec) > 100000000) { fps = ((double)frames_since_print) / (((double)elapsed.tv_sec) * 1000000000.0 + ((double)elapsed.tv_nsec) / 1000000000.0); frames_since_print = 0; last_print.tv_sec = now.tv_sec; last_print.tv_nsec = now.tv_nsec; diff_timespecs(start, now, &elapsed); total_elapsed_seconds = elapsed.tv_sec + 1; if (FPS_PRINTER) { debug(0, "fps: %.02f (avg fps: %.f) %u, %u%s", fps, (double)frame_count / (double)total_elapsed_seconds, audio_ring_buf.play_cursor, audio_ring_buf.write_cursor, ERIC_DEBUG ? "\n" : "\r"); } } } debug(0, "\n"); if (sdl_audio_dev) { SDL_CloseAudioDevice(sdl_audio_dev); } close_audio_debug_logging(&audio_ring_buf); sdl_close_joysticks(&event_ctx); /* we probably do not need to do these next steps */ if (HANDMAIDEN_TRY_TO_MAKE_VALGRIND_HAPPY) { /* first cleanup SDL stuff */ if (texture_buf.texture) { SDL_DestroyTexture(texture_buf.texture); } SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); /* then collect our own garbage */ if (blit_buf.pixels) { platform_free(blit_buf.pixels, blit_buf.pixels_bytes_len); } if (audio_ring_buf.buf) { platform_free(audio_ring_buf.buf, audio_ring_buf.buf_len); } if (audio_buf.samples) { platform_free(audio_buf.samples, audio_buf.buf_len); } if (mem.fixed_memory) { platform_free(mem.fixed_memory, mem.fixed_memory_size + mem.transient_memory_size); } } return 0; }
int main(int argc, char **argv) { Uint8 *RawMooseData; SDL_RWops *handle; SDL_Window *window; int j; int fps = 12; int nodelay = 0; #ifdef TEST_NV12 Uint32 pixel_format = SDL_PIXELFORMAT_NV12; #else Uint32 pixel_format = SDL_PIXELFORMAT_YV12; #endif int scale = 5; /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); if (SDL_Init(SDL_INIT_VIDEO) < 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); return 3; } while (argc > 1) { if (strcmp(argv[1], "-fps") == 0) { if (argv[2]) { fps = atoi(argv[2]); if (fps == 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "The -fps option requires an argument [from 1 to 1000], default is 12.\n"); quit(10); } if ((fps < 0) || (fps > 1000)) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "The -fps option must be in range from 1 to 1000, default is 12.\n"); quit(10); } argv += 2; argc -= 2; } else { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "The -fps option requires an argument [from 1 to 1000], default is 12.\n"); quit(10); } } else if (strcmp(argv[1], "-nodelay") == 0) { nodelay = 1; argv += 1; argc -= 1; } else if (strcmp(argv[1], "-scale") == 0) { if (argv[2]) { scale = atoi(argv[2]); if (scale == 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "The -scale option requires an argument [from 1 to 50], default is 5.\n"); quit(10); } if ((scale < 0) || (scale > 50)) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "The -scale option must be in range from 1 to 50, default is 5.\n"); quit(10); } argv += 2; argc -= 2; } else { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "The -fps option requires an argument [from 1 to 1000], default is 12.\n"); quit(10); } } else if ((strcmp(argv[1], "-help") == 0) || (strcmp(argv[1], "-h") == 0)) { PrintUsage(argv[0]); quit(0); } else { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unrecognized option: %s.\n", argv[1]); quit(10); } break; } RawMooseData = (Uint8 *) malloc(MOOSEFRAME_SIZE * MOOSEFRAMES_COUNT); if (RawMooseData == NULL) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Can't allocate memory for movie !\n"); free(RawMooseData); quit(1); } /* load the trojan moose images */ handle = SDL_RWFromFile("moose.dat", "rb"); if (handle == NULL) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Can't find the file moose.dat !\n"); free(RawMooseData); quit(2); } SDL_RWread(handle, RawMooseData, MOOSEFRAME_SIZE, MOOSEFRAMES_COUNT); SDL_RWclose(handle); /* Create the window and renderer */ window_w = MOOSEPIC_W * scale; window_h = MOOSEPIC_H * scale; window = SDL_CreateWindow("Happy Moose", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, window_w, window_h, SDL_WINDOW_RESIZABLE); if (!window) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create window: %s\n", SDL_GetError()); free(RawMooseData); quit(4); } renderer = SDL_CreateRenderer(window, -1, 0); if (!renderer) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create renderer: %s\n", SDL_GetError()); free(RawMooseData); quit(4); } MooseTexture = SDL_CreateTexture(renderer, pixel_format, SDL_TEXTUREACCESS_STREAMING, MOOSEPIC_W, MOOSEPIC_H); if (!MooseTexture) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create texture: %s\n", SDL_GetError()); free(RawMooseData); quit(5); } /* Uncomment this to check vertex color with a YUV texture */ /* SDL_SetTextureColorMod(MooseTexture, 0xff, 0x80, 0x80); */ for (i = 0; i < MOOSEFRAMES_COUNT; i++) { Uint8 MooseFrameRGB[MOOSEFRAME_SIZE*3]; Uint8 *rgb; Uint8 *frame; rgb = MooseFrameRGB; frame = RawMooseData + i * MOOSEFRAME_SIZE; for (j = 0; j < MOOSEFRAME_SIZE; ++j) { rgb[0] = MooseColors[frame[j]].r; rgb[1] = MooseColors[frame[j]].g; rgb[2] = MooseColors[frame[j]].b; rgb += 3; } switch (pixel_format) { case SDL_PIXELFORMAT_YV12: ConvertRGBtoYV12(MooseFrameRGB, MooseFrame[i], MOOSEPIC_W, MOOSEPIC_H, 0, 100); break; case SDL_PIXELFORMAT_NV12: ConvertRGBtoNV12(MooseFrameRGB, MooseFrame[i], MOOSEPIC_W, MOOSEPIC_H, 0, 100); break; default: SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unsupported pixel format\n"); break; } } free(RawMooseData); /* set the start frame */ i = 0; if (nodelay) { fpsdelay = 0; } else { fpsdelay = 1000 / fps; } displayrect.x = 0; displayrect.y = 0; displayrect.w = window_w; displayrect.h = window_h; /* Ignore key up events, they don't even get filtered */ SDL_EventState(SDL_KEYUP, SDL_IGNORE); /* Loop, waiting for QUIT or RESIZE */ #ifdef __EMSCRIPTEN__ emscripten_set_main_loop(loop, nodelay ? 0 : fps, 1); #else while (!done) { loop(); } #endif SDL_DestroyRenderer(renderer); quit(0); return 0; }
//-------------------------------------------- // -- //-------------------------------------------- Machine::~Machine() { SDL_DestroyRenderer(mRenderer); SDL_DestroyWindow(mWindow); }
int main() { // more info at: https://wiki.libsdl.org/ puts( "Initializing SDL.." ); if(SDL_Init(SDL_INIT_EVERYTHING)) error1("SDL_Init Error"); SDL_Window *win = SDL_CreateWindow("Pong", 100, 100, W, H, SDL_WINDOW_SHOWN); if (!win) error1("SDL_CreateWindow Error"); SDL_Renderer *ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC); if (!ren) error1("SDL_CreateRenderer Error"); SDL_Surface *sur = SDL_LoadBMP("bg.bmp"); if(!sur) error1("SDL_CreateRGBSurface error"); SDL_Texture *bg = SDL_CreateTextureFromSurface(ren,sur); if(!bg) error1("SDL_CreateTextureFromSurface error"); SDL_FreeSurface(sur); sur = SDL_LoadBMP("fb.bmp"); if(!sur) error1("SDL_CreateRGBSurface error"); SDL_Texture *fb = SDL_CreateTextureFromSurface(ren,sur); if(!fb) error1("SDL_CreateTextureFromSurface error"); SDL_FreeSurface(sur); Uint32 rate_ms; SDL_Event e; int speed = 5; SDL_Rect pos; pos.x = 100; pos.y = 100; pos.h = 36; pos.w = 36; int dx = speed, dy = speed; bool running = true; while(running) { // gamel loop rate_ms = SDL_GetTicks(); // check for input while(SDL_PollEvent(&e)) { switch(e.type) { case SDL_QUIT: running = false; break; case SDL_KEYDOWN: switch(e.key.keysym.scancode) { case SDL_SCANCODE_RETURN: case SDL_SCANCODE_RETURN2: case SDL_SCANCODE_KP_ENTER: case SDL_SCANCODE_SPACE: dx = 0; dy = 0; case SDL_SCANCODE_ESCAPE: running = false; break; } break; case SDL_MOUSEBUTTONUP: pos.x = e.motion.x; pos.y = e.motion.y; break; } } // game logic pos.x += dx; pos.y += dy; if(pos.x<=1) dx = speed; else if(pos.x>=W-pos.w) dx = -speed; if(pos.y<=1) dy = speed; else if(pos.y>=H-pos.h) dy = -speed; // render //SDL_RenderClear(ren); SDL_RenderCopy(ren, bg, NULL, NULL); SDL_RenderCopy(ren, fb, NULL, &pos); SDL_RenderPresent(ren); // sleep rate_ms = SDL_GetTicks()-rate_ms; if (rate_ms<FRAME_RATE) SDL_Delay(FRAME_RATE-rate_ms); } // free resources SDL_DestroyRenderer(ren); SDL_DestroyWindow(win); SDL_Quit(); return 0; }