Crazy memory bugs fixed. Menu improved.
This commit is contained in:
parent
aff5341801
commit
c49fe5afe4
14 changed files with 480 additions and 261 deletions
1
.gitattributes
vendored
1
.gitattributes
vendored
|
@ -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
1
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
|||
~*
|
||||
*~
|
||||
*.log
|
||||
*.user
|
||||
|
|
BIN
singe/Manual.docx
Normal file
BIN
singe/Manual.docx
Normal file
Binary file not shown.
BIN
singe/Manual.odt
(Stored with Git LFS)
BIN
singe/Manual.odt
(Stored with Git LFS)
Binary file not shown.
153
singe/Menu.singe
153
singe/Menu.singe
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
73
singe/main.c
73
singe/main.c
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
3
singe/makePDFs.docbuilder
Normal file
3
singe/makePDFs.docbuilder
Normal file
|
@ -0,0 +1,3 @@
|
|||
builder.OpenFile("Manual.docx");
|
||||
builder.SaveFile("pdf", "/tmp/Manual.pdf");
|
||||
builder.CloseFile();
|
473
singe/singe.c
473
singe/singe.c
|
@ -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++;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ typedef struct ConfigS {
|
|||
char *scriptFile;
|
||||
char *dataDir;
|
||||
char *dataDirBase;
|
||||
bool resolutionWasCalculated;
|
||||
bool isFrameFile;
|
||||
bool stretchVideo;
|
||||
bool noMouse;
|
||||
|
|
|
@ -322,3 +322,6 @@ platformLinux {
|
|||
|
||||
write_file("source.inc.sh", FILEINFO)
|
||||
}
|
||||
|
||||
DISTFILES += \
|
||||
makePDFs.docbuilder
|
||||
|
|
12
singe/util.c
12
singe/util.c
|
@ -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(©, true);
|
||||
|
|
Loading…
Add table
Reference in a new issue