making gamehelpers usable

This commit is contained in:
Adam D. Ruppe 2019-03-23 21:11:14 -04:00
parent 1d14657596
commit fc896e74cb
3 changed files with 93 additions and 11 deletions

View File

@ -1,5 +1,7 @@
// WORK IN PROGRESS
// register cheat code? or even a fighting game combo..
/++
An add-on for simpledisplay.d, joystick.d, and simpleaudio.d
that includes helper functions for writing games (and perhaps
@ -67,6 +69,7 @@ module arsd.gamehelpers;
public import arsd.color;
public import arsd.simpledisplay;
public import arsd.simpleaudio;
import std.math;
public import core.time;
@ -110,6 +113,19 @@ class GameHelperBase {
/// here like one created with `create2dWindow`.
abstract SimpleWindow getWindow();
/// Override this and return true to initialize the audio system.
/// Note that trying to use the [audio] member without this will segfault!
bool wantAudio() { return false; }
/// You must override [wantAudio] and return true for this to be valid;
AudioPcmOutThread audio;
this() {
if(wantAudio) {
audio = new AudioPcmOutThread();
audio.start();
}
}
/// These functions help you handle user input. It offers polling functions for
/// keyboard, mouse, joystick, and virtual controller input.
@ -121,6 +137,53 @@ class GameHelperBase {
ref JoystickUpdate joystick1() { return joysticks[0]; }
bool[256] keyboardState;
VirtualController snes;
}
/++
The virtual controller is based on the SNES. If you need more detail, try using
the joystick or keyboard and mouse members directly.
l r
U X
L R s S Y A
D B
For Playstation and XBox controllers plugged into the computer,
it picks those buttons based on similar layout on the physical device.
For keyboard control, arrows and WASD are mapped to the d-pad (ULRD in the diagram),
Q and E are mapped to the shoulder buttons (l and r in the diagram).So are U and P.
Z, X, C, V (for when right hand is on arrows) and K,L,I,O (for left hand on WASD) are mapped to B,A,Y,X buttons.
G is mapped to select, and H is mapped to start.
The space bar and enter keys are also set to button A.
Only player 1 is mapped to the keyboard.
+/
struct VirtualController {
ushort state;
enum Button {
Up, Left, Right, Down,
X, A, B, Y,
Select, Start, L, R
}
bool opIndex(Button idx) {
return (state & (1 << (cast(int) idx))) ? true : false;
}
private void opIndexAssign(bool value, Button idx) {
if(value)
state |= (1 << (cast(int) idx));
else
state &= ~(1 << (cast(int) idx));
}
}
/// The max rates are given in executions per second
@ -147,27 +210,44 @@ void runGame(T : GameHelperBase)(T game, int maxUpdateRate = 20, int maxRedrawRa
game.joysticks[p] = update;
}// else assert(0);
// FIXME: fill in snes too
auto now = MonoTime.currTime;
game.update(now - lastUpdate);
bool changed = game.update(now - lastUpdate);
lastUpdate = now;
// FIXME: rate limiting
window.redrawOpenGlSceneNow();
if(changed)
window.redrawOpenGlSceneNow();
},
delegate (KeyEvent ke) {
game.keyboardState[ke.hardwareCode] = ke.pressed;
/*
with(VirtualController.Button)
switch(ke.key) {
case Key.UpArrow:
game.joysticks[0]
break;
case Key.Up, Key.W: game.snes[Up] = ke.pressed; break;
case Key.Down, Key.S: game.snes[Down] = ke.pressed; break;
case Key.Left, Key.A: game.snes[Left] = ke.pressed; break;
case Key.Right, Key.D: game.snes[Right] = ke.pressed; break;
case Key.Q, Key.U: game.snes[L] = ke.pressed; break;
case Key.E, Key.P: game.snes[R] = ke.pressed; break;
case Key.Z, Key.K: game.snes[B] = ke.pressed; break;
case Key.Space, Key.Enter, Key.X, Key.L: game.snes[A] = ke.pressed; break;
case Key.C, Key.I: game.snes[Y] = ke.pressed; break;
case Key.V, Key.O: game.snes[X] = ke.pressed; break;
case Key.G: game.snes[Select] = ke.pressed; break;
case Key.H: game.snes[Start] = ke.pressed; break;
default:
}
*/
// FIXME
}
);
// FIXME: what if an exception is thrown above?
if(game.audio !is null) {
game.audio.stop();
game.audio.join();
}
}
/++
@ -320,6 +400,7 @@ final class OpenGlTexture {
if(freeRequired)
free(cast(void*) data);
glBindTexture(GL_TEXTURE_2D, 0);
}
/// ditto

View File

@ -270,9 +270,9 @@ final class AudioPcmOutThread : Thread {
addSample(s);
}
/// Requires vorbis.d to be compiled in (module iv.stb.vorbis)
/// Requires vorbis.d to be compiled in (module arsd.vorbis)
void playOgg()(string filename, bool loop = false) {
import iv.stb.vorbis;
import arsd.vorbis;
auto v = new VorbisDecoder(filename);

View File

@ -53,7 +53,8 @@
//
// See end of file for full version history.
// D translation by Ketmar // Invisible Vector
module iv.stb.vorbis;
// stolen by adam and module renamed.
module arsd.vorbis;
import core.stdc.stdio : FILE;