Keyboard and mouse mostly implemented.

This commit is contained in:
Scott Duensing 2019-12-05 21:30:23 -06:00
parent fa91f8e281
commit 9f44dc055c
4 changed files with 608 additions and 68 deletions

View file

@ -450,6 +450,8 @@ int main(int argc, char *argv[]) {
window = SDL_CreateWindow("SINGE", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, _confXResolution, _confYResolution, SDL_WINDOW_RESIZABLE); window = SDL_CreateWindow("SINGE", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, _confXResolution, _confYResolution, SDL_WINDOW_RESIZABLE);
if (window == NULL) utilDie("%s", SDL_GetError()); if (window == NULL) utilDie("%s", SDL_GetError());
//***TODO*** Window Icon
// Do we want full screen of some kind? // Do we want full screen of some kind?
if (_confFullScreen || _confFullScreenWindow) { if (_confFullScreen || _confFullScreenWindow) {
flags = _confFullScreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP; flags = _confFullScreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP;

View file

@ -31,6 +31,7 @@
#include <lauxlib.h> #include <lauxlib.h>
#include "thirdparty/uthash.h" #include "thirdparty/uthash.h"
#include "thirdparty/manymouse/manymouse.h"
#include "common.h" #include "common.h"
#include "util.h" #include "util.h"
@ -40,8 +41,29 @@
#define AUDIO_MAX_VOLUME 63 #define AUDIO_MAX_VOLUME 63
#define MAX_TITLE_LENGTH 1024 #define MAX_TITLE_LENGTH 1024
#define MAX_MICE 128
#define SCROLLWHEEL_DISPLAY_TICKS 100
#define NOMOUSE -1
#define KEYBD_ARRAY_SIZE 15
typedef struct MouseS {
int x;
int y;
int relx;
int rely;
char name[64];
bool connected;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpadded"
Uint32 buttons;
#pragma GCC diagnostic pop
Uint32 scrolluptick;
Uint32 scrolldowntick;
Uint32 scrolllefttick;
Uint32 scrollrighttick;
} MouseT;
typedef struct SpriteS { typedef struct SpriteS {
int id; int id;
#pragma GCC diagnostic push #pragma GCC diagnostic push
@ -70,6 +92,35 @@ typedef struct FontS {
} FontT; } FontT;
enum {
SWITCH_UP,
SWITCH_LEFT,
SWITCH_DOWN,
SWITCH_RIGHT,
SWITCH_START1,
SWITCH_START2,
SWITCH_BUTTON1,
SWITCH_BUTTON2,
SWITCH_BUTTON3,
SWITCH_COIN1,
SWITCH_COIN2,
SWITCH_SKILL1,
SWITCH_SKILL2,
SWITCH_SKILL3,
SWITCH_SERVICE,
SWITCH_TEST,
SWITCH_RESET,
SWITCH_SCREENSHOT,
SWITCH_QUIT,
SWITCH_PAUSE,
SWITCH_CONSOLE,
SWITCH_TILT,
SWITCH_MOUSE_SCROLL_UP,
SWITCH_MOUSE_SCROLL_DOWN,
SWITCH_MOUSE_DISCONNECT,
SWITCH_COUNT
};
enum { enum {
KEYBD_NORMAL = 0, KEYBD_NORMAL = 0,
KEYBD_FULL KEYBD_FULL
@ -107,6 +158,7 @@ int _confYResolution = -1;
// Other globals // Other globals
static MouseT _mice[MAX_MICE];
static lua_State *_luaContext = NULL; static lua_State *_luaContext = NULL;
static SDL_Color _colorForeground = { 255, 255, 255, 255 }; static SDL_Color _colorForeground = { 255, 255, 255, 255 };
static SDL_Color _colorBackground = { 0, 0, 0, 255 }; static SDL_Color _colorBackground = { 0, 0, 0, 255 };
@ -120,16 +172,63 @@ static int _effectsVolume = AUDIO_MAX_VOLUME;
static int _keyboardMode = KEYBD_NORMAL; static int _keyboardMode = KEYBD_NORMAL;
static int _videoHandle = -1; static int _videoHandle = -1;
static int _fontQuality = 1; static int _fontQuality = 1;
static double _overlayScaleX = 1; static int _mouseMode = MOUSE_SINGLE;
static double _overlayScaleY = 1; static int _mouseCount = 0;
static double _overlayScaleX = 1; // Difference between overlay and video
static double _overlayScaleY = 1; // Difference between overlay and video
static bool _pauseState = false; // by RDG2010 static bool _pauseState = false; // by RDG2010
static bool _pauseEnabled = true; // by RDG2010 static bool _pauseEnabled = true; // by RDG2010
static bool _running = true; static bool _running = true;
static bool _discStopped = true;
static bool _mouseEnabled = true;
static SpriteT *_spriteList = NULL; static SpriteT *_spriteList = NULL;
static SoundT *_soundList = NULL; static SoundT *_soundList = NULL;
static FontT *_fontList = NULL; static FontT *_fontList = NULL;
static FontT *_fontCurrent = NULL; static FontT *_fontCurrent = NULL;
static int _keyDefs[SWITCH_COUNT][2] = {
{ SDLK_UP, SDLK_KP_8 }, // Up
{ SDLK_LEFT, SDLK_KP_4 }, // Left
{ SDLK_DOWN, SDLK_KP_2 }, // Down
{ SDLK_RIGHT, SDLK_KP_6 }, // Right
{ SDLK_1, 0 }, // 1 player start
{ SDLK_2, 0 }, // 2 player start
{ SDLK_SPACE, SDLK_LCTRL }, // Action button 1
{ SDLK_LALT, 0 }, // Action button 2
{ SDLK_LSHIFT, 0 }, // Action button 3
{ SDLK_5, SDLK_c }, // Coin chute left
{ SDLK_6, 0 }, // Coin chute right
{ SDLK_KP_DIVIDE, 0 }, // Skill easy
{ SDLK_KP_MULTIPLY, 0 }, // Skill medium
{ SDLK_KP_MINUS, 0 }, // Skill hard
{ SDLK_9, 0 }, // Service coin
{ SDLK_F2, 0 }, // Test mode
{ SDLK_F3, 0 }, // Reset cpu
{ SDLK_F12, SDLK_F11 }, // Take screenshot
{ SDLK_ESCAPE, SDLK_q }, // Quit
{ SDLK_p, 0 }, // Pause game
{ SDLK_BACKQUOTE, 0 }, // Toggle console
{ SDLK_t, 0 } // Tilt/Slam switch
};
static int _fullKeybdDefs[] = {
SDLK_BACKSPACE,
SDLK_TAB,
SDLK_RETURN,
SDLK_PAUSE,
SDLK_SPACE,
SDLK_QUOTE,
SDLK_COMMA,
SDLK_SEMICOLON,
SDLK_EQUALS,
SDLK_LEFTBRACKET,
SDLK_RIGHTBRACKET,
SDLK_BACKSLASH,
SDLK_SLASH,
SDLK_DELETE,
SDLK_PERIOD
};
int apiColorBackground(lua_State *L); int apiColorBackground(lua_State *L);
int apiColorForeground(lua_State *L); int apiColorForeground(lua_State *L);
@ -194,16 +293,64 @@ int apiSingeQuit(lua_State *L);
int apiSingeVersion(lua_State *L); int apiSingeVersion(lua_State *L);
int apiSingeSetGameName(lua_State *L); int apiSingeSetGameName(lua_State *L);
int apiSingeGetScriptPath(lua_State *L); int apiSingeGetScriptPath(lua_State *L);
void callLua(const char *func, const char *sig, ...);
int luaError(lua_State *L); int luaError(lua_State *L);
void processKey(bool down, int keysym);
int apiColorBackground(lua_State *L) { int apiColorBackground(lua_State *L) {
int n = lua_gettop(L);
if ((n == 3) || (n == 4)) {
if (lua_isinteger(L, 1)) {
if (lua_isinteger(L, 2)) {
if (lua_isinteger(L, 3)) {
_colorBackground.r = (byte)lua_tointeger(L, 1);
_colorBackground.g = (byte)lua_tointeger(L, 2);
_colorBackground.b = (byte)lua_tointeger(L, 3);
if (n == 3) {
_colorBackground.a = (byte)255;
} else {
if (lua_isinteger(L, 4)) {
_colorBackground.a = (byte)lua_tointeger(L, 4);
} else {
_colorBackground.a = (byte)255;
}
}
}
}
}
}
return 0;
} }
int apiColorForeground(lua_State *L) { int apiColorForeground(lua_State *L) {
int n = lua_gettop(L);
if ((n == 3) || (n == 4)) {
if (lua_isinteger(L, 1)) {
if (lua_isinteger(L, 2)) {
if (lua_isinteger(L, 3)) {
_colorForeground.r = (byte)lua_tointeger(L, 1);
_colorForeground.g = (byte)lua_tointeger(L, 2);
_colorForeground.b = (byte)lua_tointeger(L, 3);
if (n == 3) {
_colorForeground.a = (byte)255;
} else {
if (lua_isinteger(L, 4)) {
_colorForeground.a = (byte)lua_tointeger(L, 4);
} else {
_colorForeground.a = (byte)255;
}
}
}
}
}
}
return 0;
} }
@ -224,7 +371,37 @@ int apiDaphneGetWidth(lua_State *L) {
int apiDaphneScreenshot(lua_State *L) { int apiDaphneScreenshot(lua_State *L) {
int x = 0;
int y = 0;
Uint32 format = 0;
char filename[128];
void *pixels = NULL;
SDL_Surface *surface = NULL;
SDL_Texture *texture = NULL;
(void)L;
while (x <= 999) {
snprintf(filename, 128, "singe%03d", x);
if (!utilFileExists(filename)) break;
x++;
}
if (x > 999) utilDie("Seriously? You have 1000 screenshots in this folder? Remove some.");
SDL_SetRenderTarget(_renderer, NULL);
texture = SDL_GetRenderTarget(_renderer);
SDL_QueryTexture(texture, &format, NULL, &x, &y);
pixels = malloc((size_t)x * (size_t)y * SDL_BYTESPERPIXEL(format));
if (!pixels) utilDie("Unable to allocate screenshot.");
if (SDL_RenderReadPixels(_renderer, NULL, format, pixels, (Uint16)x * SDL_BYTESPERPIXEL(format)) < 0) utilDie("%s", SDL_GetError());
surface = SDL_CreateRGBSurfaceWithFormatFrom(pixels, x, y, SDL_BITSPERPIXEL(format), (Uint16)x * SDL_BYTESPERPIXEL(format), format);
if (!surface) utilDie("%s", SDL_GetError());
if (IMG_SavePNG(surface, filename) < 0) utilDie("%s", IMG_GetError());
SDL_FreeSurface(surface);
free(pixels);
SDL_SetRenderTarget(_renderer, _overlay);
return 0;
} }
@ -242,7 +419,25 @@ int apiDebugPrint(lua_State *L) {
int apiDiscAudio(lua_State *L) { int apiDiscAudio(lua_State *L) {
int n = lua_gettop(L);
int channel = 0;
int left = 0;
int right = 0;
bool onOff = false;
if (n == 2) {
if (lua_isinteger(L, 1)) {
if (lua_isboolean(L, 2)) {
channel = (int)lua_tointeger(L, 1);
onOff = (bool)lua_toboolean(L, 2);
if ((channel == 1) && onOff) left = _confVolumeVldp;
if ((channel == 2) && onOff) right = _confVolumeVldp;
videoSetVolume(_videoHandle, left, right);
}
}
}
return 0;
} }
@ -254,14 +449,20 @@ int apiDiscChangeSpeed(lua_State *L) {
int apiDiscGetFrame(lua_State *L) { int apiDiscGetFrame(lua_State *L) {
if (_discStopped) {
lua_pushinteger(L, 0);
} else {
lua_pushinteger(L, videoGetFrame(_videoHandle)); lua_pushinteger(L, videoGetFrame(_videoHandle));
}
return 1; return 1;
} }
int apiDiscPause(lua_State *L) { int apiDiscPause(lua_State *L) {
(void)L; (void)L;
if (!_discStopped) {
videoPause(_videoHandle); videoPause(_videoHandle);
}
return 0; return 0;
} }
@ -269,12 +470,14 @@ int apiDiscPause(lua_State *L) {
int apiDiscPauseAtFrame(lua_State *L) { int apiDiscPauseAtFrame(lua_State *L) {
int n = lua_gettop(L); int n = lua_gettop(L);
if (!_discStopped) {
if (n == 1) { if (n == 1) {
if (lua_isinteger(L, 1)) { if (lua_isinteger(L, 1)) {
videoSeek(_videoHandle, (int)lua_tointeger(L, 1)); videoSeek(_videoHandle, (int)lua_tointeger(L, 1));
videoPause(_videoHandle); videoPause(_videoHandle);
} }
} }
}
return 0; return 0;
} }
@ -283,17 +486,20 @@ int apiDiscPauseAtFrame(lua_State *L) {
int apiDiscPlay(lua_State *L) { int apiDiscPlay(lua_State *L) {
(void)L; (void)L;
videoPlay(_videoHandle); videoPlay(_videoHandle);
_discStopped = false;
} }
int apiDiscSearch(lua_State *L) { int apiDiscSearch(lua_State *L) {
int n = lua_gettop(L); int n = lua_gettop(L);
if (!_discStopped) {
if (n == 1) { if (n == 1) {
if (lua_isinteger(L, 1)) { if (lua_isinteger(L, 1)) {
videoSeek(_videoHandle, (int)lua_tointeger(L, 1)); videoSeek(_videoHandle, (int)lua_tointeger(L, 1));
} }
} }
}
return 0; return 0;
} }
@ -316,11 +522,13 @@ int apiDiscSetFps(lua_State *L) {
int apiDiscSkipBackward(lua_State *L) { int apiDiscSkipBackward(lua_State *L) {
int n = lua_gettop(L); int n = lua_gettop(L);
if (!_discStopped) {
if (n == 1) { if (n == 1) {
if (lua_isinteger(L, 1)) { if (lua_isinteger(L, 1)) {
videoSeek(_videoHandle, videoGetFrame(_videoHandle) - (int)lua_tointeger(L, 1)); videoSeek(_videoHandle, videoGetFrame(_videoHandle) - (int)lua_tointeger(L, 1));
} }
} }
}
return 0; return 0;
} }
@ -336,11 +544,13 @@ int apiDiscSkipBlanking(lua_State *L) {
int apiDiscSkipForward(lua_State *L) { int apiDiscSkipForward(lua_State *L) {
int n = lua_gettop(L); int n = lua_gettop(L);
if (!_discStopped) {
if (n == 1) { if (n == 1) {
if (lua_isinteger(L, 1)) { if (lua_isinteger(L, 1)) {
videoSeek(_videoHandle, videoGetFrame(_videoHandle) + (int)lua_tointeger(L, 1)); videoSeek(_videoHandle, videoGetFrame(_videoHandle) + (int)lua_tointeger(L, 1));
} }
} }
}
return 0; return 0;
} }
@ -354,22 +564,26 @@ int apiDiscSkipToFrame(lua_State *L) {
int apiDiscStepBackward(lua_State *L) { int apiDiscStepBackward(lua_State *L) {
(void)L; (void)L;
if (!_discStopped) {
videoSeek(_videoHandle, videoGetFrame(_videoHandle) - 1); videoSeek(_videoHandle, videoGetFrame(_videoHandle) - 1);
}
return 0; return 0;
} }
int apiDiscStepForward(lua_State *L) { int apiDiscStepForward(lua_State *L) {
(void)L; (void)L;
if (!_discStopped) {
videoSeek(_videoHandle, videoGetFrame(_videoHandle) + 1); videoSeek(_videoHandle, videoGetFrame(_videoHandle) + 1);
}
return 0; return 0;
} }
int apiDiscStop(lua_State *L) { int apiDiscStop(lua_State *L) {
(void)L; (void)L;
//***TODO*** Add a real stopped state
videoPause(_videoHandle); videoPause(_videoHandle);
_discStopped = true;
} }
@ -391,9 +605,9 @@ int apiFontLoad(lua_State *L) {
font->font = TTF_OpenFont(name, points); font->font = TTF_OpenFont(name, points);
if (!font->font) utilDie("%s", TTF_GetError()); if (!font->font) utilDie("%s", TTF_GetError());
// Make it the current font and mark it as loaded. // Make it the current font and mark it as loaded.
_fontCurrent = _nextFontId++; font->id = _nextFontId;
font->id = _fontCurrent; result = _nextFontId++;
result = _fontCurrent; _fontCurrent = font;
HASH_ADD_INT(_fontList, id, font); HASH_ADD_INT(_fontList, id, font);
} }
} }
@ -405,7 +619,53 @@ int apiFontLoad(lua_State *L) {
int apiFontPrint(lua_State *L) { int apiFontPrint(lua_State *L) {
int n = lua_gettop(L);
const char *message = NULL;
SDL_Surface *textSurface = NULL;
SDL_Texture *texture = NULL;
SDL_Rect dest;
if (n == 3) {
if (lua_isinteger(L, 1)) {
if (lua_isinteger(L, 2)) {
if (lua_isstring(L, 3)) {
if (_fontCurrent) {
dest.x = (int)lua_tointeger(L, 1);
dest.y = (int)lua_tointeger(L, 2);
textSurface = NULL;
message = lua_tostring(L, 3);
switch (_fontQuality) {
case 1:
textSurface = TTF_RenderText_Solid(_fontCurrent->font, message, _colorForeground);
break;
case 2:
textSurface = TTF_RenderText_Shaded(_fontCurrent->font, message, _colorForeground, _colorBackground);
break;
case 3:
textSurface = TTF_RenderText_Blended(_fontCurrent->font, message, _colorForeground);
break;
}
if (!textSurface) {
utilDie("Font surface is null!");
} else {
SDL_SetSurfaceBlendMode(textSurface, SDL_BLENDMODE_BLEND);
// Transparent index is 0
SDL_SetColorKey(textSurface, true, 0);
texture = SDL_CreateTextureFromSurface(_renderer, textSurface);
SDL_FreeSurface(textSurface);
if (!texture) utilDie("%s", SDL_GetError());
if (SDL_QueryTexture(texture, NULL, NULL, &dest.w, &dest.h) < 0) utilDie("%s", SDL_GetError());
SDL_RenderCopy(_renderer, texture, NULL, &dest);
}
}
}
}
}
}
return 0;
} }
@ -525,7 +785,19 @@ int apiOverlayGetWidth(lua_State *L) {
int apiOverlayPrint(lua_State *L) { int apiOverlayPrint(lua_State *L) {
int n = lua_gettop(L);
if (n == 3) {
if (lua_isinteger(L, 1)) {
if (lua_isinteger(L, 2)) {
if (lua_isinteger(L, 3)) {
//***TODO*** g_pSingeIn->draw_string((char *)lua_tostring(L, 3), lua_tonumber(L, 1), lua_tonumber(L, 2), g_se_surface);
}
}
}
}
return 0;
} }
@ -564,6 +836,7 @@ int apiSoundPlay(lua_State *L) {
HASH_FIND_INT(_soundList, &id, sound); HASH_FIND_INT(_soundList, &id, sound);
if (!sound) utilDie("No sound at index %d in apiSoundPlay.", id); if (!sound) utilDie("No sound at index %d in apiSoundPlay.", id);
result = Mix_PlayChannel(-1, sound->chunk, 0); result = Mix_PlayChannel(-1, sound->chunk, 0);
Mix_Volume(result, _effectsVolume * 2);
} }
} }
lua_pushnumber(L, result); lua_pushnumber(L, result);
@ -711,7 +984,6 @@ int apiSoundSetVolume(lua_State *L) {
if (thisValue >= 0 && thisValue <= AUDIO_MAX_VOLUME) { if (thisValue >= 0 && thisValue <= AUDIO_MAX_VOLUME) {
_effectsVolume = thisValue; _effectsVolume = thisValue;
Mix_Volume(-1, _effectsVolume * 2); Mix_Volume(-1, _effectsVolume * 2);
//***TODO*** Handle laser volume
} else { } else {
utilDie("Invalid sound volume value."); utilDie("Invalid sound volume value.");
} }
@ -862,7 +1134,37 @@ int apiVldpGetHeight(lua_State *L) {
int apiVldpGetPixel(lua_State *L) { int apiVldpGetPixel(lua_State *L) {
int n = lua_gettop(L);
bool result = false;
byte pixel[SDL_BYTESPERPIXEL(SDL_PIXELFORMAT_BGRA32)];
SDL_Rect rect;
if (n == 2) {
if (lua_isinteger(L, 1)) {
if (lua_isinteger(L, 2)) {
rect.h = 1;
rect.w = 1;
rect.x = (int)lua_tointeger(L, 1);
rect.y = (int)lua_tointeger(L, 2);
SDL_SetRenderTarget(_renderer, NULL);
if (SDL_RenderReadPixels(_renderer, &rect, SDL_PIXELFORMAT_BGRA32, pixel, SDL_BYTESPERPIXEL(SDL_PIXELFORMAT_BGRA32)) < 0) utilDie("%s", SDL_GetError());
SDL_SetRenderTarget(_renderer, _overlay);
result = true;
}
}
}
if (result) {
lua_pushinteger(L, (int)pixel[2]); // R
lua_pushinteger(L, (int)pixel[1]); // G
lua_pushinteger(L, (int)pixel[0]); // B
} else {
lua_pushinteger(L, -1);
lua_pushinteger(L, -1);
lua_pushinteger(L, -1);
}
return 3;
} }
@ -917,7 +1219,7 @@ int apiKeyboardSetMode(lua_State *L) {
int apiMouseEnable(lua_State *L) { int apiMouseEnable(lua_State *L) {
// Enables mouse monitoring // Enables mouse monitoring
(void)L; (void)L;
//***TODO*** g_pSingeIn->dll_side_mouse_enable(g_pSingeIn->pSingeInstance); _mouseEnabled = (bool)!_confNoMouse;
return 0; return 0;
} }
@ -925,7 +1227,7 @@ int apiMouseEnable(lua_State *L) {
int apiMouseDisable(lua_State *L) { int apiMouseDisable(lua_State *L) {
// Disables mouse monitoring // Disables mouse monitoring
(void)L; (void)L;
//***TODO*** g_pSingeIn->dll_side_mouse_disable(g_pSingeIn->pSingeInstance); _mouseEnabled = false;
return 0; return 0;
} }
@ -949,24 +1251,22 @@ int apiMouseSetMode(lua_State *L) {
// --rdg // --rdg
int n = lua_gettop(L); int n = lua_gettop(L);
int thisValue = 0;
bool result = false; bool result = false;
if (n == 1) { if (n == 1) {
if (lua_isinteger(L, 1)) { if (lua_isinteger(L, 1)) {
thisValue = (int)lua_tointeger(L, 1); _mouseMode = (int)lua_tointeger(L, 1);
//***TODO*** result = g_pSingeIn->dll_side_set_mouse_mode(thisValue); result = true;
if (!result) utilDie("mouseSetMode failed. Is mouse enabled?");
} }
} }
lua_pushboolean(L, result); lua_pushboolean(L, result);
return 1; return 1;
} }
int apiMouseHowMany(lua_State *L) { int apiMouseHowMany(lua_State *L) {
int total = 1; //***TODO*** g_pSingeIn->dll_side_mouse_get_how_many(g_pSingeIn->pSingeInstance); lua_pushinteger(L, _mouseCount);
lua_pushinteger(L, total);
return 1; return 1;
} }
@ -985,9 +1285,8 @@ int apiDiscGetState(lua_State *L) {
* *
*/ */
//***TODO*** Add a STOPPED state where a black screen is displayed
// Our player isn't as sophisticated as the one in Daphne // Our player isn't as sophisticated as the one in Daphne
lua_pushinteger(L, videoIsPlaying(_videoHandle) ? LDP_PLAYING : LDP_PAUSE); lua_pushinteger(L, _discStopped ? LDP_STOPPED : (videoIsPlaying(_videoHandle) ? LDP_PLAYING : LDP_PAUSE));
return 1; return 1;
} }
@ -1067,7 +1366,8 @@ int apiSingeSetGameName(lua_State *L) {
if (n == 1) { if (n == 1) {
if (lua_isstring(L, 1)) { if (lua_isstring(L, 1)) {
sprintf(thisName,"%.40s",lua_tostring(L, 1)); // Need a better way to do this... sprintf(thisName,"%.40s",lua_tostring(L, 1)); // Need a better way to do this...
//***TODO*** g_pSingeIn->dll_side_set_caption(g_pSingeIn->pSingeInstance, thisName); SDL_SetWindowTitle(_window, thisName);
result = true;
} }
} }
@ -1200,7 +1500,77 @@ int luaError(lua_State *L) {
} }
void processKey(bool down, int keysym) {
int move;
if (_keyboardMode == KEYBD_NORMAL) {
// Daphne keys
for (move=0; move<SWITCH_COUNT; move++) {
if ((keysym == _keyDefs[move][0]) || (keysym == _keyDefs[move][1])) {
if (!down) {
if ((move == SWITCH_PAUSE) && (_pauseEnabled)) {
//***TODO*** g_game->toggle_game_pause();
}
if ((move == SWITCH_QUIT) || (keysym == SDLK_ESCAPE)) {
_running = false;
}
if (move == SWITCH_SCREENSHOT) {
//***TODO*** g_ldp->request_screenshot();
}
}
if (move != SWITCH_PAUSE) {
callLua(down ? "onInputPressed" : "onInputReleased", "ii", move, NOMOUSE);
}
}
}
} else {
//***TODO*** Why is RDG filtering keys?
// Full keyboard
if (keysym >= SDLK_a && keysym <= SDLK_z)
callLua(down ? "onInputPressed" : "onInputReleased", "ii", keysym, NOMOUSE);
// check to see if key is a number on the top row of the keyboard (not keypad)
else if (keysym >= SDLK_MINUS && keysym <= SDLK_9)
callLua(down ? "onInputPressed" : "onInputReleased", "ii", keysym, NOMOUSE);
// numeric keypad keys
else if (keysym >= SDLK_KP_0 && keysym <= SDLK_KP_EQUALS)
callLua(down ? "onInputPressed" : "onInputReleased", "ii", keysym, NOMOUSE);
// arrow keys and insert, delete, home, end, pgup, pgdown
else if (keysym >= SDLK_UP && keysym <= SDLK_PAGEDOWN)
callLua(down ? "onInputPressed" : "onInputReleased", "ii", keysym, NOMOUSE);
// function keys
else if (keysym >= SDLK_F1 && keysym <= SDLK_F15)
callLua(down ? "onInputPressed" : "onInputReleased", "ii", keysym, NOMOUSE);
// Key state modifier keys (left and right ctrls, alts)
else if (keysym >= SDLK_NUMLOCKCLEAR && keysym <= SDLK_LGUI)
callLua(down ? "onInputPressed" : "onInputReleased", "ii", keysym, NOMOUSE);
// International keys
/*
else if (keysym >= SDLK_WORLD_0 && keysym <= SDLK_WORLD_95)
callLua(down ? "onInputPressed" : "onInputReleased", "ii", keysym, NOMOUSE);
*/
else {
/*
* SDLK_BACKSPACE, SDLK_TAB, SDLK_RETURN, SDLK_PAUSE,
* SDLK_SPACE, SDLK_QUOTE, SDLK_COMMA, SDLK_SEMICOLON,
* SDLK_EQUALS, SDLK_LEFTBRACKET, SDLK_RIGHTBRACKET,
* SDLK_BACKSLASH, SDLK_SLASH, SDLK_DELETE, SDLK_PERIOD };
*/
for (move=0; move<KEYBD_ARRAY_SIZE; move++) {
if (keysym == _fullKeybdDefs[move]) {
callLua(down ? "onInputPressed" : "onInputReleased", "ii", keysym, NOMOUSE);
break;
}
}
}
}
}
void singe(SDL_Window *window, SDL_Renderer *renderer) { void singe(SDL_Window *window, SDL_Renderer *renderer) {
int x = 0;
int y = 0;
int xr = 0;
int yr = 0;
int thisFrame = -1; int thisFrame = -1;
int lastFrame = -1; int lastFrame = -1;
int intReturn = 0; int intReturn = 0;
@ -1212,6 +1582,17 @@ void singe(SDL_Window *window, SDL_Renderer *renderer) {
SoundT *soundTemp = NULL; SoundT *soundTemp = NULL;
FontT *font = NULL; FontT *font = NULL;
FontT *fontTemp = NULL; FontT *fontTemp = NULL;
SDL_Event event;
ManyMouseEvent mouseEvent;
MouseT *mouse = NULL;
int mouseButtonMap[] = {
SWITCH_BUTTON1, // Left
SWITCH_BUTTON3, // Middle
SWITCH_BUTTON2, // Right
SWITCH_BUTTON1, // Wheel Up
SWITCH_BUTTON2, // Wheel Down
SWITCH_MOUSE_DISCONNECT
};
// Hang on to some SDL stuff // Hang on to some SDL stuff
_window = window; _window = window;
@ -1301,11 +1682,28 @@ void singe(SDL_Window *window, SDL_Renderer *renderer) {
// Open main video file // Open main video file
_videoHandle = videoLoad(_confVideoFile, _confDataDir, (bool)_confStretchVideo, _renderer); _videoHandle = videoLoad(_confVideoFile, _confDataDir, (bool)_confStretchVideo, _renderer);
if (_videoHandle < 0) utilDie("Unable to load video file: %s", _confVideoFile); if (_videoHandle < 0) utilDie("Unable to load video file: %s", _confVideoFile);
videoPlay(_videoHandle); videoSetVolume(_videoHandle, _confVolumeVldp, _confVolumeVldp);
// Mouse setup
_mouseCount = ManyMouse_Init();
if (_mouseCount < 1) utilDie("No mice detected.");
if (_mouseCount > MAX_MICE) {
_mouseCount = MAX_MICE;
}
memset(_mice, 0, sizeof(_mice));
_mouseEnabled = (bool)!_confNoMouse;
for (x=0; x<_mouseCount; x++) {
strncpy(_mice[x].name, ManyMouse_DeviceName((unsigned)x), sizeof(_mice[x].name));
_mice[x].name[sizeof(_mice[x].name) - 1] = 0;
_mice[x].x = videoGetWidth(_videoHandle) / 2;
_mice[x].y = videoGetHeight(_videoHandle) / 2;
}
SDL_SetWindowGrab(_window, SDL_TRUE);
// Create overlay texture // Create overlay texture
_overlay = SDL_CreateTexture(_renderer, SDL_PIXELFORMAT_BGRA32, SDL_TEXTUREACCESS_TARGET, videoGetWidth(_videoHandle), videoGetHeight(_videoHandle)); _overlay = SDL_CreateTexture(_renderer, SDL_PIXELFORMAT_BGRA32, SDL_TEXTUREACCESS_TARGET, videoGetWidth(_videoHandle), videoGetHeight(_videoHandle));
if (_overlay == NULL) utilDie("%s", SDL_GetError()); if (_overlay == NULL) utilDie("%s", SDL_GetError());
SDL_SetTextureBlendMode(_overlay, SDL_BLENDMODE_BLEND);
if (_confStretchVideo) { if (_confStretchVideo) {
SDL_RenderSetLogicalSize(_renderer, videoGetWidth(_videoHandle), videoGetHeight(_videoHandle)); SDL_RenderSetLogicalSize(_renderer, videoGetWidth(_videoHandle), videoGetHeight(_videoHandle));
} }
@ -1313,39 +1711,118 @@ void singe(SDL_Window *window, SDL_Renderer *renderer) {
// Set volume // Set volume
_effectsVolume = (int)((float)AUDIO_MAX_VOLUME * (float)_confVolumeNonVldp * (float)0.01); _effectsVolume = (int)((float)AUDIO_MAX_VOLUME * (float)_confVolumeNonVldp * (float)0.01);
Mix_Volume(-1, _effectsVolume * 2); Mix_Volume(-1, _effectsVolume * 2);
//***TODO*** Handle laser volume
// Start video
videoPlay(_videoHandle);
_discStopped = false;
//***TODO*** Sound completed callback
// Game Loop // Game Loop
while (_running) { while (_running) {
// Event Loop // SDL Event Loop
SDL_Event event;
while (SDL_PollEvent(&event)) { while (SDL_PollEvent(&event)) {
switch (event.type) { switch (event.type) {
case SDL_KEYDOWN: case SDL_KEYDOWN:
switch (event.key.keysym.sym) { processKey(true, event.key.keysym.sym);
default: //***TODO*** RDG used "g" to re-grab/re-scan for mice
//***TODO*** Process key
break;
}
break; break;
case SDL_KEYUP: case SDL_KEYUP:
switch (event.key.keysym.sym) { processKey(false, event.key.keysym.sym);
case SDLK_ESCAPE:
_running = false;
break;
default:
//***TODO*** Process key
break;
}
break; break;
case SDL_QUIT: case SDL_QUIT:
_running = 0; _running = 0;
break; break;
} }
// Mouse Event Loop
while (ManyMouse_PollEvent(&mouseEvent)) {
if (mouseEvent.device >= (unsigned)_mouseCount) continue;
mouse = &_mice[mouseEvent.device];
switch (mouseEvent.type) {
case MANYMOUSE_EVENT_RELMOTION:
switch (mouseEvent.item) {
case 0:
mouse->relx += mouseEvent.value;
break;
case 1:
mouse->rely += mouseEvent.value;
break;
}
// Clamp to video size
if (mouse->relx < 0) mouse->relx = 0;
if (mouse->relx > videoGetWidth(_videoHandle)) mouse->relx = videoGetWidth(_videoHandle) - 1;
if (mouse->rely < 0) mouse->rely = 0;
if (mouse->rely > videoGetHeight(_videoHandle)) mouse->rely = videoGetHeight(_videoHandle) - 1;
x *= _overlayScaleX;
y *= _overlayScaleY;
xr *= _overlayScaleX;
yr *= _overlayScaleY;
callLua("onMouseMoved", "iiiii", x, y, xr, yr, mouseEvent.device);
break;
case MANYMOUSE_EVENT_ABSMOTION:
switch (mouseEvent.item) {
case 0:
mouse->x += mouseEvent.value;
break;
case 1:
mouse->y += mouseEvent.value;
break;
}
x *= _overlayScaleX;
y *= _overlayScaleY;
xr *= _overlayScaleX;
yr *= _overlayScaleY;
callLua("onMouseMoved", "iiiii", x, y, xr, yr, mouseEvent.device);
break;
case MANYMOUSE_EVENT_BUTTON:
if (mouseEvent.item < 32) {
if (mouseEvent.value == 1) {
// Button pressed
callLua("onInputPressed", "ii", mouseButtonMap[mouseEvent.item], mouseEvent.device);
mouse->buttons |= (1 << mouseEvent.item);
} else {
// Button released
callLua("onInputReleased", "ii", mouseButtonMap[mouseEvent.item], mouseEvent.device);
mouse->buttons &= ~(1 << mouseEvent.item);
}
}
break;
case MANYMOUSE_EVENT_SCROLL:
if (mouseEvent.item == 0) {
if (mouseEvent.value > 0) {
// Scroll up
callLua("onInputPressed", "ii", SWITCH_MOUSE_SCROLL_UP, mouseEvent.device);
callLua("onInputReleased", "ii", SWITCH_MOUSE_SCROLL_UP, mouseEvent.device);
} else {
// Scroll down
callLua("onInputPressed", "ii", SWITCH_MOUSE_SCROLL_DOWN, mouseEvent.device);
callLua("onInputReleased", "ii", SWITCH_MOUSE_SCROLL_DOWN, mouseEvent.device);
}
}
break;
case MANYMOUSE_EVENT_DISCONNECT:
mouse->connected = false;
callLua("onInputPressed", "ii", SWITCH_MOUSE_DISCONNECT, mouseEvent.device);
callLua("onInputReleased", "ii", SWITCH_MOUSE_DISCONNECT, mouseEvent.device);
break;
case MANYMOUSE_EVENT_MAX:
// We don't use this
break;
}
}
} }
// Call game code // Call game code
@ -1412,4 +1889,7 @@ void singe(SDL_Window *window, SDL_Renderer *renderer) {
// Unload video // Unload video
videoUnload(_videoHandle); videoUnload(_videoHandle);
// Stop mice
ManyMouse_Quit();
} }

View file

@ -44,6 +44,8 @@ typedef struct VideoPlayerS {
byte audioSampleBytes; byte audioSampleBytes;
byte *audioSilenceRaw; byte *audioSilenceRaw;
char errMsg[1024]; char errMsg[1024];
int volumeLeft;
int volumeRight;
int audioTrack; int audioTrack;
int videoTrack; int videoTrack;
int frame; int frame;
@ -91,6 +93,9 @@ void _dequeueVideoAudio(int channel, void *stream, int bytes, void *udata) {
int bytesToCopy = bytes; int bytesToCopy = bytes;
int available = SDL_AudioStreamAvailable(v->audioStream); int available = SDL_AudioStreamAvailable(v->audioStream);
int remainder = 0; int remainder = 0;
int bytesRead = 0;
int i = 0;
Sint16 *data = stream;
(void)channel; (void)channel;
@ -103,7 +108,22 @@ void _dequeueVideoAudio(int channel, void *stream, int bytes, void *udata) {
remainder = bytesToCopy % v->audioSampleSize; remainder = bytesToCopy % v->audioSampleSize;
bytesToCopy -= remainder; bytesToCopy -= remainder;
if (SDL_AudioStreamGet(v->audioStream, stream, bytesToCopy) < 0) utilDie("%s", SDL_GetError()); // Read audio data
bytesRead = SDL_AudioStreamGet(v->audioStream, stream, bytesToCopy);
if (bytesRead < 0) utilDie("%s", SDL_GetError());
// We do our own volume per channel here in the mixer
if (_mixChannels < 2) {
// Mono output, average volume levels together
Mix_Volume(channel, (int)((float)MIX_MAX_VOLUME * ((float)v->volumeLeft * (float)v->volumeRight / (float)2) * (float)0.01));
} else {
// Stereo output. Assumes MIX_DEFAULT_FORMAT for now.
Mix_Volume(channel, MIX_MAX_VOLUME);
for (i=0; i<bytesRead / 2; i+=2) {
data[i] = (Sint16)((float)data[i] * (float)v->volumeLeft * (float)0.01);
data[i + 1] = (Sint16)((float)data[i] * (float)v->volumeRight * (float)0.01);
}
}
} }
@ -120,6 +140,7 @@ int FFMS_CC _indexCallBack(int64_t current, int64_t total, void *ICPrivate) {
if (thisPercent != lastPercent) { if (thisPercent != lastPercent) {
lastPercent = thisPercent; lastPercent = thisPercent;
utilSay("Indexing: %d%%", thisPercent); utilSay("Indexing: %d%%", thisPercent);
//***TODO*** GUI
} }
} }
@ -138,6 +159,9 @@ int videoInit(void) {
if (!Mix_QuerySpec(&_mixRate, &_mixFormat, &channels)) utilDie("%s", Mix_GetError()); if (!Mix_QuerySpec(&_mixRate, &_mixFormat, &channels)) utilDie("%s", Mix_GetError());
_mixChannels = (Uint8)channels; _mixChannels = (Uint8)channels;
// Volume only works with MIX_DEFAULT_FORMAT
if (_mixFormat != MIX_DEFAULT_FORMAT) utilDie("videoInit: Only MIX_DEFAULT_FORMAT audio is supported.");
return 0; return 0;
} }
@ -186,6 +210,20 @@ int videoGetWidth(int playerIndex) {
} }
int videoGetVolume(int playerIndex, int *leftPercent, int *rightPercent) {
VideoPlayerT *v = NULL;
// Get our player structure
HASH_FIND_INT(_videoPlayerHash, &playerIndex, v);
if (!v) utilDie("No video player at index %d in videoGetVolume.", playerIndex);
if (leftPercent != NULL) *leftPercent = v->volumeLeft;
if (rightPercent != NULL) *rightPercent = v->volumeRight;
return 0;
}
int videoLoad(char *filename, char *indexPath, bool stretchVideo, SDL_Renderer *renderer) { int videoLoad(char *filename, char *indexPath, bool stretchVideo, SDL_Renderer *renderer) {
char indexName[1024]; char indexName[1024];
int pixelFormats[2]; int pixelFormats[2];
@ -321,6 +359,10 @@ int videoLoad(char *filename, char *indexPath, bool stretchVideo, SDL_Renderer *
// Register effect to provide video stream audio on this channel // Register effect to provide video stream audio on this channel
Mix_RegisterEffect(v->audioSilenceChannel, _dequeueVideoAudio, NULL, v); Mix_RegisterEffect(v->audioSilenceChannel, _dequeueVideoAudio, NULL, v);
// Default volume, in percent
v->volumeLeft = 100;
v->volumeRight = 100;
/* /*
utilSay("Frames: %d (%dx%d) Audio Samples: %ld (%d Hz) %d Channel%s", utilSay("Frames: %d (%dx%d) Audio Samples: %ld (%d Hz) %d Channel%s",
v->videoProps->NumFrames, v->videoProps->NumFrames,
@ -407,6 +449,20 @@ int videoSeek(int playerIndex, int seekFrame) {
} }
int videoSetVolume(int playerIndex, int leftPercent, int rightPercent) {
VideoPlayerT *v = NULL;
// Get our player structure
HASH_FIND_INT(_videoPlayerHash, &playerIndex, v);
if (!v) utilDie("No video player at index %d in videoSetVolume.", playerIndex);
v->volumeLeft = leftPercent;
v->volumeRight = rightPercent;
return 0;
}
int videoUnload(int playerIndex) { int videoUnload(int playerIndex) {
VideoPlayerT *v = NULL; VideoPlayerT *v = NULL;

View file

@ -34,11 +34,13 @@ int videoIsPlaying(int playerIndex);
int videoGetFrame(int playerIndex); int videoGetFrame(int playerIndex);
int videoGetHeight(int playerIndex); int videoGetHeight(int playerIndex);
int videoGetWidth(int playerIndex); int videoGetWidth(int playerIndex);
int videoGetVolume(int playerIndex, int *leftPercent, int *rightPercent);
int videoLoad(char *filename, char *indexPath, bool stretchVideo, SDL_Renderer *renderer); int videoLoad(char *filename, char *indexPath, bool stretchVideo, SDL_Renderer *renderer);
int videoPause(int playerIndex); int videoPause(int playerIndex);
int videoPlay(int playerIndex); int videoPlay(int playerIndex);
int videoQuit(void); int videoQuit(void);
int videoSeek(int playerIndex, int seekFrame); int videoSeek(int playerIndex, int seekFrame);
int videoSetVolume(int playerIndex, int leftPercent, int rightPercent);
int videoUnload(int playerIndex); int videoUnload(int playerIndex);
int videoUpdate(int playerIndex, SDL_Texture **texture); int videoUpdate(int playerIndex, SDL_Texture **texture);