Here’s everything else:
module jecsdl.setup;
import jecsdl.base;
bool bindbcSetup() {
/*
This version attempts to load the SDL shared library using well-known variations
of the library name for the host system.
*/
SDLSupport ret = loadSDL();
if(ret != sdlSupport) {
// Handle error. For most use cases, this is enough. The error handling API in
// bindbc-loader can be used for error messages. If necessary, it’s possible
// to determine the primary cause programmtically:
if(ret == SDLSupport.noLibrary) {
// SDL shared library failed to load
assert(0, "no library");
}
else if(SDLSupport.badLibrary) {
// One or more symbols failed to load. The likely cause is that the
// shared library is for a lower version than bindbc-sdl was configured
// to load (via SDL_201, SDL_202, etc.)
assert(0, "old library, or some thing");
}
}
/*
This version attempts to load the SDL library using a user-supplied file name.
Usually, the name and/or path used will be platform specific, as in this example
which attempts to load `SDL2.dll` from the `libs` subdirectory, relative
to the executable, only on Windows. It has the same return values.
*/
// version(Windows) loadSDL("libs/SDL2.dll")
/*
The satellite library loaders also have the same two versions of the load functions,
named according to the library name. Only the parameterless versions are shown
here. These return similar values as loadSDL, but in an enum namespace that matches
the library name: SDLImageSupport, SDLMixerSupport, and SDLTTFSupport.
*/
if(loadSDLImage() != sdlImageSupport) {
/* handle error */
assert(0,"problem with loading image library");
}
return true;
}
bool initKeys() {
g_keystate = SDL_GetKeyboardState(null);
foreach(tkey; cast(SDL_Scancode)0 … SDL_NUM_SCANCODES)
g_keys ~= new TKey(cast(SDL_Scancode)tkey);
return g_keys.length == SDL_NUM_SCANCODES;
}
int setup(string title = “SDL Joel program”, int screenWidth = 640, int screenHeight = 480) {
SCREEN_WIDTH = screenWidth;
SCREEN_HEIGHT = screenHeight;
bool init()
{
//Initialization flag
bool success = true;
if (! bindbcSetup) {
success = false;
} else {
//Initialize SDL
if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
writef( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
success = false;
}
else
{
import std.string : toStringz;
//Create window
gWindow = SDL_CreateWindow( title.toStringz, SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
if( gWindow is null )
{
writef( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
success = false;
}
}
//Set texture filtering to linear
if( !SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "1" ) )
{
writef( "Warning: Linear texture filtering not enabled!" );
}
//Create renderer for window
gRenderer = SDL_CreateRenderer( gWindow, -1, SDL_RENDERER_ACCELERATED );
if( gRenderer is null )
{
printf( "Renderer could not be created! SDL Error: %s\n", SDL_GetError() );
success = false;
}
else
{
//Initialize renderer color
SDL_SetRenderDrawColor( gRenderer, 0x00, 0x0, 0xFF, 0xFF );
//Initialize PNG loading
int imgFlags = IMG_INIT_PNG;
if( !( IMG_Init( imgFlags ) & imgFlags ) )
{
writef( "SDL_image could not initialize! SDL_image Error: %s\n", IMG_GetError() );
success = false;
}
}
}
if (! initKeys)
success = false;
return success;
}
if (! init)
return 1;
return 0;
}
################# another file
module jecsdl.base;
public {
//Using SDL and standard IO
import std.stdio;
import bindbc.sdl;
import bindbc.sdl.image; // SDL_image binding
import std.math, std.conv, std.path;
}
import jecsdl.setup;
import std.datetime: Duration;
import std.datetime.stopwatch: StopWatch;
//public import jec.base, jec.input, jec.jexting, jec.setup, jec.sound, jmisc, jec.gui, jec.guifile, jec.guiconfirm;
//public import jec, jmisc;
//Screen dimensions
int SCREEN_WIDTH;
int SCREEN_HEIGHT;
string getClipboardText() {
import std.conv : to;
return SDL_GetClipboardText().to!string;
}
void setClipboardText(string txt) {
import std.string : toStringz;
if (SDL_HasClipboardText() == SDL_TRUE)
SDL_SetClipboardText(txt.toStringz);
}
//The window we’ll be rendering to
SDL_Window* gWindow;
//The window renderer
SDL_Renderer* gRenderer;
//Current displayed texture
SDL_Texture* gTexture;
Uint8* g_keystate;
SDL_Texture* loadTexture( string path )
{
//The final texture
SDL_Texture* newTexture;
import std.string : toStringz;
//Load image at specified path
SDL_Surface* loadedSurface = IMG_Load( path.toStringz );
if( loadedSurface is null )
{
writef( "Unable to load image %s! SDL_image Error: %s\n", path, IMG_GetError() );
}
else
{
//Create texture from surface pixels
newTexture = SDL_CreateTextureFromSurface( gRenderer, loadedSurface );
if( newTexture is null )
{
writef( "Unable to create texture from %s! SDL Error: %s\n", path, SDL_GetError() );
}
//Get rid of old loaded surface
SDL_FreeSurface( loadedSurface );
}
return newTexture;
}
/**
-
Handle keys, one hit buttons
*/
class TKey {
/// Key state
enum KeyState {up, down, startGap, smallGap}
/// Key state variable
KeyState _keyState;
/// Start pause
static _startPause = 200;
/// Moving momments
static _pauseTime = 40; // msecs
/// Timer for start pause
StopWatch _stopWatchStart;
/// Timer for moving moments
StopWatch _stopWatchPause;
/// Key to use
SDL_Scancode tKey;
/// Is key set to down
bool _keyDown;
/**
- Constructor
*/
this(SDL_Scancode tkey0) {
tKey = tkey0;
_keyDown = false;
_keyState = KeyState.up;
}
/// Is key pressed
bool keyPressed() { // eg. g_keys[Keyboard.Key.A].keyPressed
//return Keyboard.isKeyPressed(tKey) != 0;
return g_keystate[tKey] != 0;
}
/// Goes once per key hit
bool keyTrigger() { // eg. g_keys[Keyboard.Key.A].keyTrigger
if (g_keystate[tKey] && _keyDown == false) {
_keyDown = true;
return true;
} else if (! g_keystate[tKey]) {
_keyDown = false;
}
return false;
}
// returns true doing trigger other wise false saying the key is already down
/** One hit key */
/+
Press key down, print the character. Keep holding down the key and the cursor move at a staggered pace.
+/
bool keyInput() { // eg. g_keys[Keyboard.Key.A].keyInput
if (! g_keystate[tKey])
_keyState = KeyState.up;
if (g_keystate[tKey] && _keyState == KeyState.up) {
_keyState = KeyState.down;
_stopWatchStart.reset;
_stopWatchStart.start;
return true;
}
if (_keyState == KeyState.down && _stopWatchStart.peek.total!"msecs" > _startPause) {
_keyState = KeyState.smallGap;
_stopWatchPause.reset;
_stopWatchPause.start;
}
if (_keyState == KeyState.smallGap && _stopWatchPause.peek.total!"msecs" > _pauseTime) {
_keyState = KeyState.down;
return true;
}
return false;
}
/** hold key */
// bool keyPress() {
// return Keyboard.isKeyPressed(tKey) > 0;
// }
}
// eg lkeys[Letter.p].keyTrigger
/// Keys array
TKey[] g_keys; // g_keys[Keyboard.Key.T].keyTrigger
/// Trim off parts of file name
auto trim(T)(in T str) { //if (SomeString!T) {
import std.path : stripExtension;
if (str.length > 6 && str[0 … 2] == “./”)
return str[2 … $].stripExtension.dup;
else
return str.dup;
}
/// Stop with key
void keyHold(int key) {
while(g_keys[key]) {
SDL_PumpEvents();
SDL_Delay(1);
} //# need to add like sleep(50.dur!msecs);, not that it stops the tight loop!
//while(Keyboard.isKeyPressed(cast(Keyboard.Key)key)) { sleep(50.dur!msecs); } // eg. keyHold(Keyboard.Key.Num0 + i);
}