Overlay now using blending instead of color key for transparency. Data folder automatically generates subdirectory names for individual games. Beta 12 released.

This commit is contained in:
Scott Duensing 2020-03-23 18:20:45 -05:00
parent c885b533dd
commit fe607e6682
9 changed files with 71 additions and 53 deletions

View file

@ -49,7 +49,6 @@ for dir in lfs.dir(".") do
end end
end end
table.sort(FOUND_GAMES, compareTitles) table.sort(FOUND_GAMES, compareTitles)
scriptExecute(FOUND_GAMES[1])
font = fontLoad("ActionMax/font_LED_Real.ttf", 32); font = fontLoad("ActionMax/font_LED_Real.ttf", 32);

View file

@ -64,8 +64,8 @@ function doBuild() {
${CROSS}-${CPPCOMPILER} -o "${TARGET}" ${OFILES} ${EXTRA_OFILES} "-L${SOURCE_DIR}/../thirdparty-build/${OSNAME}/${OSARCH}/installed/lib" ${EXTRA_LD_FLAGS} ${CROSS}-${CPPCOMPILER} -o "${TARGET}" ${OFILES} ${EXTRA_OFILES} "-L${SOURCE_DIR}/../thirdparty-build/${OSNAME}/${OSARCH}/installed/lib" ${EXTRA_LD_FLAGS}
echo "Compressing ${TARGET}..." echo "Compressing ${TARGET}..."
#${CROSS}-strip "${TARGET}" ${CROSS}-strip "${TARGET}"
#upx -9 "${TARGET}" upx -9 "${TARGET}"
popd popd
} }

View file

@ -3,7 +3,6 @@ GAMES = {
TITLE = ".38 Ambush Alley", TITLE = ".38 Ambush Alley",
SCRIPT = "ActionMax/38AmbushAlley.singe", SCRIPT = "ActionMax/38AmbushAlley.singe",
VIDEO = "ActionMax/frame_38AmbushAlley.txt", VIDEO = "ActionMax/frame_38AmbushAlley.txt",
DATA = "ActionMax",
STRETCH = false, STRETCH = false,
NO_MOUSE = false, NO_MOUSE = false,
RESOLUTION_X = 720, RESOLUTION_X = 720,
@ -25,7 +24,6 @@ GAMES = {
TITLE = "Blue Thunder", TITLE = "Blue Thunder",
SCRIPT = "ActionMax/BlueThunder.singe", SCRIPT = "ActionMax/BlueThunder.singe",
VIDEO = "ActionMax/frame_BlueThunder.txt", VIDEO = "ActionMax/frame_BlueThunder.txt",
DATA = "ActionMax",
STRETCH = false, STRETCH = false,
NO_MOUSE = false, NO_MOUSE = false,
RESOLUTION_X = 720, RESOLUTION_X = 720,
@ -69,7 +67,6 @@ GAMES = {
TITLE = "Rescue of Pops Ghostly, The", TITLE = "Rescue of Pops Ghostly, The",
SCRIPT = "ActionMax/PopsGhostly.singe", SCRIPT = "ActionMax/PopsGhostly.singe",
VIDEO = "ActionMax/frame_PopsGhostly.txt", VIDEO = "ActionMax/frame_PopsGhostly.txt",
DATA = "ActionMax",
STRETCH = false, STRETCH = false,
NO_MOUSE = false, NO_MOUSE = false,
RESOLUTION_X = 720, RESOLUTION_X = 720,
@ -91,7 +88,6 @@ GAMES = {
TITLE = "Sonic Fury", TITLE = "Sonic Fury",
SCRIPT = "ActionMax/SonicFury.singe", SCRIPT = "ActionMax/SonicFury.singe",
VIDEO = "ActionMax/frame_SonicFury.txt", VIDEO = "ActionMax/frame_SonicFury.txt",
DATA = "ActionMax",
STRETCH = false, STRETCH = false,
NO_MOUSE = false, NO_MOUSE = false,
RESOLUTION_X = 720, RESOLUTION_X = 720,

View file

@ -355,9 +355,12 @@ ConfigT *createConf(char *exeName, int argc, char *argv[]) {
conf->isFrameFile = true; conf->isFrameFile = true;
} }
// Do we need to generate a data directory name? // They provided a data directory. Append the game name.
if (conf->dataDir) { if (conf->dataDir) {
utilFixPathSeparators(&conf->dataDir, false); conf->dataDirBase = strdup(conf->dataDir);
utilFixPathSeparators(&conf->dataDirBase, true);
free(conf->dataDir);
conf->dataDir = utilCreateString("%s%s", conf->dataDirBase, utilGetUpToLastPathComponent(conf->scriptFile));
// Try to create data directory to ensure it exists. // Try to create data directory to ensure it exists.
utilMkDirP(conf->dataDir, 0777); utilMkDirP(conf->dataDir, 0777);
// Does it exist? // Does it exist?
@ -366,16 +369,9 @@ ConfigT *createConf(char *exeName, int argc, char *argv[]) {
conf->dataDir = NULL; conf->dataDir = NULL;
} }
} else { } else {
// Put it in the game folder. // No data directory specified. Use the game folder.
x = (int32_t)(strlen(conf->scriptFile) - strlen(utilGetLastPathComponent(conf->scriptFile))) - 1; conf->dataDirBase = utilCreateString(".%c", utilGetPathSeparator());
if (x < 0) { conf->dataDir = strdup(utilGetUpToLastPathComponent(conf->scriptFile));
x = 0;
}
temp = strdup(conf->scriptFile);
temp[x] = 0;
conf->dataDir = strdup(temp);
free(temp);
temp = NULL;
} }
if (!conf->dataDir) showUsage(exeName, "Unable to locate data directory."); if (!conf->dataDir) showUsage(exeName, "Unable to locate data directory.");
utilFixPathSeparators(&conf->dataDir, true); utilFixPathSeparators(&conf->dataDir, true);
@ -697,6 +693,7 @@ void showUsage(char *name, char *message) {
temp = utilCreateString("Singe%cFramework.singe", utilGetPathSeparator()); temp = utilCreateString("Singe%cFramework.singe", utilGetPathSeparator());
created |= extractFile(temp, Framework_singe, Framework_singe_len); created |= extractFile(temp, Framework_singe, Framework_singe_len);
free(temp); free(temp);
/*
// Singe/Menu.singe // Singe/Menu.singe
temp = utilCreateString("Singe%cMenu.singe", utilGetPathSeparator()); temp = utilCreateString("Singe%cMenu.singe", utilGetPathSeparator());
created |= extractFile(temp, Menu_singe, Menu_singe_len); created |= extractFile(temp, Menu_singe, Menu_singe_len);
@ -705,6 +702,7 @@ void showUsage(char *name, char *message) {
temp = utilCreateString("Singe%cmenuBackground.mkv", utilGetPathSeparator()); temp = utilCreateString("Singe%cmenuBackground.mkv", utilGetPathSeparator());
created |= extractFile(temp, menuBackground_mkv, menuBackground_mkv_len); created |= extractFile(temp, menuBackground_mkv, menuBackground_mkv_len);
free(temp); free(temp);
*/
// Singe/controls.cfg.example // Singe/controls.cfg.example
temp = utilCreateString("Singe%ccontrols.cfg.example", utilGetPathSeparator()); temp = utilCreateString("Singe%ccontrols.cfg.example", utilGetPathSeparator());
created |= extractFile(temp, controls_cfg, controls_cfg_len); created |= extractFile(temp, controls_cfg, controls_cfg_len);
@ -742,7 +740,6 @@ int main(int argc, char *argv[]) {
launcher(exeName, conf); launcher(exeName, conf);
destroyConf(&conf); destroyConf(&conf);
LL_DELETE(_scriptQueue, q); LL_DELETE(_scriptQueue, q);
free(q);
} }
return 0; return 0;

View file

@ -1399,7 +1399,7 @@ int32_t apiOverlaySetResolution(lua_State *L) {
// Create the new one. // Create the new one.
_global.overlay = SDL_CreateRGBSurfaceWithFormat(0, x, y, 32, SDL_PIXELFORMAT_BGRA32); _global.overlay = SDL_CreateRGBSurfaceWithFormat(0, x, y, 32, SDL_PIXELFORMAT_BGRA32);
if (_global.overlay == NULL) utilDie("%s", SDL_GetError()); if (_global.overlay == NULL) utilDie("%s", SDL_GetError());
SDL_SetColorKey(_global.overlay, true, 0); SDL_SetSurfaceBlendMode(_global.overlay, SDL_BLENDMODE_BLEND);
// Update some variables. // Update some variables.
_global.overlayScaleX = x / videoGetWidth(_global.videoHandle); _global.overlayScaleX = x / videoGetWidth(_global.videoHandle);
_global.overlayScaleY = y / videoGetHeight(_global.videoHandle); _global.overlayScaleY = y / videoGetHeight(_global.videoHandle);
@ -1912,14 +1912,12 @@ int32_t apiVideoDraw(lua_State *L) {
if (video->surface) SDL_FreeSurface(video->surface); if (video->surface) SDL_FreeSurface(video->surface);
SDL_QueryTexture(video->texture, NULL, NULL, &w, &h); SDL_QueryTexture(video->texture, NULL, NULL, &w, &h);
video->surface = SDL_CreateRGBSurface(0, w, h, 32, 0, 0, 0, 255); video->surface = SDL_CreateRGBSurface(0, w, h, 32, 0, 0, 0, 255);
SDL_SetColorKey(video->surface, SDL_FALSE, 0);
if (!video->surface) utilDie("%s", SDL_GetError()); if (!video->surface) utilDie("%s", SDL_GetError());
if (SDL_SetRenderTarget(_global.renderer, video->texture) < 0) luaDie(L, "videoDraw", "%s", SDL_GetError()); if (SDL_SetRenderTarget(_global.renderer, video->texture) < 0) luaDie(L, "videoDraw", "%s", SDL_GetError());
if (SDL_RenderReadPixels(_global.renderer, NULL, video->surface->format->format, video->surface->pixels, video->surface->pitch) != 0) luaDie(L, "videoDraw", "%s", SDL_GetError()); if (SDL_RenderReadPixels(_global.renderer, NULL, video->surface->format->format, video->surface->pixels, video->surface->pitch) != 0) luaDie(L, "videoDraw", "%s", SDL_GetError());
if (SDL_SetRenderTarget(_global.renderer, NULL) < 0) luaDie(L, "videoDraw", "%s", SDL_GetError()); if (SDL_SetRenderTarget(_global.renderer, NULL) < 0) luaDie(L, "videoDraw", "%s", SDL_GetError());
} }
// Render frame into overlay // Render frame into overlay
SDL_SetColorKey(_global.overlay, SDL_FALSE, 0);
if (SDL_BlitScaled(video->surface, NULL, _global.overlay, &dest) != 0) luaDie(L, "videoDraw", "%s", SDL_GetError()); if (SDL_BlitScaled(video->surface, NULL, _global.overlay, &dest) != 0) luaDie(L, "videoDraw", "%s", SDL_GetError());
result = true; result = true;
} }
@ -2125,25 +2123,18 @@ int32_t apiVideoLoad(lua_State *L) {
int32_t n = lua_gettop(L); int32_t n = lua_gettop(L);
int32_t result = -1; int32_t result = -1;
const char *name = NULL; const char *name = NULL;
const char *data = NULL; char *data = NULL;
VideoT *video = NULL; VideoT *video = NULL;
if ((n == 1) || (n == 2)) { if (n == 1) {
if (lua_isstring(L, 1)) { if (lua_isstring(L, 1)) {
name = lua_tostring(L, 1); name = lua_tostring(L, 1);
if (n == 2) { // Create data directory based on video path.
if (lua_isstring(L, 2)) { data = utilCreateString("%s%s", _global.conf.dataDirBase, utilGetUpToLastPathComponent((char *)name));
data = lua_tostring(L, 2);
} else {
luaDie(L, "videoLoad", "Optional second parameter must be a string.");
}
} else {
data = _global.conf.dataDir;
}
video = (VideoT *)calloc(1, sizeof(VideoT)); video = (VideoT *)calloc(1, sizeof(VideoT));
if (!video) luaDie(L, "videoLoad", "Unable to allocate new video."); if (!video) luaDie(L, "videoLoad", "Unable to allocate new video.");
// Load this video. // Load this video.
video->handle = videoLoad((char *)name, (char *)data, false, _global.renderer); video->handle = videoLoad((char *)name, data, false, _global.renderer);
if (video->handle < 0) luaDie(L, "videoLoad", "Failed to load video: %s", name); if (video->handle < 0) luaDie(L, "videoLoad", "Failed to load video: %s", name);
video->id = _global.nextVideoId; video->id = _global.nextVideoId;
video->lastFrame = -1; video->lastFrame = -1;
@ -2158,6 +2149,8 @@ int32_t apiVideoLoad(lua_State *L) {
luaTrace(L, "fontVideo", "Failed!"); luaTrace(L, "fontVideo", "Failed!");
} }
free(data);
lua_pushnumber(L, result); lua_pushnumber(L, result);
return 1;} return 1;}
@ -2729,9 +2722,9 @@ int32_t apiSingeGetScriptPath(lua_State *L) {
ConfigT *buildConfFromTable(lua_State *L) { ConfigT *buildConfFromTable(lua_State *L) {
char *sindenString = NULL;
const char *confKey = NULL; const char *confKey = NULL;
const char *valueString = NULL; const char *valueString = NULL;
char *sindenString = NULL;
bool valueBoolean = false; bool valueBoolean = false;
int64_t valueNumber = 0; int64_t valueNumber = 0;
ConfigT *c = NULL; ConfigT *c = NULL;
@ -2739,9 +2732,10 @@ ConfigT *buildConfFromTable(lua_State *L) {
// Start with current config. // Start with current config.
c = (ConfigT *)calloc(1, sizeof(ConfigT)); c = (ConfigT *)calloc(1, sizeof(ConfigT));
memcpy(c, &_global.conf, sizeof(ConfigT)); memcpy(c, &_global.conf, sizeof(ConfigT));
if (_global.conf.scriptFile) c->scriptFile = strdup(_global.conf.scriptFile); if (_global.conf.scriptFile) c->scriptFile = strdup(_global.conf.scriptFile);
if (_global.conf.videoFile) c->videoFile = strdup(_global.conf.videoFile); if (_global.conf.videoFile) c->videoFile = strdup(_global.conf.videoFile);
if (_global.conf.dataDir) c->dataDir = strdup(_global.conf.dataDir); if (_global.conf.dataDirBase) c->dataDirBase = strdup(_global.conf.dataDirBase);
if (_global.conf.dataDir) c->dataDir = strdup(_global.conf.dataDir);
// Update with data in the table on the top of the Lua stack. // Update with data in the table on the top of the Lua stack.
lua_pushnil(L); lua_pushnil(L);
@ -2780,12 +2774,15 @@ ConfigT *buildConfFromTable(lua_State *L) {
if (strcmp(confKey, "SCRIPT") == 0) { if (strcmp(confKey, "SCRIPT") == 0) {
if (c->scriptFile) free (c->scriptFile); if (c->scriptFile) free (c->scriptFile);
c->scriptFile = strdup(valueString); c->scriptFile = strdup(valueString);
utilFixPathSeparators(&c->scriptFile, false);
} else if (strcmp(confKey, "VIDEO") == 0) { } else if (strcmp(confKey, "VIDEO") == 0) {
if (c->videoFile) free(c->videoFile); if (c->videoFile) free(c->videoFile);
c->videoFile = strdup(valueString); c->videoFile = strdup(valueString);
} else if (strcmp(confKey, "DATA") == 0) { utilFixPathSeparators(&c->videoFile, false);
if (c->dataDir) free(c->dataDir); // Is it a framefile?
c->dataDir = strdup(valueString); if (strncmp(utilGetFileExtension(c->videoFile), "txt", 3) == 0) {
c->isFrameFile = true;
}
} else if (strcmp(confKey, "STRETCH") == 0) { } else if (strcmp(confKey, "STRETCH") == 0) {
c->stretchVideo = valueBoolean; c->stretchVideo = valueBoolean;
} else if (strcmp(confKey, "NO_MOUSE") == 0) { } else if (strcmp(confKey, "NO_MOUSE") == 0) {
@ -2805,6 +2802,16 @@ ConfigT *buildConfFromTable(lua_State *L) {
lua_pop(L, 1); lua_pop(L, 1);
} }
// Create new data dir location based on script location.
if (c->dataDir) free(c->dataDir);
c->dataDir = utilCreateString("%s%s", c->dataDirBase, utilGetUpToLastPathComponent(c->scriptFile));
// Try to create data directory to ensure it exists.
utilMkDirP(c->dataDir, 0777);
// Does it exist?
if (!utilPathExists(c->dataDir)) {
utilDie("Unable to create data directory: %s", c->dataDir);
}
return c; return c;
} }
@ -3653,7 +3660,7 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) {
y = (int32_t)(videoGetHeight(_global.videoHandle) * _global.overlayScaleY); y = (int32_t)(videoGetHeight(_global.videoHandle) * _global.overlayScaleY);
_global.overlay = SDL_CreateRGBSurfaceWithFormat(0, x, y, 32, SDL_PIXELFORMAT_BGRA32); _global.overlay = SDL_CreateRGBSurfaceWithFormat(0, x, y, 32, SDL_PIXELFORMAT_BGRA32);
if (_global.overlay == NULL) utilDie("%s", SDL_GetError()); if (_global.overlay == NULL) utilDie("%s", SDL_GetError());
SDL_SetColorKey(_global.overlay, SDL_FALSE, 0); SDL_SetSurfaceBlendMode(_global.overlay, SDL_BLENDMODE_BLEND);
// Mouse setup // Mouse setup
_global.mouseCount = ManyMouse_Init(); _global.mouseCount = ManyMouse_Init();
@ -3674,9 +3681,9 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) {
} }
// Grab mouse // Grab mouse
// _global.mouseGrabbed = true; _global.mouseGrabbed = true;
// SDL_SetWindowGrab(_global.window, SDL_TRUE); SDL_SetWindowGrab(_global.window, SDL_TRUE);
// SDL_ShowCursor(SDL_DISABLE); SDL_ShowCursor(SDL_DISABLE);
// Clear axis cache // Clear axis cache
for (x=0; x<AXIS_COUNT; x++) { for (x=0; x<AXIS_COUNT; x++) {

View file

@ -31,7 +31,7 @@
// Don't forget to update singe.rc! // Don't forget to update singe.rc!
#define SINGE_VERSION 2.00 #define SINGE_VERSION 2.00
#define VERSION_STRING "v2.00b12" #define VERSION_STRING "v2.00b13"
#define COPYRIGHT_END_YEAR "2020" #define COPYRIGHT_END_YEAR "2020"
@ -49,6 +49,7 @@ typedef struct ConfigS {
char *videoFile; char *videoFile;
char *scriptFile; char *scriptFile;
char *dataDir; char *dataDir;
char *dataDirBase;
bool isFrameFile; bool isFrameFile;
bool stretchVideo; bool stretchVideo;
bool noMouse; bool noMouse;

View file

@ -1,7 +1,7 @@
101 ICON "/tmp/icon.ico" 101 ICON "/tmp/icon.ico"
1 VERSIONINFO 1 VERSIONINFO
FILEVERSION 2,0,0,12 FILEVERSION 2,0,0,13
PRODUCTVERSION 2,0,0,12 PRODUCTVERSION 2,0,0,13
BEGIN BEGIN
BLOCK "StringFileInfo" BLOCK "StringFileInfo"
BEGIN BEGIN
@ -9,12 +9,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "Kangaroo Punch Studios" VALUE "CompanyName", "Kangaroo Punch Studios"
VALUE "FileDescription", "Somewhat Interactive Nostalgic Game Engine" VALUE "FileDescription", "Somewhat Interactive Nostalgic Game Engine"
VALUE "FileVersion", "2.00b12" VALUE "FileVersion", "2.00b13"
VALUE "InternalName", "Singe" VALUE "InternalName", "Singe"
VALUE "LegalCopyright", "Copyright 2006-2020 Scott C. Duensing" VALUE "LegalCopyright", "Copyright 2006-2020 Scott C. Duensing"
VALUE "OriginalFilename", "singe.exe" VALUE "OriginalFilename", "singe.exe"
VALUE "ProductName", "Singe" VALUE "ProductName", "Singe"
VALUE "ProductVersion", "2.00b12" VALUE "ProductVersion", "2.00b13"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View file

@ -161,8 +161,10 @@ char *utilGetFileExtension(char *filename) {
char *utilGetLastPathComponent(char *pathname) { char *utilGetLastPathComponent(char *pathname) {
char *start = pathname; static char *start;
int32_t x; int32_t x;
start = pathname;
// Scan through name and find the last path separator // Scan through name and find the last path separator
for (x=0; x<(int32_t)strlen(pathname); x++) { for (x=0; x<(int32_t)strlen(pathname); x++) {
@ -184,6 +186,21 @@ char utilGetPathSeparator(void) {
} }
char *utilGetUpToLastPathComponent(char *pathname) {
static char *copy;
int32_t x;
x = (int32_t)(strlen(pathname) - strlen(utilGetLastPathComponent(pathname))) - 1;
if (x < 0) x = 0;
if (copy) free(copy);
copy = strdup(pathname);
copy[x] = 0;
utilFixPathSeparators(&copy, true);
return copy;
}
bool utilMkDirP(const char *dir, const mode_t mode) { bool utilMkDirP(const char *dir, const mode_t mode) {
char tmp[UTIL_PATH_MAX]; char tmp[UTIL_PATH_MAX];
char *p = NULL; char *p = NULL;

View file

@ -44,6 +44,7 @@ void utilFixPathSeparators(char **path, bool slash);
char *utilGetFileExtension(char *filename); char *utilGetFileExtension(char *filename);
char *utilGetLastPathComponent(char *pathname); char *utilGetLastPathComponent(char *pathname);
char utilGetPathSeparator(void); char utilGetPathSeparator(void);
char *utilGetUpToLastPathComponent(char *pathname);
bool utilMkDirP(const char *dir, const mode_t mode); bool utilMkDirP(const char *dir, const mode_t mode);
bool utilPathExists(char *pathname); bool utilPathExists(char *pathname);
char *utilReadFile(char *filename, size_t *bytes); char *utilReadFile(char *filename, size_t *bytes);