Crazy memory bugs fixed. Menu improved.

This commit is contained in:
Scott Duensing 2020-05-01 20:18:56 -05:00
parent aff5341801
commit c49fe5afe4
14 changed files with 480 additions and 261 deletions

1
.gitattributes vendored
View file

@ -3,3 +3,4 @@
*.mp4 filter=lfs diff=lfs merge=lfs -text
*.ttf filter=lfs diff=lfs merge=lfs -text
*.odt filter=lfs diff=lfs merge=lfs -text
*.mpg filter=lfs diff=lfs merge=lfs -text

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
~*
*~
*.log
*.user

BIN
singe/Manual.docx Normal file

Binary file not shown.

BIN
singe/Manual.odt (Stored with Git LFS)

Binary file not shown.

View file

@ -71,38 +71,43 @@ end
function onInputPressed(what)
if what == SWITCH_UP then
if TEXT_LINE_TOP > 1 then
TEXT_LINE_TOP = TEXT_LINE_TOP - 1
end
end
-- Are we displaying the grid background?
if (discGetFrame() >= DISC_GRID_START) then
if what == SWITCH_DOWN then
if TEXT_LINE_TOP < TEXT_LINE_COUNT - TEXT_LINE_LIMIT + 1 then
TEXT_LINE_TOP = TEXT_LINE_TOP + 1
if what == SWITCH_UP then
if TEXT_LINE_TOP > 1 then
TEXT_LINE_TOP = TEXT_LINE_TOP - 1
end
end
end
if what == SWITCH_LEFT then
GAME_SELECTED = GAME_SELECTED - 1
if GAME_SELECTED < 1 then
GAME_SELECTED = GAME_COUNT
if what == SWITCH_DOWN then
if TEXT_LINE_TOP < TEXT_LINE_COUNT - TEXT_LINE_LIMIT + 1 then
TEXT_LINE_TOP = TEXT_LINE_TOP + 1
end
end
loadGameAssets(false)
end
if what == SWITCH_RIGHT then
GAME_SELECTED = GAME_SELECTED + 1
if GAME_SELECTED > GAME_COUNT then
GAME_SELECTED = 1
if what == SWITCH_LEFT then
GAME_SELECTED = GAME_SELECTED - 1
if GAME_SELECTED < 1 then
GAME_SELECTED = GAME_COUNT
end
loadGameAssets(false)
end
if what == SWITCH_RIGHT then
GAME_SELECTED = GAME_SELECTED + 1
if GAME_SELECTED > GAME_COUNT then
GAME_SELECTED = 1
end
loadGameAssets(false)
end
if what == SWITCH_START1 or what == SWITCH_START2 or what == SWITCH_BUTTON1 or what == SWITCH_BUTTON2 or what == SWITCH_BUTTON3 or what == SWITCH_BUTTON4 then
-- Start next game
SHUTDOWN_FROM_PUSH = true
scriptPush(GAME_LIST[GAME_SELECTED])
end
loadGameAssets(false)
end
if what == SWITCH_START1 or what == SWITCH_START2 or what == SWITCH_BUTTON1 or what == SWITCH_BUTTON2 or what == SWITCH_BUTTON3 or what == SWITCH_BUTTON4 then
saveConfig()
-- Start next game
scriptPush(GAME_LIST[GAME_SELECTED])
end
end
@ -117,46 +122,55 @@ function onOverlayUpdate()
overlayClear()
-- Cabinet image
x = CABINET_X + (CABINET_W - spriteGetWidth(SPRITE_CABINET)) * 0.5
y = CABINET_Y + (CABINET_H - spriteGetHeight(SPRITE_CABINET)) * 0.5
spriteDraw(x, y, SPRITE_CABINET)
-- Are we displaying the grid background?
if (discGetFrame() >= DISC_GRID_START) then
-- Marquee Image
x = MARQUEE_X + (MARQUEE_W - spriteGetWidth(SPRITE_MARQUEE)) * 0.5
y = MARQUEE_Y + (MARQUEE_H - spriteGetHeight(SPRITE_MARQUEE)) * 0.5
spriteDraw(x, y, SPRITE_MARQUEE)
-- Cabinet image
x = CABINET_X + (CABINET_W - spriteGetWidth(SPRITE_CABINET)) * 0.5
y = CABINET_Y + (CABINET_H - spriteGetHeight(SPRITE_CABINET)) * 0.5
spriteDraw(x, y, SPRITE_CABINET)
-- Attract Mode Video
videoDraw(VIDEO_ATTRACT, VIDEO_X, VIDEO_Y, VIDEO_X + VIDEO_W, VIDEO_Y + VIDEO_H)
if videoGetFrame(VIDEO_ATTRACT) > GAME_LIST[GAME_SELECTED].ATTRACT_END then
videoSeek(VIDEO_ATTRACT, GAME_LIST[GAME_SELECTED].ATTRACT_START)
-- Marquee Image
x = MARQUEE_X + (MARQUEE_W - spriteGetWidth(SPRITE_MARQUEE)) * 0.5
y = MARQUEE_Y + (MARQUEE_H - spriteGetHeight(SPRITE_MARQUEE)) * 0.5
spriteDraw(x, y, SPRITE_MARQUEE)
-- Attract Mode Video
videoDraw(VIDEO_ATTRACT, VIDEO_X, VIDEO_Y, VIDEO_X + VIDEO_W, VIDEO_Y + VIDEO_H)
if videoGetFrame(VIDEO_ATTRACT) > GAME_LIST[GAME_SELECTED].ATTRACT_END then
videoSeek(VIDEO_ATTRACT, GAME_LIST[GAME_SELECTED].ATTRACT_START)
end
-- Game Description
colorForeground(255, 255, 255, 255)
y = TEXT_Y
c = 0
t = 1
for _, handle in ipairs(TEXT_SPRITE_LIST) do
-- Find height of font and number of lines that fit
if TEXT_LINE_HEIGHT == 0 then
if (handle >= 0) then
TEXT_LINE_HEIGHT = spriteGetHeight(handle)
TEXT_LINE_LIMIT = math.floor(TEXT_H / TEXT_LINE_HEIGHT)
end
end
-- Only display what is visible in the window
if (t >= TEXT_LINE_TOP) then
if (c < TEXT_LINE_LIMIT) then
if (handle >= 0) then
spriteDraw(TEXT_X, y, handle)
end
y = y + TEXT_LINE_HEIGHT + 1
c = c + 1
end
end
t = t + 1
end
end
-- Game Description
colorForeground(255, 255, 255, 255)
y = TEXT_Y
c = 0
t = 1
for _, handle in ipairs(TEXT_SPRITE_LIST) do
-- Find height of font and number of lines that fit
if TEXT_LINE_HEIGHT == 0 then
if (handle >= 0) then
TEXT_LINE_HEIGHT = spriteGetHeight(handle)
TEXT_LINE_LIMIT = math.floor(TEXT_H / TEXT_LINE_HEIGHT)
end
end
-- Only display what is visible in the window
if (t >= TEXT_LINE_TOP) then
if (c < TEXT_LINE_LIMIT) then
if (handle >= 0) then
spriteDraw(TEXT_X, y, handle)
end
y = y + TEXT_LINE_HEIGHT + 1
c = c + 1
end
end
t = t + 1
-- Loop video?
if (discGetFrame() >= DISC_LAST_FRAME) then
discSkipToFrame(DISC_GRID_START)
end
return(OVERLAY_UPDATED)
@ -165,15 +179,16 @@ end
function onShutdown()
saveConfig()
saveConfig(not SHUTDOWN_FROM_PUSH)
end
function saveConfig()
function saveConfig(showIntro)
if GAME_COUNT > 0 then
-- Save what game we're currently viewing
local cfg = io.open(CONFIG_FILE, "w")
cfg:write("GAME_SELECTED = " .. GAME_SELECTED .. "\n")
cfg:write("SHOW_INTRO = " .. tostring(showIntro) .. "\n")
cfg:close()
end
end
@ -267,13 +282,15 @@ if GAME_COUNT == 0 then
debugPrint("No games found! Exiting.")
singeQuit()
else
discPlay()
overlaySetResolution(vldpGetWidth(), vldpGetHeight())
freeSans18 = fontLoad("Singe/FreeSansBold.ttf", 18)
fontQuality(FONT_QUALITY_BLENDED)
fontSelect(freeSans18)
DISC_GRID_START = 180
DISC_LAST_FRAME = 359
MARGIN_X = 25
MARGIN_Y = 25
@ -319,7 +336,10 @@ else
TEXT_LINE_HEIGHT = 0
TEXT_SPRITE_LIST = {}
SHUTDOWN_FROM_PUSH = false
-- Load configuration
SHOW_INTRO = true
CONFIG_FILE = singeGetDataPath() .. "menu.dat"
local confattr = lfs.attributes(CONFIG_FILE)
if confattr then
@ -331,6 +351,11 @@ else
GAME_SELECTED = 1
end
discPlay()
if (not SHOW_INTRO) then
discSkipToFrame(DISC_GRID_START)
end
-- Prime the pump
loadGameAssets(true)
end

View file

@ -622,17 +622,19 @@ createEmbeddedBinary FreeSansBold.ttf FreeSansBold_ttf.h FREESANSBOLD_TTF_H
# === Singe Menu Background Video ===
if [[ ! -f menuBackground_mkv.h ]]; then
ffmpeg -i 180503_01_PurpleGrid.mp4 -filter:v 'crop=ih/3*4:ih' -vf scale=720:480 -c:v libx264 -c:a copy menuBackground.mkv
ffmpeg -i "Singe Engine Intro.mpg" -filter:v 'crop=ih/3*4:ih' -vf scale=720:480 -c:v libx264 -c:a aac temp1.mkv
ffmpeg -i 180503_01_PurpleGrid.mp4 -filter:v 'crop=ih/3*4:ih' -vf scale=720:480 -c:v libx264 -c:a aac temp2.mkv
ffmpeg -f concat -safe 0 -i <(echo -e "file $PWD/temp1.mkv\nfile $PWD/temp2.mkv\n") -c copy menuBackground.mkv
createEmbeddedBinary menuBackground.mkv menuBackground_mkv.h MENUBACKGROUND_MKV_H
rm menuBackground.mkv
rm temp1.mkv temp2.mkv # menuBackground.mkv
fi
popd
# === Singe Manual ===
libreoffice --headless "-env:UserInstallation=file:///tmp/LibreOffice_Conversion_${USER}" --convert-to pdf:writer_pdf_Export Manual.odt
#libreoffice --headless "-env:UserInstallation=file:///tmp/LibreOffice_Conversion_${USER}" --convert-to pdf:writer_pdf_Export Manual.odt
createEmbeddedBinary Manual.pdf Manual_pdf.h MANUAL_H
rm Manual.pdf
#rm Manual.pdf
# Clean Uo
case "${G_PLATFORM}" in

View file

@ -192,6 +192,8 @@ int32_t frameFileLoad(char *filename, char *indexPath, bool stretchVideo, SDL_Re
free(frameLine);
}
free(data);
// Allocate new framefile
frameFile = malloc(sizeof(FrameFileT));
frameFile->id = _nextId;

View file

@ -62,7 +62,7 @@ typedef struct ModeS {
} ModeT;
typedef struct QueueS {
ConfigT conf;
ConfigT *conf;
struct QueueS *next;
} QueueT;
@ -100,12 +100,48 @@ static ModeT _modes[] = {
ConfigT *createConf(char *exeName, int argc, char *argv[]);
void destroyConf(ConfigT **confPointer);
bool extractFile(char *filename, unsigned char *data, int32_t length);
void launcher(char *exeName, ConfigT *conf);
void showUsage(char *name, char *message);
ConfigT *cloneConf(ConfigT *conf) {
int32_t x;
ConfigT *c;
c = (ConfigT *)calloc(1, sizeof(ConfigT));
// Deep copy conf manually to avoid optimizer issues
if (conf->scriptFile) c->scriptFile = strdup(conf->scriptFile);
if (conf->videoFile) c->videoFile = strdup(conf->videoFile);
if (conf->dataDirBase) c->dataDirBase = strdup(conf->dataDirBase);
if (conf->dataDir) c->dataDir = strdup(conf->dataDir);
c->resolutionWasCalculated = conf->resolutionWasCalculated;
c->isFrameFile = conf->isFrameFile;
c->stretchVideo = conf->stretchVideo;
c->noMouse = conf->noMouse;
c->noSound = conf->noSound;
c->fullScreen = conf->fullScreen;
c->fullScreenWindow = conf->fullScreenWindow;
c->showCalculated = conf->showCalculated;
c->noConsole = conf->noConsole;
c->noLogos = conf->noLogos;
c->tracing = conf->tracing;
c->bestRatioIndex = conf->bestRatioIndex;
c->volumeVldp = conf->volumeVldp;
c->volumeNonVldp = conf->volumeNonVldp;
c->scaleFactor = conf->scaleFactor;
c->xResolution = conf->xResolution;
c->yResolution = conf->yResolution;
c->sindenArgc = conf->sindenArgc;
for (x=0; x<SINDEN_OPTION_COUNT; x++) {
c->sindenArgv[x] = conf->sindenArgv[x];
}
return c;
}
ConfigT *createConf(char *exeName, int argc, char *argv[]) {
int32_t x = 0;
int32_t argCount = 0;
@ -153,10 +189,11 @@ ConfigT *createConf(char *exeName, int argc, char *argv[]) {
// Default configuration values
conf = (ConfigT *)calloc(1, sizeof(ConfigT));
if (!conf) utilDie("Out of memory creating config.");
conf->bestRatioIndex = -1;
conf->volumeVldp = 100;
conf->volumeNonVldp = 100;
conf->scaleFactor = 100;
conf->bestRatioIndex = -1;
conf->volumeVldp = 100;
conf->volumeNonVldp = 100;
conf->scaleFactor = 100;
conf->resolutionWasCalculated = true;
// Parse command line
argCount = ap_arguments(&parser);
@ -173,6 +210,7 @@ ConfigT *createConf(char *exeName, int argc, char *argv[]) {
case 'a':
if (aspectString) free(aspectString);
aspectString = strdup(arg);
conf->resolutionWasCalculated = false;
argCount++;
break;
@ -263,12 +301,14 @@ ConfigT *createConf(char *exeName, int argc, char *argv[]) {
// X Resolution
case 'x':
conf->xResolution = atoi(arg);
conf->resolutionWasCalculated = false;
argCount++;
break;
// Y Resolution
case 'y':
conf->yResolution = atoi(arg);
conf->resolutionWasCalculated = false;
argCount++;
break;
@ -424,11 +464,13 @@ ConfigT *createConf(char *exeName, int argc, char *argv[]) {
void destroyConf(ConfigT **confPointer) {
ConfigT *conf = *confPointer;
if (conf->dataDir) free(conf->dataDir);
if (conf->videoFile) free(conf->videoFile);
if (conf->scriptFile) free(conf->scriptFile);
if (conf->dataDir) free(conf->dataDir);
if (conf->dataDirBase) free(conf->dataDirBase);
if (conf->videoFile) free(conf->videoFile);
if (conf->scriptFile) free(conf->scriptFile);
free(conf);
conf = NULL;
}
@ -553,8 +595,8 @@ void launcher(char *exeName, ConfigT *conf) {
// Init SDL_ttf
if (TTF_Init() < 0) utilDie("%s", TTF_GetError());
// Create Resizable Window
window = SDL_CreateWindow("SINGE", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, conf->xResolution, conf->yResolution, SDL_WINDOW_RESIZABLE);
// Create Window
window = SDL_CreateWindow("SINGE", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, conf->xResolution, conf->yResolution, 0 /* SDL_WINDOW_RESIZABLE */);
if (window == NULL) utilDie("%s", SDL_GetError());
// Window Icon
@ -640,7 +682,7 @@ void queueScript(ConfigT *conf) {
QueueT *q;
q = (QueueT *)calloc(1, sizeof(QueueT));
memcpy(&q->conf, conf, sizeof(ConfigT));
q->conf = cloneConf(conf);
LL_APPEND(_scriptQueue, q);
}
@ -752,14 +794,15 @@ int main(int argc, char *argv[]) {
// Queue initial script
conf = createConf(exeName, argc, argv);
queueScript(conf);
destroyConf(&conf);
// Run script queue
while (_scriptQueue) {
q = _scriptQueue;
conf = (ConfigT *)&q->conf;
launcher(exeName, q->conf);
destroyConf(&q->conf);
LL_DELETE(_scriptQueue, q);
launcher(exeName, conf);
destroyConf(&conf);
free(q);
}
#ifdef _WIN32

View file

@ -29,8 +29,10 @@
#include "singe.h"
bool parseSindenString(char **sindenStringPointer, ConfigT *conf);
void queueScript(ConfigT *conf);
ConfigT *cloneConf(ConfigT *conf);
void destroyConf(ConfigT **confPointer);
bool parseSindenString(char **sindenStringPointer, ConfigT *conf);
void queueScript(ConfigT *conf);
#endif // MAIN_H

View file

@ -0,0 +1,3 @@
builder.OpenFile("Manual.docx");
builder.SaveFile("pdf", "/tmp/Manual.pdf");
builder.CloseFile();

View file

@ -221,7 +221,7 @@ typedef struct GlobalS {
FontT *fontList;
FontT *fontCurrent;
MappingT controlMappings[INPUT_COUNT];
ConfigT conf; // Local copy of command line options
ConfigT *conf; // Local copy of command line options
} GlobalT;
@ -272,8 +272,10 @@ int32_t apiMouseDisable(lua_State *L);
int32_t apiMouseEnable(lua_State *L);
int32_t apiMouseGetPosition(lua_State *L);
int32_t apiMouseHowMany(lua_State *L);
int32_t apiMouseSetCaptured(lua_State *L);
int32_t apiMouseSetMode(lua_State *L);
int32_t apiOverlayBox(lua_State *L);
int32_t apiOverlayCircle(lua_State *L);
int32_t apiOverlayClear(lua_State *L);
int32_t apiOverlayEllipse(lua_State *L);
@ -338,12 +340,13 @@ void doIndexDisplay(int32_t percent);
void doLogos(void);
void callLua(const char *func, const char *sig, ...);
void channelFinished(int channel);
void line(int32_t x1, int32_t y1, int32_t x2, int32_t y2, SDL_Color *c);
void luaDie(lua_State *L, char *method, char *fmt, ...);
int32_t luaError(lua_State *L);
void luaPreload(lua_State *L, const char *name, lua_CFunction func);
void luaTrace(lua_State *L, char *method, char *fmt, ...);
void processKey(bool down, int keysym, int32_t scancode);
void putPixel(int32_t x, int32_t y);
void putPixel(int32_t x, int32_t y, SDL_Color *c);
void startControllers(void);
void startLuaContext(lua_State *L);
void stopControllers(void);
@ -367,7 +370,7 @@ int32_t apiColorBackground(lua_State *L) {
d = lua_tonumber(L, 2); _global.colorBackground.g = (byte)d;
d = lua_tonumber(L, 3); _global.colorBackground.b = (byte)d;
if (n == 3) {
_global.colorBackground.a = (byte)255;
_global.colorBackground.a = (byte)0; // Default to transparent.
} else {
if (lua_isnumber(L, 4)) {
d = lua_tonumber(L, 4); _global.colorBackground.a = (byte)d;
@ -404,7 +407,7 @@ int32_t apiColorForeground(lua_State *L) {
d = lua_tonumber(L, 2); _global.colorForeground.g = (byte)d;
d = lua_tonumber(L, 3); _global.colorForeground.b = (byte)d;
if (n == 3) {
_global.colorForeground.a = (byte)255;
_global.colorForeground.a = (byte)255; // Default to opaque.
} else {
if (lua_isnumber(L, 4)) {
d = lua_tonumber(L, 4); _global.colorForeground.a = (byte)d;
@ -517,8 +520,8 @@ int32_t apiDiscAudio(lua_State *L) {
d = lua_tonumber(L, 1); channel = (int32_t)d;
d = lua_toboolean(L, 2); onOff = (bool)d;
videoGetVolume(_global.videoHandle, &left, &right);
if (channel == 1) left = (onOff ? _global.conf.volumeVldp : 0);
if (channel == 2) right = (onOff ? _global.conf.volumeVldp : 0);
if (channel == 1) left = (onOff ? _global.conf->volumeVldp : 0);
if (channel == 2) right = (onOff ? _global.conf->volumeVldp : 0);
videoSetVolume(_global.videoHandle, left, right);
result = true;
}
@ -548,7 +551,7 @@ int32_t apiDiscGetFrame(lua_State *L) {
int64_t frame = 0;
if (!_global.discStopped) {
if (_global.conf.isFrameFile) {
if (_global.conf->isFrameFile) {
frame = frameFileGetFrame(_global.frameFileHandle, _global.videoHandle);
} else {
if (_global.videoHandle >= 0) frame = videoGetFrame(_global.videoHandle);
@ -601,7 +604,7 @@ int32_t apiDiscSearch(lua_State *L) {
if (n == 1) {
if (lua_isnumber(L, 1)) {
d = lua_tonumber(L, 1); frame = (int64_t)d;
if (_global.conf.isFrameFile) {
if (_global.conf->isFrameFile) {
frameFileSeek(_global.frameFileHandle, frame, &_global.videoHandle, &aFrame);
} else {
if (_global.videoHandle >= 0) videoSeek(_global.videoHandle, frame);
@ -652,7 +655,7 @@ int32_t apiDiscSkipBackward(lua_State *L) {
if (lua_isnumber(L, 1)) {
d = lua_tonumber(L, 1);
if (_global.videoHandle >= 0) frame = videoGetFrame(_global.videoHandle) - (int64_t)d;
if (_global.conf.isFrameFile) {
if (_global.conf->isFrameFile) {
frameFileSeek(_global.frameFileHandle, frame, &_global.videoHandle, &aFrame);
} else {
if (_global.videoHandle >= 0) videoSeek(_global.videoHandle, frame);
@ -696,7 +699,7 @@ int32_t apiDiscSkipForward(lua_State *L) {
if (n == 1) {
if (lua_isnumber(L, 1)) {
d = lua_tonumber(L, 1); if (_global.videoHandle >= 0) frame = videoGetFrame(_global.videoHandle) + (int64_t)d;
if (_global.conf.isFrameFile) {
if (_global.conf->isFrameFile) {
frameFileSeek(_global.frameFileHandle, frame, &_global.videoHandle, &aFrame);
} else {
if (_global.videoHandle >= 0) videoSeek(_global.videoHandle, frame);
@ -731,7 +734,7 @@ int32_t apiDiscSkipToFrame(lua_State *L) {
if (n == 1) {
if (lua_isnumber(L, 1)) {
d = lua_tonumber(L, 1); frame = (int64_t)d;
if (_global.conf.isFrameFile) {
if (_global.conf->isFrameFile) {
frameFileSeek(_global.frameFileHandle, frame, &_global.videoHandle, &aFrame);
} else {
if (_global.videoHandle >= 0) videoSeek(_global.videoHandle, frame);
@ -761,7 +764,7 @@ int32_t apiDiscStepBackward(lua_State *L) {
// No matter disc state, go back a frame. If playing, pause.
if (_global.videoHandle >= 0) {
if (_global.conf.isFrameFile) {
if (_global.conf->isFrameFile) {
frame = frameFileGetFrame(_global.frameFileHandle, _global.videoHandle) - 1;
frameFileSeek(_global.frameFileHandle, frame, &_global.videoHandle, &aFrame);
} else {
@ -785,7 +788,7 @@ int32_t apiDiscStepForward(lua_State *L) {
// No matter disc state, go forward a frame. If playing, pause.
if (_global.videoHandle >= 0) {
if (_global.conf.isFrameFile) {
if (_global.conf->isFrameFile) {
frame = frameFileGetFrame(_global.frameFileHandle, _global.videoHandle) + 1;
frameFileSeek(_global.frameFileHandle, frame, &_global.videoHandle, &aFrame);
} else {
@ -1044,6 +1047,59 @@ int32_t apiFontToSprite(lua_State *L) {
}
int32_t apiOverlayBox(lua_State *L) {
int32_t n = lua_gettop(L);
int32_t x1 = 0;
int32_t y1 = 0;
int32_t x2 = 0;
int32_t y2 = 0;
//SDL_Rect r;
double d = 0;
bool result = false;
if (n == 4) {
if (lua_isnumber(L, 1)) {
if (lua_isnumber(L, 2)) {
if (lua_isnumber(L, 3)) {
if (lua_isnumber(L, 4)) {
d = lua_tonumber(L, 1); x1 = (int32_t)d;
d = lua_tonumber(L, 2); y1 = (int32_t)d;
d = lua_tonumber(L, 3); x2 = (int32_t)d;
d = lua_tonumber(L, 4); y2 = (int32_t)d;
/*
r.x = x1;
r.y = y1;
r.w = abs(x2 - x1) + 1;
r.h = abs(y2 - y1) + 1;
*/
SDL_LockSurface(_global.overlay);
//***TODO*** No filling until I can find an efficient way to blend individual pixels.
//SDL_FillRect(_global.overlay, &r, SDL_MapRGBA(_global.overlay->format, _global.colorBackground.r, _global.colorBackground.g, _global.colorBackground.b, _global.colorBackground.a));
line(x1, y1, x2, y1, &_global.colorForeground);
line(x2, y1, x2, y2, &_global.colorForeground);
line(x2, y2, x1, y2, &_global.colorForeground);
line(x1, y2, x1, y1, &_global.colorForeground);
SDL_UnlockSurface(_global.overlay);
result = true;
}
}
}
}
}
if (result) {
luaTrace(L, "overlayBox", "%d %d %d %d", x1, y1, x2, y2);
} else {
luaDie(L, "overlayBox", "Failed!");
}
return 0;
}
int32_t apiOverlayCircle(lua_State *L) {
int32_t n = lua_gettop(L);
@ -1075,14 +1131,14 @@ int32_t apiOverlayCircle(lua_State *L) {
SDL_LockSurface(_global.overlay);
while (x >= y) {
putPixel(x0 + x, y0 + y);
putPixel(x0 + y, y0 + x);
putPixel(x0 - y, y0 + x);
putPixel(x0 - x, y0 + y);
putPixel(x0 - x, y0 - y);
putPixel(x0 - y, y0 - x);
putPixel(x0 + y, y0 - x);
putPixel(x0 + x, y0 - y);
putPixel(x0 + x, y0 + y, &_global.colorForeground);
putPixel(x0 + y, y0 + x, &_global.colorForeground);
putPixel(x0 - y, y0 + x, &_global.colorForeground);
putPixel(x0 - x, y0 + y, &_global.colorForeground);
putPixel(x0 - x, y0 - y, &_global.colorForeground);
putPixel(x0 - y, y0 - x, &_global.colorForeground);
putPixel(x0 + y, y0 - x, &_global.colorForeground);
putPixel(x0 + x, y0 - y, &_global.colorForeground);
if (err <= 0) {
y++;
@ -1178,10 +1234,10 @@ int32_t apiOverlayEllipse(lua_State *L) {
b1 = 8 * b * b;
do {
putPixel(x1, y0); // I. Quadrant
putPixel(x0, y0); // II. Quadrant
putPixel(x0, y1); // III. Quadrant
putPixel(x1, y1); // IV. Quadrant
putPixel(x1, y0, &_global.colorForeground); // I. Quadrant
putPixel(x0, y0, &_global.colorForeground); // II. Quadrant
putPixel(x0, y1, &_global.colorForeground); // III. Quadrant
putPixel(x1, y1, &_global.colorForeground); // IV. Quadrant
e2 = 2 * err;
if (e2 <= dy) { // y step
y0++;
@ -1196,10 +1252,10 @@ int32_t apiOverlayEllipse(lua_State *L) {
} while (x0 <= x1);
while (y0-y1 < b) { // too early stop of flat ellipses a = 1
putPixel(x0-1, y0); // -> finish tip of ellipse
putPixel(x1+1, y0++);
putPixel(x0-1, y1);
putPixel(x1+1, y1--);
putPixel(x0-1, y0, &_global.colorForeground); // -> finish tip of ellipse
putPixel(x1+1, y0++, &_global.colorForeground);
putPixel(x0-1, y1, &_global.colorForeground);
putPixel(x1+1, y1--, &_global.colorForeground);
}
SDL_UnlockSurface(_global.overlay);
@ -1241,13 +1297,6 @@ int32_t apiOverlayLine(lua_State *L) {
int32_t y1 = 0;
int32_t x2 = 0;
int32_t y2 = 0;
int32_t x = 0;
int32_t y = 0;
int32_t dx = 0;
int32_t dy = 0;
int32_t incX = 0;
int32_t incY = 0;
int32_t balance = 0;
double d = 0;
bool result = false;
@ -1262,56 +1311,7 @@ int32_t apiOverlayLine(lua_State *L) {
d = lua_tonumber(L, 4); y2 = (int32_t)d;
SDL_LockSurface(_global.overlay);
if (x2 >= x1) {
dx = x2 - x1;
incX = 1;
} else {
dx = x1 - x2;
incX = -1;
}
if (y2 >= y1) {
dy = y2 - y1;
incY = 1;
} else {
dy = y1 - y2;
incY = -1;
}
x = x1;
y = y1;
if (dx >= dy) {
dy <<= 1;
balance = dy - dx;
dx <<= 1;
while (x != x2) {
putPixel(x, y);
if (balance >= 0) {
y += incY;
balance -= dx;
}
balance += dy;
x += incX;
}
putPixel(x, y);
} else {
dx <<= 1;
balance = dx - dy;
dy <<= 1;
while (y != y2) {
putPixel(x, y);
if (balance >= 0) {
x += incX;
balance -= dy;
}
balance += dx;
y += incY;
}
putPixel(x, y);
}
line(x1, y1, x2, y2, &_global.colorForeground);
SDL_UnlockSurface(_global.overlay);
result = true;
}
@ -1345,7 +1345,7 @@ int32_t apiOverlayPlot(lua_State *L) {
d = lua_tonumber(L, 2); y1 = (int32_t)d;
SDL_LockSurface(_global.overlay);
putPixel(x1, y1);
putPixel(x1, y1, &_global.colorForeground);
SDL_UnlockSurface(_global.overlay);
result = true;
}
@ -1764,24 +1764,42 @@ int32_t apiSoundUnload(lua_State *L) {
int32_t apiSpriteDraw(lua_State *L) {
int32_t n = lua_gettop(L);
int32_t id = -1;
double d = 0;
SpriteT *sprite = NULL;
SDL_Rect dest;
int32_t n = lua_gettop(L);
int32_t id = -1;
double d = 0;
SpriteT *sprite = NULL;
SDL_Rect dest;
if (n == 3) {
if ((n == 3) || (n == 5)) {
if (lua_isnumber(L, 1)) {
if (lua_isnumber(L, 2)) {
if (lua_isnumber(L, 3)) {
d = lua_tonumber(L, 1); dest.x = (int32_t)d;
d = lua_tonumber(L, 2); dest.y = (int32_t)d;
d = lua_tonumber(L, 3); id = (int32_t)d;
if (n == 5) {
// Target is scaled
if (lua_isnumber(L, 4)) {
if (lua_isnumber(L, 5)) {
d = lua_tonumber(L, 3); dest.w = (int32_t)d - dest.x + 1;
d = lua_tonumber(L, 4); dest.h = (int32_t)d - dest.y + 1;
d = lua_tonumber(L, 5); id = (int32_t)d;
}
}
} else {
// Target is same size as sprite
d = lua_tonumber(L, 3); id = (int32_t)d;
}
HASH_FIND_INT(_global.spriteList, &id, sprite);
if (!sprite) luaDie(L, "spriteDraw", "No sprite at index %d in apiSpriteGetWidth.", id);
dest.w = sprite->surface->w;
dest.h = sprite->surface->h;
SDL_BlitSurface(sprite->surface, NULL, _global.overlay, &dest);
if (n == 5) {
// Target is scaled
SDL_BlitScaled(sprite->surface, NULL, _global.overlay, &dest);
} else {
// Target is same size as sprite
dest.w = sprite->surface->w;
dest.h = sprite->surface->h;
SDL_BlitSurface(sprite->surface, NULL, _global.overlay, &dest);
}
}
}
}
@ -1934,8 +1952,8 @@ int32_t apiVideoDraw(lua_State *L) {
d = lua_tonumber(L, 1); id = (int32_t)d;
d = lua_tonumber(L, 2); dest.x = (int32_t)d;
d = lua_tonumber(L, 3); dest.y = (int32_t)d;
d = lua_tonumber(L, 4); dest.w = (int32_t)d - dest.x;
d = lua_tonumber(L, 5); dest.h = (int32_t)d - dest.y;
d = lua_tonumber(L, 4); dest.w = (int32_t)d - dest.x + 1;
d = lua_tonumber(L, 5); dest.h = (int32_t)d - dest.y + 1;
// Get our video structure
HASH_FIND_INT(_global.videoList, &id, video);
if (!video) luaDie(L, "videoDraw", "No video at index %d in apiVideoDraw.", id);
@ -2166,7 +2184,7 @@ int32_t apiVideoLoad(lua_State *L) {
name = lua_tostring(L, 1);
// Create data directory based on video path.
temp = utilGetUpToLastPathComponent((char *)name);
data = utilCreateString("%s%s", _global.conf.dataDirBase, temp);
data = utilCreateString("%s%s", _global.conf->dataDirBase, temp);
free(temp);
temp = NULL;
utilFixPathSeparators(&data, false);
@ -2470,8 +2488,8 @@ int32_t apiKeyboardSetMode(lua_State *L) {
int32_t apiMouseEnable(lua_State *L) {
// Enables mouse monitoring
(void)L;
luaTrace(L, "mouseEnable", "%d", _global.conf.noMouse);
_global.mouseEnabled = (bool)!_global.conf.noMouse;
luaTrace(L, "mouseEnable", "%d", _global.conf->noMouse);
_global.mouseEnabled = (bool)!_global.conf->noMouse;
return 0;
}
@ -2485,6 +2503,36 @@ int32_t apiMouseDisable(lua_State *L) {
}
int32_t apiMouseSetCaptured(lua_State *L) {
int32_t n = lua_gettop(L);
bool result = false;
if (n == 1) {
if (lua_isboolean(L, 1)) {
_global.mouseGrabbed = (bool)lua_toboolean(L, 1);
if (_global.mouseGrabbed) {
// Grab mouse
SDL_SetWindowGrab(_global.window, SDL_TRUE);
SDL_ShowCursor(SDL_DISABLE);
} else {
// Ungrab mouse
SDL_SetWindowGrab(_global.window, SDL_FALSE);
SDL_ShowCursor(SDL_ENABLE);
}
result = true;
}
}
if (result) {
luaTrace(L, "mouseSetCaptured", "%d", _global.mouseGrabbed);
} else {
luaDie(L, "mouseSetCaptured", "Failed!");
}
return 0;
}
int32_t apiMouseSetMode(lua_State *L) {
// Sets the scanning mode for mouse input.
// Can be one of two values:
@ -2599,7 +2647,7 @@ int32_t apiScriptExecute(lua_State *L) {
// Push next script.
conf = buildConfFromTable(L);
queueScript(conf);
free(conf);
destroyConf(&conf);
// Stop this script running.
_global.running = false;
result = true;
@ -2626,9 +2674,9 @@ int32_t apiScriptPush(lua_State *L) {
// Push next script.
conf = buildConfFromTable(L);
queueScript(conf);
free(conf);
destroyConf(&conf);
// Push this script.
queueScript(&_global.conf);
queueScript(_global.conf);
// Stop this script running.
_global.running = false;
result = true;
@ -2718,8 +2766,8 @@ int32_t apiSingeVersion(lua_State *L) {
int32_t apiSingeGetDataPath(lua_State *L) {
luaTrace(L, "singeGetDataPath", "%s", _global.conf.dataDir);
lua_pushstring(L, _global.conf.dataDir);
luaTrace(L, "singeGetDataPath", "%s", _global.conf->dataDir);
lua_pushstring(L, _global.conf->dataDir);
return 1;
}
@ -2758,8 +2806,8 @@ int32_t apiSingeSetGameName(lua_State *L) {
int32_t apiSingeGetScriptPath(lua_State *L) {
luaTrace(L, "singeGetScriptPath", "%s", _global.conf.scriptFile);
lua_pushstring(L, _global.conf.scriptFile);
luaTrace(L, "singeGetScriptPath", "%s", _global.conf->scriptFile);
lua_pushstring(L, _global.conf->scriptFile);
return 1;
}
@ -2773,12 +2821,7 @@ ConfigT *buildConfFromTable(lua_State *L) {
ConfigT *c = NULL;
// Start with current config.
c = (ConfigT *)calloc(1, sizeof(ConfigT));
memcpy(c, &_global.conf, sizeof(ConfigT));
if (_global.conf.scriptFile) c->scriptFile = strdup(_global.conf.scriptFile);
if (_global.conf.videoFile) c->videoFile = strdup(_global.conf.videoFile);
if (_global.conf.dataDirBase) c->dataDirBase = strdup(_global.conf.dataDirBase);
if (_global.conf.dataDir) c->dataDir = strdup(_global.conf.dataDir);
c = cloneConf(_global.conf);
// Update with data in the table on the top of the Lua stack.
lua_pushnil(L);
@ -3140,6 +3183,66 @@ void doLogos(void) {
}
void line(int32_t x1, int32_t y1, int32_t x2, int32_t y2, SDL_Color *c) {
int32_t x = 0;
int32_t y = 0;
int32_t dx = 0;
int32_t dy = 0;
int32_t incX = 0;
int32_t incY = 0;
int32_t balance = 0;
if (x2 >= x1) {
dx = x2 - x1;
incX = 1;
} else {
dx = x1 - x2;
incX = -1;
}
if (y2 >= y1) {
dy = y2 - y1;
incY = 1;
} else {
dy = y1 - y2;
incY = -1;
}
x = x1;
y = y1;
if (dx >= dy) {
dy <<= 1;
balance = dy - dx;
dx <<= 1;
while (x != x2) {
putPixel(x, y, c);
if (balance >= 0) {
y += incY;
balance -= dx;
}
balance += dy;
x += incX;
}
putPixel(x, y, c);
} else {
dx <<= 1;
balance = dx - dy;
dy <<= 1;
while (y != y2) {
putPixel(x, y, c);
if (balance >= 0) {
x += incX;
balance -= dy;
}
balance += dx;
y += incY;
}
putPixel(x, y, c);
}
}
void luaDie(lua_State *L, char *method, char *fmt, ...) {
va_list args;
lua_Debug ar;
@ -3297,12 +3400,12 @@ void processKey(bool down, int32_t keysym, int32_t scancode) {
}
void putPixel(int32_t x, int32_t y) {
void putPixel(int32_t x, int32_t y, SDL_Color *c) {
SDL_Surface *surface = _global.overlay;
int32_t bpp = surface->format->BytesPerPixel;
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
Uint32 pixel = SDL_MapRGBA(surface->format, _global.colorForeground.r, _global.colorForeground.g, _global.colorForeground.b, _global.colorForeground.a);
Uint32 pixel = SDL_MapRGBA(surface->format, c->r, c->g, c->b, c->a);
if ((x < 0) || (x >= _global.overlay->w) || (y < 0) || (y >= _global.overlay->h)) return;
@ -3343,6 +3446,7 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) {
int64_t thisFrame = -1;
int64_t lastFrame = -1;
uint32_t frameClock = 0;
bool changed = false;
char *temp = NULL;
char *temp2 = NULL;
SDL_Rect windowTarget;
@ -3382,12 +3486,8 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) {
_global.discStopped = true;
_global.mouseEnabled = true;
// Deep copy conf
memcpy(&_global.conf, conf, sizeof(ConfigT));
_global.conf.dataDir = strdup(conf->dataDir);
_global.conf.dataDirBase = strdup(conf->dataDirBase);
_global.conf.scriptFile = strdup(conf->scriptFile);
_global.conf.videoFile = strdup(conf->videoFile);
// Local copy of config
_global.conf = cloneConf(conf);
// Input mappings
_global.controlMappings[INPUT_UP].name = "INPUT_UP";
@ -3431,20 +3531,21 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) {
if (luaL_loadbuffer(_global.luaContext, (char *)controls_cfg, controls_cfg_len, "Input Mappings") || lua_pcall(_global.luaContext, 0, 0, 0)) utilDie("%s", lua_tostring(_global.luaContext, -1));
if (utilFileExists("controls.cfg") && luaL_dofile(_global.luaContext, "controls.cfg")) utilDie("%s", lua_tostring(_global.luaContext, -1));
// Load mappings in main data dir
temp = utilCreateString("%s..%ccontrols.cfg", _global.conf.dataDir, utilGetPathSeparator());
temp = utilCreateString("%s..%ccontrols.cfg", _global.conf->dataDir, utilGetPathSeparator());
if (utilFileExists(temp) && luaL_dofile(_global.luaContext, temp)) utilDie("%s", lua_tostring(_global.luaContext, -1));
free(temp);
// Load mappings in game data dir
temp = utilCreateString("%scontrols.cfg", _global.conf.dataDir);
temp = utilCreateString("%scontrols.cfg", _global.conf->dataDir);
if (utilFileExists(temp) && luaL_dofile(_global.luaContext, temp)) utilDie("%s", lua_tostring(_global.luaContext, -1));
free(temp);
// Load mappings in game script dir
temp = strdup(_global.conf.scriptFile);
temp = strdup(_global.conf->scriptFile);
temp2 = utilStrndup(temp, strlen(temp) - strlen(utilGetLastPathComponent(temp)));
free(temp);
temp = utilCreateString("%scontrols.cfg", temp2);
if (utilFileExists(temp) && luaL_dofile(_global.luaContext, temp)) utilDie("%s", lua_tostring(_global.luaContext, -1));
free(temp);
free(temp2);
// Parse results
lua_getglobal(_global.luaContext, "DEAD_ZONE");
if (lua_isnumber(_global.luaContext, -1)) {
@ -3496,7 +3597,7 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) {
lua_close(_global.luaContext);
// Show splash screens
if (!_global.conf.noLogos) {
if (!_global.conf->noLogos) {
doLogos();
}
@ -3548,8 +3649,10 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) {
lua_register(_global.luaContext, "mouseDisable", apiMouseDisable);
lua_register(_global.luaContext, "mouseGetPosition", apiMouseGetPosition);
lua_register(_global.luaContext, "mouseHowMany", apiMouseHowMany);
lua_register(_global.luaContext, "mouseSetCaptured", apiMouseSetCaptured);
lua_register(_global.luaContext, "mouseSetMode", apiMouseSetMode);
lua_register(_global.luaContext, "overlayBox", apiOverlayBox);
lua_register(_global.luaContext, "overlayCircle", apiOverlayCircle);
lua_register(_global.luaContext, "overlayClear", apiOverlayClear);
lua_register(_global.luaContext, "overlayEllipse", apiOverlayEllipse);
@ -3615,39 +3718,61 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) {
// Open main video file
doIndexDisplay(-1);
videoSetIndexCallback(doIndexDisplay);
if (_global.conf.isFrameFile) {
_global.frameFileHandle = frameFileLoad(_global.conf.videoFile, _global.conf.dataDir, (bool)_global.conf.stretchVideo, _global.renderer, _global.conf.showCalculated);
if (_global.frameFileHandle < 0) utilDie("Unable to load framefile: %s", _global.conf.videoFile);
if (_global.conf->isFrameFile) {
_global.frameFileHandle = frameFileLoad(_global.conf->videoFile, _global.conf->dataDir, (bool)_global.conf->stretchVideo, _global.renderer, _global.conf->showCalculated);
if (_global.frameFileHandle < 0) utilDie("Unable to load framefile: %s", _global.conf->videoFile);
frameFileSeek(_global.frameFileHandle, 0, &_global.videoHandle, &thisFrame); // Fills in _global.videoHandle
} else {
_global.videoHandle = videoLoad(_global.conf.videoFile, _global.conf.dataDir, (bool)_global.conf.stretchVideo, _global.renderer);
_global.videoHandle = videoLoad(_global.conf->videoFile, _global.conf->dataDir, (bool)_global.conf->stretchVideo, _global.renderer);
}
if (_global.videoHandle < 0) utilDie("Unable to load video file: %s", _global.conf.videoFile);
videoSetVolume(_global.videoHandle, _global.conf.volumeVldp, _global.conf.volumeVldp);
if (_global.videoHandle < 0) utilDie("Unable to load video file: %s", _global.conf->videoFile);
videoSetVolume(_global.videoHandle, _global.conf->volumeVldp, _global.conf->volumeVldp);
videoSetIndexCallback(NULL);
doIndexDisplay(-2);
// Should we resize the window?
//***TODO***
if (conf->resolutionWasCalculated) {
// Is the video wider than the display window?
if ((videoGetWidth(_global.videoHandle) / videoGetHeight(_global.videoHandle)) > (conf->xResolution / conf->yResolution)) {
// Find new window height
conf->yResolution = ((float)conf->xResolution / (float)videoGetWidth(_global.videoHandle) * (float)videoGetHeight(_global.videoHandle));
changed = true;
} else {
// Find new window width
conf->xResolution = ((float)conf->yResolution / (float)videoGetHeight(_global.videoHandle) * (float)videoGetWidth(_global.videoHandle));
changed = true;
}
if (changed) {
SDL_SetWindowSize(_global.window, conf->xResolution, conf->yResolution);
SDL_DestroyRenderer(_global.renderer);
// Recreate an accelerated renderer.
_global.renderer = SDL_CreateRenderer(_global.window, -1, SDL_RENDERER_ACCELERATED);
if (_global.renderer == NULL) utilDie("%s", SDL_GetError());
// Clear screen with black
SDL_SetRenderDrawColor(_global.renderer, 0, 0, 0, 255);
SDL_RenderClear(_global.renderer);
changed = false;
}
}
// Default render location is the entire window
windowTarget.x = 0;
windowTarget.y = 0;
windowTarget.w = videoGetWidth(_global.videoHandle);
windowTarget.h = videoGetHeight(_global.videoHandle);
windowTarget.x = 0;
windowTarget.y = 0;
windowTarget.w = videoGetWidth(_global.videoHandle);
windowTarget.h = videoGetHeight(_global.videoHandle);
sindenWhite.x = -1;
sindenBlack.x = -1;
// Overscan compensation
if (_global.conf.scaleFactor < 100) {
windowTarget.w = videoGetWidth(_global.videoHandle) * _global.conf.scaleFactor / 100;
windowTarget.h = videoGetHeight(_global.videoHandle) * _global.conf.scaleFactor / 100;
if (_global.conf->scaleFactor < 100) {
windowTarget.w = videoGetWidth(_global.videoHandle) * _global.conf->scaleFactor / 100;
windowTarget.h = videoGetHeight(_global.videoHandle) * _global.conf->scaleFactor / 100;
windowTarget.x = (videoGetWidth(_global.videoHandle) - windowTarget.w) / 2;
windowTarget.y = (videoGetHeight(_global.videoHandle) - windowTarget.h) / 2;
}
// Sinden Light Gun Border Setup
if (_global.conf.sindenArgc > 0) {
if (_global.conf->sindenArgc > 0) {
//***TODO*** ADD MOUSE SCALING TO COMPENSATE FOR BORDER
sindenWhiteColor.r = 255;
sindenWhiteColor.g = 255;
@ -3658,41 +3783,41 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) {
sindenBlackColor.b = 0;
sindenBlackColor.a = 255;
// Ok, this thing can have a mess of different arguments:
switch(_global.conf.sindenArgc) {
switch(_global.conf->sindenArgc) {
// WW - Just the width of the white border
case SINDEN_WHITE:
sindenWhite.x = _global.conf.sindenArgv[0];
sindenWhite.x = _global.conf->sindenArgv[0];
break;
// WW WB - Width of white border and then black border
case SINDEN_WHITE_BLACK:
sindenWhite.x = _global.conf.sindenArgv[0];
sindenBlack.x = _global.conf.sindenArgv[1];
sindenWhite.x = _global.conf->sindenArgv[0];
sindenBlack.x = _global.conf->sindenArgv[1];
break;
// RW GW BW WW - Custom color "white" border and width
case SINDEN_CUSTOM_WHITE:
sindenWhiteColor.r = _global.conf.sindenArgv[0];
sindenWhiteColor.g = _global.conf.sindenArgv[1];
sindenWhiteColor.b = _global.conf.sindenArgv[2];
sindenWhite.x = _global.conf.sindenArgv[3];
sindenWhiteColor.r = _global.conf->sindenArgv[0];
sindenWhiteColor.g = _global.conf->sindenArgv[1];
sindenWhiteColor.b = _global.conf->sindenArgv[2];
sindenWhite.x = _global.conf->sindenArgv[3];
break;
// RW GW BW WW WB - Custom color "white" border and width then width of black border
case SINDEN_CUSTOM_WHITE_BLACK:
sindenWhiteColor.r = _global.conf.sindenArgv[0];
sindenWhiteColor.g = _global.conf.sindenArgv[1];
sindenWhiteColor.b = _global.conf.sindenArgv[2];
sindenWhite.x = _global.conf.sindenArgv[3];
sindenBlack.x = _global.conf.sindenArgv[4];
sindenWhiteColor.r = _global.conf->sindenArgv[0];
sindenWhiteColor.g = _global.conf->sindenArgv[1];
sindenWhiteColor.b = _global.conf->sindenArgv[2];
sindenWhite.x = _global.conf->sindenArgv[3];
sindenBlack.x = _global.conf->sindenArgv[4];
break;
// RW GW BW WW RB GB BB WB - Custom color "white" border and width then custom color "black" border and width
case SINDEN_CUSTOM_WHITE_CUSTOM_BLACK:
sindenWhiteColor.r = _global.conf.sindenArgv[0];
sindenWhiteColor.g = _global.conf.sindenArgv[1];
sindenWhiteColor.b = _global.conf.sindenArgv[2];
sindenWhite.x = _global.conf.sindenArgv[3];
sindenBlackColor.r = _global.conf.sindenArgv[4];
sindenBlackColor.g = _global.conf.sindenArgv[5];
sindenBlackColor.b = _global.conf.sindenArgv[6];
sindenBlack.x = _global.conf.sindenArgv[7];
sindenWhiteColor.r = _global.conf->sindenArgv[0];
sindenWhiteColor.g = _global.conf->sindenArgv[1];
sindenWhiteColor.b = _global.conf->sindenArgv[2];
sindenWhite.x = _global.conf->sindenArgv[3];
sindenBlackColor.r = _global.conf->sindenArgv[4];
sindenBlackColor.g = _global.conf->sindenArgv[5];
sindenBlackColor.b = _global.conf->sindenArgv[6];
sindenBlack.x = _global.conf->sindenArgv[7];
break;
}
if (sindenWhite.x >= 0) {
@ -3730,7 +3855,7 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) {
_global.mouseCount = MAX_MICE;
}
memset(_global.mice, 0, sizeof(_global.mice));
_global.mouseEnabled = (bool)!_global.conf.noMouse;
_global.mouseEnabled = (bool)!_global.conf->noMouse;
for (x=0; x<_global.mouseCount; x++) {
strncpy(_global.mice[x].name, ManyMouse_DeviceName((unsigned)x), sizeof(_global.mice[x].name));
_global.mice[x].name[sizeof(_global.mice[x].name) - 1] = 0;
@ -3752,7 +3877,7 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) {
// Controllers are started by the event loop
// Set volume
_global.effectsVolume = (int32_t)((float)AUDIO_MAX_VOLUME * (float)_global.conf.volumeNonVldp * (float)0.01);
_global.effectsVolume = (int32_t)((float)AUDIO_MAX_VOLUME * (float)_global.conf->volumeNonVldp * (float)0.01);
Mix_Volume(-1, _global.effectsVolume * 2);
// Let us know when sounds end
@ -3770,7 +3895,7 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) {
_global.discStopped = false;
// Start script
if (luaL_dofile(_global.luaContext, _global.conf.scriptFile) != 0) utilDie("Error compiling script: %s", lua_tostring(_global.luaContext, -1));
if (luaL_dofile(_global.luaContext, _global.conf->scriptFile) != 0) utilDie("Error compiling script: %s", lua_tostring(_global.luaContext, -1));
// Game Loop
while (_global.running) {
@ -3984,7 +4109,7 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) {
// Update video
thisFrame = videoUpdate(_global.videoHandle, &_global.videoTexture);
if (_global.conf.isFrameFile) {
if (_global.conf->isFrameFile) {
frameFileUpdate(_global.frameFileHandle, &_global.videoHandle);
}
// Did we get a new video frame?
@ -4032,7 +4157,7 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) {
// Overlay
overlayTexture = SDL_CreateTextureFromSurface(_global.renderer, _global.overlay);
if (!overlayTexture) utilDie("%s", SDL_GetError());
if (!_global.conf.stretchVideo) {
if (!_global.conf->stretchVideo) {
SDL_RenderSetLogicalSize(renderer, videoGetWidth(_global.videoHandle), videoGetHeight(_global.videoHandle));
}
SDL_RenderCopy(_global.renderer, overlayTexture, NULL, &windowTarget);
@ -4103,7 +4228,7 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) {
}
// Unload background video
if (_global.conf.isFrameFile) {
if (_global.conf->isFrameFile) {
frameFileUnload(_global.frameFileHandle);
} else {
videoUnload(_global.videoHandle);
@ -4115,6 +4240,14 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) {
// Stop mice
SDL_ShowCursor(SDL_ENABLE);
ManyMouse_Quit();
// Release global conf memory
destroyConf(&_global.conf);
// Release control mappings
for (x=0; x<INPUT_COUNT; x++) {
free(_global.controlMappings[x].input);
}
}
@ -4188,7 +4321,7 @@ void takeScreenshot(void) {
SDL_Rect viewport;
while (x <= 999) {
snprintf(filename, 1024, "%ssinge%03d.png", _global.conf.dataDir, x);
snprintf(filename, 1024, "%ssinge%03d.png", _global.conf->dataDir, x);
if (!utilFileExists(filename)) break;
x++;
}

View file

@ -50,6 +50,7 @@ typedef struct ConfigS {
char *scriptFile;
char *dataDir;
char *dataDirBase;
bool resolutionWasCalculated;
bool isFrameFile;
bool stretchVideo;
bool noMouse;

View file

@ -322,3 +322,6 @@ platformLinux {
write_file("source.inc.sh", FILEINFO)
}
DISTFILES += \
makePDFs.docbuilder

View file

@ -156,7 +156,7 @@ void utilFixPathSeparators(char **path, bool slash) {
// No - append one.
temp = strdup(work);
free(work);
work = malloc(sizeof(char) * (strlen(temp) + 1));
work = malloc(sizeof(char) * (strlen(temp) + 2));
strcpy(work, temp);
work[strlen(temp)] = utilGetPathSeparator();
work[strlen(temp) + 1] = 0;
@ -219,12 +219,18 @@ char utilGetPathSeparator(void) {
char *utilGetUpToLastPathComponent(char *pathname) {
static char *copy;
static char *copy = NULL;
bool dumb = false; // Using (copy == NULL) below didn't work after optimizations, so enter the dummy.
int32_t x;
x = (int32_t)(strlen(pathname) - strlen(utilGetLastPathComponent(pathname))) - 1;
if (x < 0) x = 0;
if (copy) free(copy);
if (dumb) {
free(copy);
copy = NULL;
} else {
dumb = true;
}
copy = strdup(pathname);
copy[x] = 0;
utilFixPathSeparators(&copy, true);