Keyboard and mouse mostly implemented.
This commit is contained in:
parent
fa91f8e281
commit
9f44dc055c
4 changed files with 608 additions and 68 deletions
|
@ -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);
|
||||
if (window == NULL) utilDie("%s", SDL_GetError());
|
||||
|
||||
//***TODO*** Window Icon
|
||||
|
||||
// Do we want full screen of some kind?
|
||||
if (_confFullScreen || _confFullScreenWindow) {
|
||||
flags = _confFullScreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
|
|
552
singe/singe.c
552
singe/singe.c
|
@ -31,6 +31,7 @@
|
|||
#include <lauxlib.h>
|
||||
|
||||
#include "thirdparty/uthash.h"
|
||||
#include "thirdparty/manymouse/manymouse.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "util.h"
|
||||
|
@ -40,8 +41,29 @@
|
|||
|
||||
#define AUDIO_MAX_VOLUME 63
|
||||
#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 {
|
||||
int id;
|
||||
#pragma GCC diagnostic push
|
||||
|
@ -70,6 +92,35 @@ typedef struct FontS {
|
|||
} 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 {
|
||||
KEYBD_NORMAL = 0,
|
||||
KEYBD_FULL
|
||||
|
@ -107,6 +158,7 @@ int _confYResolution = -1;
|
|||
|
||||
|
||||
// Other globals
|
||||
static MouseT _mice[MAX_MICE];
|
||||
static lua_State *_luaContext = NULL;
|
||||
static SDL_Color _colorForeground = { 255, 255, 255, 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 _videoHandle = -1;
|
||||
static int _fontQuality = 1;
|
||||
static double _overlayScaleX = 1;
|
||||
static double _overlayScaleY = 1;
|
||||
static int _mouseMode = MOUSE_SINGLE;
|
||||
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 _pauseEnabled = true; // by RDG2010
|
||||
static bool _running = true;
|
||||
static bool _discStopped = true;
|
||||
static bool _mouseEnabled = true;
|
||||
static SpriteT *_spriteList = NULL;
|
||||
static SoundT *_soundList = NULL;
|
||||
static FontT *_fontList = 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 apiColorForeground(lua_State *L);
|
||||
|
@ -194,16 +293,64 @@ int apiSingeQuit(lua_State *L);
|
|||
int apiSingeVersion(lua_State *L);
|
||||
int apiSingeSetGameName(lua_State *L);
|
||||
int apiSingeGetScriptPath(lua_State *L);
|
||||
void callLua(const char *func, const char *sig, ...);
|
||||
int luaError(lua_State *L);
|
||||
void processKey(bool down, int keysym);
|
||||
|
||||
|
||||
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 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 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 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) {
|
||||
if (_discStopped) {
|
||||
lua_pushinteger(L, 0);
|
||||
} else {
|
||||
lua_pushinteger(L, videoGetFrame(_videoHandle));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int apiDiscPause(lua_State *L) {
|
||||
(void)L;
|
||||
if (!_discStopped) {
|
||||
videoPause(_videoHandle);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -269,12 +470,14 @@ int apiDiscPause(lua_State *L) {
|
|||
int apiDiscPauseAtFrame(lua_State *L) {
|
||||
int n = lua_gettop(L);
|
||||
|
||||
if (!_discStopped) {
|
||||
if (n == 1) {
|
||||
if (lua_isinteger(L, 1)) {
|
||||
videoSeek(_videoHandle, (int)lua_tointeger(L, 1));
|
||||
videoPause(_videoHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -283,17 +486,20 @@ int apiDiscPauseAtFrame(lua_State *L) {
|
|||
int apiDiscPlay(lua_State *L) {
|
||||
(void)L;
|
||||
videoPlay(_videoHandle);
|
||||
_discStopped = false;
|
||||
}
|
||||
|
||||
|
||||
int apiDiscSearch(lua_State *L) {
|
||||
int n = lua_gettop(L);
|
||||
|
||||
if (!_discStopped) {
|
||||
if (n == 1) {
|
||||
if (lua_isinteger(L, 1)) {
|
||||
videoSeek(_videoHandle, (int)lua_tointeger(L, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -316,11 +522,13 @@ int apiDiscSetFps(lua_State *L) {
|
|||
int apiDiscSkipBackward(lua_State *L) {
|
||||
int n = lua_gettop(L);
|
||||
|
||||
if (!_discStopped) {
|
||||
if (n == 1) {
|
||||
if (lua_isinteger(L, 1)) {
|
||||
videoSeek(_videoHandle, videoGetFrame(_videoHandle) - (int)lua_tointeger(L, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -336,11 +544,13 @@ int apiDiscSkipBlanking(lua_State *L) {
|
|||
int apiDiscSkipForward(lua_State *L) {
|
||||
int n = lua_gettop(L);
|
||||
|
||||
if (!_discStopped) {
|
||||
if (n == 1) {
|
||||
if (lua_isinteger(L, 1)) {
|
||||
videoSeek(_videoHandle, videoGetFrame(_videoHandle) + (int)lua_tointeger(L, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -354,22 +564,26 @@ int apiDiscSkipToFrame(lua_State *L) {
|
|||
|
||||
int apiDiscStepBackward(lua_State *L) {
|
||||
(void)L;
|
||||
if (!_discStopped) {
|
||||
videoSeek(_videoHandle, videoGetFrame(_videoHandle) - 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int apiDiscStepForward(lua_State *L) {
|
||||
(void)L;
|
||||
if (!_discStopped) {
|
||||
videoSeek(_videoHandle, videoGetFrame(_videoHandle) + 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int apiDiscStop(lua_State *L) {
|
||||
(void)L;
|
||||
//***TODO*** Add a real stopped state
|
||||
videoPause(_videoHandle);
|
||||
_discStopped = true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -391,9 +605,9 @@ int apiFontLoad(lua_State *L) {
|
|||
font->font = TTF_OpenFont(name, points);
|
||||
if (!font->font) utilDie("%s", TTF_GetError());
|
||||
// Make it the current font and mark it as loaded.
|
||||
_fontCurrent = _nextFontId++;
|
||||
font->id = _fontCurrent;
|
||||
result = _fontCurrent;
|
||||
font->id = _nextFontId;
|
||||
result = _nextFontId++;
|
||||
_fontCurrent = font;
|
||||
HASH_ADD_INT(_fontList, id, font);
|
||||
}
|
||||
}
|
||||
|
@ -405,7 +619,53 @@ int apiFontLoad(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 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);
|
||||
if (!sound) utilDie("No sound at index %d in apiSoundPlay.", id);
|
||||
result = Mix_PlayChannel(-1, sound->chunk, 0);
|
||||
Mix_Volume(result, _effectsVolume * 2);
|
||||
}
|
||||
}
|
||||
lua_pushnumber(L, result);
|
||||
|
@ -711,7 +984,6 @@ int apiSoundSetVolume(lua_State *L) {
|
|||
if (thisValue >= 0 && thisValue <= AUDIO_MAX_VOLUME) {
|
||||
_effectsVolume = thisValue;
|
||||
Mix_Volume(-1, _effectsVolume * 2);
|
||||
//***TODO*** Handle laser volume
|
||||
} else {
|
||||
utilDie("Invalid sound volume value.");
|
||||
}
|
||||
|
@ -862,7 +1134,37 @@ int apiVldpGetHeight(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) {
|
||||
// Enables mouse monitoring
|
||||
(void)L;
|
||||
//***TODO*** g_pSingeIn->dll_side_mouse_enable(g_pSingeIn->pSingeInstance);
|
||||
_mouseEnabled = (bool)!_confNoMouse;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -925,7 +1227,7 @@ int apiMouseEnable(lua_State *L) {
|
|||
int apiMouseDisable(lua_State *L) {
|
||||
// Disables mouse monitoring
|
||||
(void)L;
|
||||
//***TODO*** g_pSingeIn->dll_side_mouse_disable(g_pSingeIn->pSingeInstance);
|
||||
_mouseEnabled = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -949,24 +1251,22 @@ int apiMouseSetMode(lua_State *L) {
|
|||
// --rdg
|
||||
|
||||
int n = lua_gettop(L);
|
||||
int thisValue = 0;
|
||||
bool result = false;
|
||||
|
||||
if (n == 1) {
|
||||
if (lua_isinteger(L, 1)) {
|
||||
thisValue = (int)lua_tointeger(L, 1);
|
||||
//***TODO*** result = g_pSingeIn->dll_side_set_mouse_mode(thisValue);
|
||||
if (!result) utilDie("mouseSetMode failed. Is mouse enabled?");
|
||||
_mouseMode = (int)lua_tointeger(L, 1);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
lua_pushboolean(L, result);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int apiMouseHowMany(lua_State *L) {
|
||||
int total = 1; //***TODO*** g_pSingeIn->dll_side_mouse_get_how_many(g_pSingeIn->pSingeInstance);
|
||||
lua_pushinteger(L, total);
|
||||
lua_pushinteger(L, _mouseCount);
|
||||
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
|
||||
lua_pushinteger(L, videoIsPlaying(_videoHandle) ? LDP_PLAYING : LDP_PAUSE);
|
||||
lua_pushinteger(L, _discStopped ? LDP_STOPPED : (videoIsPlaying(_videoHandle) ? LDP_PLAYING : LDP_PAUSE));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1067,7 +1366,8 @@ int apiSingeSetGameName(lua_State *L) {
|
|||
if (n == 1) {
|
||||
if (lua_isstring(L, 1)) {
|
||||
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) {
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int xr = 0;
|
||||
int yr = 0;
|
||||
int thisFrame = -1;
|
||||
int lastFrame = -1;
|
||||
int intReturn = 0;
|
||||
|
@ -1212,6 +1582,17 @@ void singe(SDL_Window *window, SDL_Renderer *renderer) {
|
|||
SoundT *soundTemp = NULL;
|
||||
FontT *font = 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
|
||||
_window = window;
|
||||
|
@ -1301,11 +1682,28 @@ void singe(SDL_Window *window, SDL_Renderer *renderer) {
|
|||
// Open main video file
|
||||
_videoHandle = videoLoad(_confVideoFile, _confDataDir, (bool)_confStretchVideo, _renderer);
|
||||
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
|
||||
_overlay = SDL_CreateTexture(_renderer, SDL_PIXELFORMAT_BGRA32, SDL_TEXTUREACCESS_TARGET, videoGetWidth(_videoHandle), videoGetHeight(_videoHandle));
|
||||
if (_overlay == NULL) utilDie("%s", SDL_GetError());
|
||||
SDL_SetTextureBlendMode(_overlay, SDL_BLENDMODE_BLEND);
|
||||
if (_confStretchVideo) {
|
||||
SDL_RenderSetLogicalSize(_renderer, videoGetWidth(_videoHandle), videoGetHeight(_videoHandle));
|
||||
}
|
||||
|
@ -1313,39 +1711,118 @@ void singe(SDL_Window *window, SDL_Renderer *renderer) {
|
|||
// Set volume
|
||||
_effectsVolume = (int)((float)AUDIO_MAX_VOLUME * (float)_confVolumeNonVldp * (float)0.01);
|
||||
Mix_Volume(-1, _effectsVolume * 2);
|
||||
//***TODO*** Handle laser volume
|
||||
|
||||
// Start video
|
||||
videoPlay(_videoHandle);
|
||||
_discStopped = false;
|
||||
|
||||
//***TODO*** Sound completed callback
|
||||
|
||||
// Game Loop
|
||||
while (_running) {
|
||||
|
||||
// Event Loop
|
||||
SDL_Event event;
|
||||
// SDL Event Loop
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
case SDL_KEYDOWN:
|
||||
switch (event.key.keysym.sym) {
|
||||
default:
|
||||
//***TODO*** Process key
|
||||
break;
|
||||
}
|
||||
processKey(true, event.key.keysym.sym);
|
||||
//***TODO*** RDG used "g" to re-grab/re-scan for mice
|
||||
break;
|
||||
|
||||
case SDL_KEYUP:
|
||||
switch (event.key.keysym.sym) {
|
||||
case SDLK_ESCAPE:
|
||||
_running = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
//***TODO*** Process key
|
||||
break;
|
||||
}
|
||||
processKey(false, event.key.keysym.sym);
|
||||
break;
|
||||
|
||||
case SDL_QUIT:
|
||||
_running = 0;
|
||||
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
|
||||
|
@ -1412,4 +1889,7 @@ void singe(SDL_Window *window, SDL_Renderer *renderer) {
|
|||
|
||||
// Unload video
|
||||
videoUnload(_videoHandle);
|
||||
|
||||
// Stop mice
|
||||
ManyMouse_Quit();
|
||||
}
|
||||
|
|
|
@ -44,6 +44,8 @@ typedef struct VideoPlayerS {
|
|||
byte audioSampleBytes;
|
||||
byte *audioSilenceRaw;
|
||||
char errMsg[1024];
|
||||
int volumeLeft;
|
||||
int volumeRight;
|
||||
int audioTrack;
|
||||
int videoTrack;
|
||||
int frame;
|
||||
|
@ -91,6 +93,9 @@ void _dequeueVideoAudio(int channel, void *stream, int bytes, void *udata) {
|
|||
int bytesToCopy = bytes;
|
||||
int available = SDL_AudioStreamAvailable(v->audioStream);
|
||||
int remainder = 0;
|
||||
int bytesRead = 0;
|
||||
int i = 0;
|
||||
Sint16 *data = stream;
|
||||
|
||||
(void)channel;
|
||||
|
||||
|
@ -103,7 +108,22 @@ void _dequeueVideoAudio(int channel, void *stream, int bytes, void *udata) {
|
|||
remainder = bytesToCopy % v->audioSampleSize;
|
||||
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) {
|
||||
lastPercent = thisPercent;
|
||||
utilSay("Indexing: %d%%", thisPercent);
|
||||
//***TODO*** GUI
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,6 +159,9 @@ int videoInit(void) {
|
|||
if (!Mix_QuerySpec(&_mixRate, &_mixFormat, &channels)) utilDie("%s", Mix_GetError());
|
||||
_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;
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
char indexName[1024];
|
||||
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
|
||||
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",
|
||||
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) {
|
||||
VideoPlayerT *v = NULL;
|
||||
|
||||
|
|
|
@ -34,11 +34,13 @@ int videoIsPlaying(int playerIndex);
|
|||
int videoGetFrame(int playerIndex);
|
||||
int videoGetHeight(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 videoPause(int playerIndex);
|
||||
int videoPlay(int playerIndex);
|
||||
int videoQuit(void);
|
||||
int videoSeek(int playerIndex, int seekFrame);
|
||||
int videoSetVolume(int playerIndex, int leftPercent, int rightPercent);
|
||||
int videoUnload(int playerIndex);
|
||||
int videoUpdate(int playerIndex, SDL_Texture **texture);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue