-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SDL 2 support (without removing SDL 1)
Second binary, which is actually partially because I plan to stick a menu on this thing for HyperPixel touchscreen purposes. Slightly ugly SDLVERSION hacks, but mostly the two are compatible. The big changes are contained to the separate main binary, needing to do different graphics setup. render() must now use the provided, not remembered, framebuffer, and report if it wants to update the screen, which the main binary takes care of (flip for SDL1, more complicated dance for SDL2). Some changes around palette handling. Also surface creation---SDL2 is more pedantic about complaining if you hand it a pixel format bitfield at the same time as saying "paletted, please". VSCode noise. Flag which hacks are working or misbehaving weirdly under SDL2. Yes, this all needs a pile of refactoring, but as always time is short.
- Loading branch information
Showing
10 changed files
with
242 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
// Copyright (c) 2020 Philip Boulain; see LICENSE for terms. | ||
#include <exception> | ||
#include <iostream> | ||
#include <memory> | ||
|
||
// Force VSCode to know this is going to get the version 2 define here. | ||
#define SDLVERSION 2 | ||
#include "hack.hpp" | ||
|
||
// This is just used to get SDL init/deinit via RAII for nice error handling. | ||
namespace SDL { | ||
struct Error : public std::exception { | ||
virtual const char* what() const throw() | ||
{ return SDL_GetError(); } | ||
}; | ||
|
||
struct Graphics { | ||
SDL_Window* window; | ||
SDL_Renderer *renderer; | ||
SDL_Texture* texture; | ||
int w, h; | ||
|
||
Graphics() { | ||
if(SDL_Init(SDL_INIT_VIDEO) != 0) { throw Error(); } | ||
if(SDL_CreateWindowAndRenderer( | ||
#ifdef DESKTOP | ||
// Resolution of the Pimoroni HyperPixel. | ||
800, 480, | ||
0, | ||
#else | ||
// Counterintuitively, the non-"desktop" behaviour is fullscreen. | ||
0, 0, | ||
SDL_WINDOW_FULLSCREEN_DESKTOP, | ||
#endif | ||
&window, &renderer) != 0 ) { throw Error(); } | ||
SDL_SetWindowTitle(window, "pixmas"); | ||
#ifndef DESKTOP | ||
SDL_SetWindowAlwaysOnTop(window, SDL_TRUE); | ||
#endif | ||
if(SDL_GetRendererOutputSize(renderer, &w, &h) != 0) | ||
{ throw Error(); } | ||
texture = SDL_CreateTexture(renderer, | ||
SDL_PIXELFORMAT_ARGB8888, | ||
SDL_TEXTUREACCESS_STREAMING, | ||
w, h); | ||
} | ||
~Graphics() { | ||
// Let SDL free all its own things. | ||
SDL_Quit(); | ||
} | ||
}; | ||
}; | ||
|
||
int main(int argc, char** argv) { | ||
SDL::Graphics graphics; | ||
#ifndef DESKTOP | ||
SDL_ShowCursor(0); | ||
#endif | ||
SDL_SetRenderDrawColor(graphics.renderer, 0x77, 0x77, 0x77, 0xff); | ||
SDL_RenderClear(graphics.renderer); | ||
SDL_RenderPresent(graphics.renderer); | ||
|
||
SDL_Surface* temp_stale_fb; | ||
temp_stale_fb = SDL_CreateRGBSurface(0, graphics.w, graphics.h, 32, | ||
0x00FF0000, | ||
0x0000FF00, | ||
0x000000FF, | ||
0xFF000000); | ||
|
||
// Pick one of the factory functions from hack.hpp here. | ||
// TODO: Allow picking at startup or runtime. | ||
// BROKEN: Segfaults, resets snow on win move(?!), double-frees the vector(?!) | ||
//std::unique_ptr<Hack::Base> hack = Hack::MakeSnowFP(temp_stale_fb); | ||
// BROKEN: Somehow makes the texture invalid(?!) | ||
//std::unique_ptr<Hack::Base> hack = Hack::MakeSnowInt(temp_stale_fb); | ||
// WORKS but window move resets snow(?!) | ||
//std::unique_ptr<Hack::Base> hack = Hack::MakeSnowClock(temp_stale_fb); | ||
// WORKS | ||
std::unique_ptr<Hack::Base> hack = Hack::MakePopClock(temp_stale_fb); | ||
// WORKS | ||
//std::unique_ptr<Hack::Base> hack = Hack::MakeColorCycle(temp_stale_fb); | ||
|
||
Uint32 tickerror = 0; | ||
Uint32 ticklast = SDL_GetTicks(); | ||
SDL_Event event; | ||
bool run = true; | ||
while(run) { | ||
// Process events. | ||
while(SDL_PollEvent(&event)) { switch(event.type) { | ||
case SDL_QUIT: | ||
run = false; break; | ||
case SDL_KEYDOWN: | ||
switch(event.key.keysym.sym) { | ||
case SDLK_ESCAPE: | ||
case SDLK_q: | ||
run = false; break; | ||
default:; // Don't care. | ||
} | ||
default:; // Don't care. | ||
}} | ||
|
||
// Process the passage of time. | ||
{ | ||
const Uint32 now = SDL_GetTicks(); | ||
if (now < ticklast) { | ||
// Timer wraparound! You could do fancier code here to figure | ||
// out the interval, but eh, stutter a bit every ~49 days. | ||
ticklast = now; | ||
} | ||
tickerror += (now - ticklast); | ||
ticklast = now; | ||
} | ||
if(tickerror >= hack->tick_duration()) { | ||
if(tickerror > hack->tick_duration() * 10) { | ||
static bool once = false; | ||
if(!once) { | ||
std::cerr << "Running too slow! Skipping ticks!" << std::endl; | ||
once = true; | ||
} | ||
tickerror = hack->tick_duration(); | ||
} | ||
do { | ||
tickerror -= hack->tick_duration(); | ||
hack->simulate(); | ||
} while(tickerror >= hack->tick_duration()); | ||
SDL_Surface* fb = nullptr; | ||
if(SDL_LockTextureToSurface(graphics.texture, NULL, &fb) != 0) | ||
{ throw std::runtime_error(SDL_GetError()); } | ||
bool rendered = hack->render(fb); | ||
SDL_UnlockTexture(graphics.texture); // Also frees fb | ||
fb = nullptr; | ||
if(rendered) { | ||
SDL_RenderClear(graphics.renderer); | ||
SDL_RenderCopy(graphics.renderer, graphics.texture, | ||
NULL, NULL); | ||
SDL_RenderPresent(graphics.renderer); | ||
} | ||
} else { | ||
/// Have a nap until we actually have at least one tick to run. | ||
SDL_Delay(hack->tick_duration()); | ||
} | ||
} | ||
|
||
return EXIT_SUCCESS; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.