Newer
Older
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
/* Set our perspective */
//gluPerspective( 45.0f, ratio, 0.1f, 100.0f );
glOrtho(0, width / screen_zoom, height / screen_zoom, 0, -1001, 1001);
/* Make sure we're chaning the model view and not the projection */
glMatrixMode( GL_MODELVIEW );
/* Reset The View */
glLoadIdentity( );
//TSDL2 SDL_SetGamma(gamma_correction, gamma_correction, gamma_correction);
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
printf("OpenGL max texture size: %d\n", max_texture_size);
/* @see main.h#resizeNeedsNewWindow */
extern bool resizeNeedsNewWindow(int w, int h, bool fullscreen, bool borderless)
{
/* Note: w and h currently not a factor */
bool newWindowNeeded = window && ( (is_borderless && !borderless)
|| (!is_borderless && borderless) );
return (newWindowNeeded);
}
/* @see main.h#do_move */
void do_move(int w, int h) {
/* Save the origin in case a window needs to be remade later. */
if (!ignore_window_change_pos) {
start_xpos = w;
start_ypos = h;
} else {
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
/* Can't move a fullscreen SDL window in one go.*/
if (is_fullscreen) {
/* Drop out of fullscreen so we can move the window. */
SDL_SetWindowFullscreen(window, SDL_FALSE);
}
/* Move the window */
SDL_SetWindowPosition(window, w, h);
/* Jump back into fullscreen if necessary */
if (is_fullscreen) {
if (!SDL_SetWindowFullscreen(window, SDL_TRUE)) {
/* Fullscreen change successful */
is_fullscreen = SDL_TRUE;
} else {
/* Error switching fullscreen mode */
printf("[DO MOVE] Unable to return window"
" to fullscreen mode: %s\n", SDL_GetError());
SDL_ClearError();
}
}
}
/* @see main.h#do_resize */
void do_resize(int w, int h, bool fullscreen, bool borderless, float zoom)
/* Temporary width, height (since SDL might reject our resize) */
int aw, ah;
int mustPushEvent = 0;
int mustCreateIconSurface = 0;
screen_zoom = zoom;
printf("[DO RESIZE] Requested: %dx%d (%d, %d); zoom %d%%\n", w, h, fullscreen, borderless, (int)(zoom * 100));
/* See if we need to reinitialize the window */
if (resizeNeedsNewWindow(w, h, fullscreen, borderless)) {
/* Destroy the current window */
SDL_GL_DeleteContext(maincontext);
SDL_DestroyWindow(window);
maincontext = 0;
window = 0;
screen = 0;
/* Clean up the old window icon */
SDL_FreeSurface(windowIconSurface);
windowIconSurface = 0;
/* Signal a new icon needs to be created. */
mustCreateIconSurface = 1;
}
/* If there is no current window, we have to make one and initialize */
if (!window) {
window = SDL_CreateWindow("TE4",
(start_xpos == -1) ? SDL_WINDOWPOS_CENTERED : start_xpos,
(start_ypos == -1) ? SDL_WINDOWPOS_CENTERED : start_ypos, w, h,
SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL
| (!borderless ? SDL_WINDOW_RESIZABLE : 0)
| (fullscreen ? SDL_WINDOW_FULLSCREEN : 0)
| (borderless ? SDL_WINDOW_BORDERLESS : 0)
);
dg
committed
if (window==NULL) {
printf("error opening screen: %s\n", SDL_GetError());
exit(1);
}
dg
committed
screen = SDL_GetWindowSurface(window);
maincontext = SDL_GL_CreateContext(window);
/* Set the window icon. */
windowIconSurface = IMG_Load_RW(PHYSFSRWOPS_openRead(WINDOW_ICON_PATH)
, TRUE);
SDL_SetWindowIcon(window, windowIconSurface);
if (!desktop_gamma_set) {
desktop_gamma = SDL_GetWindowBrightness(window);
desktop_gamma_set = TRUE;
printf("[GAMMA] Getting desktop gamma of %f\n", desktop_gamma);
}
/* SDL won't allow a fullscreen resolution change in one go. Check. */
if (is_fullscreen) {
/* Drop out of fullscreen so we can change resolution. */
SDL_SetWindowFullscreen(window, SDL_FALSE);
is_fullscreen = 0;
mustPushEvent = 1; /* Actually just a maybe for now, confirmed later */
}
/* Update window size */
dg
committed
SDL_SetWindowSize(window, w, h);
/* Jump [back] into fullscreen if requested */
if (fullscreen) {
if (!SDL_SetWindowFullscreen(window, SDL_TRUE)) {
/* Fullscreen change successful */
is_fullscreen = SDL_TRUE;
} else {
/* Error switching fullscreen mode */
printf("[DO RESIZE] Unable to switch window"
" to fullscreen mode: %s\n", SDL_GetError());
SDL_ClearError();
}
} else if (mustPushEvent) {
/* Handle fullscreen -> nonfullscreen transition */
/*
* Our changes will get clobbered by an automatic event from
* setWindowFullscreen. Push an event to the event loop to make
* sure these changes are applied after whatever that other
* event throws.
*/
/* Create an event to push */
fsEvent.type = SDL_WINDOWEVENT;
fsEvent.window.timestamp = SDL_GetTicks();
fsEvent.window.windowID = SDL_GetWindowID(window);
// windowId
fsEvent.window.event = SDL_WINDOWEVENT_RESIZED;
fsEvent.window.data1 = w;
fsEvent.window.data2 = h;
/* Push the event, but don't bother waiting */
SDL_PushEvent(&fsEvent);
printf("[DO RESIZE]: pushed fullscreen compensation event\n");
}
/* Finally, update the screen info */
dg
committed
screen = SDL_GetWindowSurface(window);
/* Check and see if SDL honored our resize request */
SDL_GetWindowSize(window, &aw, &ah);
printf("[DO RESIZE] Got: %dx%d (%d, %d)\n", aw, ah, is_fullscreen, borderless);
void boot_lua(int state, bool rebooting, int argc, char *argv[])
{
if (state == 1)
{
const char *selfexe;
/* When rebooting we destroy the lua state to free memory and we reset physfs */
if (rebooting)
{
current_mousehandler = LUA_NOREF;
current_keyhandler = LUA_NOREF;
current_game = LUA_NOREF;
lua_close(L);
PHYSFS_deinit();
}
/***************** Physfs Init *****************/
PHYSFS_init(argv[0]);
selfexe = get_self_executable(argc, argv);
{
}
else
{
printf("NO SELFEXE: bootstrapping from CWD\n");
PHYSFS_mount("bootstrap", "/bootstrap", 1);
}
/***************** Lua Init *****************/
L = lua_open(); /* create state */
luaL_openlibs(L); /* open libraries */
luaopen_fov(L);
luaopen_socket_core(L);
luaopen_mime_core(L);
luaopen_struct(L);
luaopen_profiler(L);
luaopen_md5_core(L);
luaopen_map(L);
luaopen_particles(L);
luaopen_sound(L);
luaopen_profile(L);
dg
committed
luaopen_wait(L);
physfs_reset_dir_allowed(L);
#ifdef STEAM_TE4
#endif
#ifdef DISCORD_TE4
extern int luaopen_discord(lua_State *L);
luaopen_discord(L);
// Override "print" if requested
if (no_debug)
{
lua_pushcfunction(L, noprint);
lua_setglobal(L, "print");
}
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
// Make the uids repository
lua_newtable(L);
lua_setglobal(L, "__uids");
// Tell the boostrapping code the selfexe path
if (selfexe)
lua_pushstring(L, selfexe);
else
lua_pushnil(L);
lua_setglobal(L, "__SELFEXE");
// Will be useful
#ifdef __APPLE__
lua_pushboolean(L, TRUE);
lua_setglobal(L, "__APPLE__");
#endif
// Run bootstrapping
if (!luaL_loadfile(L, "/bootstrap/boot.lua"))
{
docall(L, 0, 0);
}
// Could not load bootstrap! Try to mount the engine from working directory as last resort
else
{
lua_pop(L, 1);
printf("WARNING: No bootstrap code found, defaulting to working directory for engine code!\n");
PHYSFS_mount("game/thirdparty", "/", 1);
PHYSFS_mount("game/", "/", 1);
luaL_loadstring(L,
"fs.setPathAllowed(fs.getRealPath('/addons/', true)) " \
"if fs.getRealPath('/dlcs/') then fs.setPathAllowed(fs.getRealPath('/dlcs/', true)) end " \
"fs.setPathAllowed(fs.getRealPath('/modules/', true)) "
);
lua_pcall(L, 0, 0, 0);
}
if (bootstrap_mounted) {
PHYSFS_removeFromSearchPath("bootstrap");
if (te4_web_init) te4_web_init(L);
// And run the lua engine pre init scripts
if (!luaL_loadfile(L, "/loader/pre-init.lua"))
docall(L, 0, 0);
else
lua_pop(L, 1);
create_particles_thread();
}
else if (state == 2)
{
// Now we can open lua lanes, the physfs paths are set and it can load it's lanes-keeper.lua file
// luaopen_lanes(L);
printf("Running lua loader code...\n");
// And run the lua engine scripts
if (!luaL_loadfile(L, "/loader/init.lua"))
{
if (core_def->reboot_engine) lua_pushstring(L, core_def->reboot_engine); else lua_pushnil(L);
if (core_def->reboot_engine_version) lua_pushstring(L, core_def->reboot_engine_version); else lua_pushnil(L);
if (core_def->reboot_module) lua_pushstring(L, core_def->reboot_module); else lua_pushnil(L);
if (core_def->reboot_name) lua_pushstring(L, core_def->reboot_name); else lua_pushnil(L);
lua_pushboolean(L, core_def->reboot_new);
if (core_def->reboot_einfo) lua_pushstring(L, core_def->reboot_einfo); else lua_pushnil(L);
docall(L, 6, 0);
}
else
{
lua_pop(L, 1);
}
// Update core to run
static void define_core(core_boot_type *core_def, const char *coretype, int id, const char *reboot_engine, const char *reboot_engine_version, const char *reboot_module, const char *reboot_name, int reboot_new, const char *reboot_einfo)
{
if (core_def->coretype) free(core_def->coretype);
if (core_def->reboot_engine) free(core_def->reboot_engine);
if (core_def->reboot_engine_version) free(core_def->reboot_engine_version);
if (core_def->reboot_module) free(core_def->reboot_module);
if (core_def->reboot_name) free(core_def->reboot_name);
if (core_def->reboot_einfo) free(core_def->reboot_einfo);
core_def->corenum = id;
core_def->coretype = coretype ? strdup(coretype) : NULL;
core_def->reboot_engine = reboot_engine ? strdup(reboot_engine) : NULL;
core_def->reboot_engine_version = reboot_engine_version ? strdup(reboot_engine_version) : NULL;
core_def->reboot_module = reboot_module ? strdup(reboot_module) : NULL;
core_def->reboot_name = reboot_name ? strdup(reboot_name) : NULL;
core_def->reboot_einfo = reboot_einfo ? strdup(reboot_einfo) : NULL;
core_def->reboot_new = reboot_new;
}
// Let some platforms use a different entry point
#ifdef USE_TENGINE_MAIN
#ifdef main
#undef main
#endif
#define main tengine_main
#endif
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
/* Cleans up a timer lock. See function declaration for more info. */
void cleanupTimerLock(SDL_mutex *lock, SDL_TimerID *timer
, int *timerFlag)
{
// Grab the lock and start cleaning up
SDL_mutexP(lock);
// Cancel the timer (if it is running)
if (*timer) SDL_RemoveTimer(*timer);
*timer = 0;
*timerFlag = -1;
SDL_mutexV(lock);
/*
* Need to get lock once more just in case a timer call was stuck waiting on
* the lock when we altered the variables.
*/
SDL_mutexP(lock);
SDL_mutexV(lock);
// Can now safely destroy the lock.
SDL_DestroyMutex(lock);
}
/* Handles game idle transition. See function declaration for more info. */
void handleIdleTransition(int goIdle)
{
/* Only allow if a display timer is already running. */
if (display_timer_id) {
if (goIdle) {
/* Make sure this isn't an idle->idle transition */
if (requested_fps != requested_fps_idle) {
requested_fps_idle_saved = requested_fps;
setupDisplayTimer(requested_fps_idle);
}
} else if (requested_fps_idle_saved && (requested_fps != requested_fps_idle_saved)) {
/* Made sure this wasn't a nonidle->nonidle */
setupDisplayTimer(requested_fps_idle_saved);
}
if (current_game != LUA_NOREF)
{
lua_rawgeti(L, LUA_REGISTRYINDEX, current_game);
lua_pushstring(L, "idling");
lua_gettable(L, -2);
lua_remove(L, -2);
lua_rawgeti(L, LUA_REGISTRYINDEX, current_game);
lua_pushboolean(L, !goIdle);
docall(L, 2, 0);
}
* Core entry point.
core_def->define = &define_core;
core_def->define(core_def, "te4core", -1, NULL, NULL, NULL, NULL, 0, NULL);
// Parse arguments
int i;
for (i = 1; i < argc; i++)
{
char *arg = argv[i];
if (!strncmp(arg, "-M", 2)) core_def->reboot_module = strdup(arg+2);
if (!strncmp(arg, "-u", 2)) core_def->reboot_name = strdup(arg+2);
if (!strncmp(arg, "-E", 2)) core_def->reboot_einfo = strdup(arg+2);
if (!strncmp(arg, "-n", 2)) core_def->reboot_new = 1;
if (!strncmp(arg, "--flush-stdout", 14))
{
setvbuf(stdout, (char *) NULL, _IOLBF, 0);
#ifdef SELFEXE_WINDOWS
if (!strncmp(arg, "--no-debug", 10)) no_debug = TRUE;
if (!strncmp(arg, "--xpos", 6)) start_xpos = strtol(argv[++i], NULL, 10);
if (!strncmp(arg, "--ypos", 6)) start_ypos = strtol(argv[++i], NULL, 10);
if (!strncmp(arg, "--ignore-window-change-pos", 26)) ignore_window_change_pos = TRUE;
if (!strncmp(arg, "--safe-mode", 11)) safe_mode = TRUE;
if (!strncmp(arg, "--home", 6)) override_home = strdup(argv[++i]);
if (!strncmp(arg, "--no-steam", 10)) no_steam = TRUE;
if (!strncmp(arg, "--type=renderer", 15)) is_zygote = TRUE;
if (!strncmp(arg, "--logtofile", 11)) logtofile = TRUE;
logtofile = TRUE;
#endif
if (!is_zygote && logtofile) {
if (os_autoflush) setvbuf(logfile, NULL, _IONBF, 2);
}
#ifdef SELFEXE_MACOSX
if (!is_zygote) {
const char *logname = "/tmp/te4_log.txt";
logfile = freopen(logname, "w", stdout);
if (os_autoflush) setlinebuf(logfile);
// Initialize display lock for thread safety.
renderingLock = SDL_CreateMutex();
realtimeLock = SDL_CreateMutex();
// Get cpu cores
nb_cpus = get_number_cpus();
printf("[CPU] Detected %d CPUs\n", nb_cpus);
#ifdef STEAM_TE4
// RNG init
init_gen_rand(time(NULL));
int vid_drv;
for (vid_drv = 0; vid_drv < SDL_GetNumVideoDrivers(); vid_drv++)
{
printf("Available video driver: %s\n", SDL_GetVideoDriver(vid_drv));
}
Uint32 flags=SDL_INIT_TIMER | SDL_INIT_JOYSTICK;
if (SDL_Init (flags) < 0) {
printf("cannot initialize SDL: %s\n", SDL_GetError ());
if (SDL_VideoInit(NULL) != 0) {
printf("Error initializing SDL video: %s\n", SDL_GetError());
return 2;
}
if (SDL_NumJoysticks() >= 1) {
if (gamepad = SDL_JoystickOpen(0)) {
printf("Found gamepad, enabling support\n");
}
}
dg
committed
SDL_SetEventFilter(event_filter, NULL);
do_resize(WIDTH, HEIGHT, FALSE, FALSE, screen_zoom);
if (screen==NULL) {
printf("error opening screen: %s\n", SDL_GetError());
dg
committed
SDL_SetWindowTitle(window, "T4Engine");
/* Sets up OpenGL double buffering */
resizeWindow(WIDTH, HEIGHT);
dg
committed
// Allow screensaver to work
SDL_EnableScreenSaver();
SDL_StartTextInput();
dg
committed
// Get OpenGL capabilities
multitexture_active = GLEW_ARB_multitexture;
shaders_active = GLEW_ARB_shader_objects;
fbo_active = GLEW_EXT_framebuffer_object || GLEW_ARB_framebuffer_object;
if (!multitexture_active) shaders_active = FALSE;
if (!GLEW_VERSION_2_1 || safe_mode)
{
multitexture_active = FALSE;
shaders_active = FALSE;
fbo_active = FALSE;
}
if (safe_mode) printf("Safe mode activated\n");
// setupDisplayTimer(30);
init_blank_surface();
boot_lua(2, FALSE, argc, argv);
if (!isActive || tickPaused) SDL_WaitEvent(NULL);
#ifdef SELFEXE_WINDOWS
if (os_autoflush) _commit(_fileno(stdout));
#endif
#ifdef SELFEXE_MACOSX
if (os_autoflush) fflush(stdout);
/* handle the events in the queue */
while (SDL_PollEvent(&event))
{
switch(event.type)
{
dg
committed
case SDL_WINDOWEVENT:
switch (event.window.event)
dg
committed
case SDL_WINDOWEVENT_RESIZED:
/* Note: SDL can't resize a fullscreen window, so don't bother! */
if (!is_fullscreen) {
printf("SDL_WINDOWEVENT_RESIZED: %d x %d\n", event.window.data1, event.window.data2);
do_resize(event.window.data1, event.window.data2, is_fullscreen, is_borderless, screen_zoom);
if (current_game != LUA_NOREF)
{
lua_rawgeti(L, LUA_REGISTRYINDEX, current_game);
lua_pushstring(L, "onResolutionChange");
lua_gettable(L, -2);
lua_remove(L, -2);
lua_rawgeti(L, LUA_REGISTRYINDEX, current_game);
docall(L, 1, 0);
}
} else {
printf("SDL_WINDOWEVENT_RESIZED: ignored due to fullscreen\n");
dg
committed
}
break;
case SDL_WINDOWEVENT_MOVED: {
int x, y;
/* Note: SDL can't resize a fullscreen window, so don't bother! */
if (!is_fullscreen) {
SDL_GetWindowPosition(window, &x, &y);
printf("move %d x %d\n", x, y);
if (current_game != LUA_NOREF)
{
lua_rawgeti(L, LUA_REGISTRYINDEX, current_game);
lua_pushstring(L, "onWindowMoved");
lua_gettable(L, -2);
lua_remove(L, -2);
lua_rawgeti(L, LUA_REGISTRYINDEX, current_game);
lua_pushnumber(L, x);
lua_pushnumber(L, y);
docall(L, 3, 0);
}
} else {
printf("SDL_WINDOWEVENT_MOVED: ignored due to fullscreen\n");
dg
committed
}
break;
dg
committed
case SDL_WINDOWEVENT_CLOSE:
event.type = SDL_QUIT;
SDL_PushEvent(&event);
break;
dg
committed
case SDL_WINDOWEVENT_SHOWN:
case SDL_WINDOWEVENT_FOCUS_GAINED:
SDL_SetModState(KMOD_NONE);
/* break from idle */
//printf("[EVENT HANDLER]: Got a SHOW/FOCUS_GAINED event, restoring full FPS.\n");
handleIdleTransition(0);
break;
case SDL_WINDOWEVENT_HIDDEN:
dg
committed
case SDL_WINDOWEVENT_FOCUS_LOST:
dg
committed
SDL_SetModState(KMOD_NONE);
//printf("[EVENT HANDLER]: Got a HIDDEN/FOCUS_LOST event, going idle.\n");
handleIdleTransition(1);
dg
committed
break;
default:
break;
/* TODO: Enumerate user event codes */
switch(event.user.code)
{
case 0:
if (isActive) {
current_redraw_type = redraw_type_normal;
on_redraw();
SDL_mutexP(renderingLock);
redraw_pending = 0;
SDL_mutexV(renderingLock);
}
break;
break;
case 2:
if (isActive) {
on_tick();
SDL_mutexP(realtimeLock);
realtime_pending = 0;
SDL_mutexV(realtimeLock);
}
break;
default:
break;
/* handle key presses */
if (on_event(&event)) {
tickPaused = FALSE;
}
// Note: since realtime_timer_id is accessed, have to lock first
int doATick = 0;
SDL_mutexP(realtimeLock);
if (!realtime_timer_id && isActive && !tickPaused) {
doATick = 1;
realtime_pending = 1;
}
SDL_mutexV(realtimeLock);
if (doATick) {
on_tick();
SDL_mutexP(realtimeLock);
realtime_pending = 0;
SDL_mutexV(realtimeLock);
}
/* Reboot the lua engine */
// Just reboot the lua VM
{
tickPaused = FALSE;
setupRealtime(0);
boot_lua(1, TRUE, argc, argv);
boot_lua(2, TRUE, argc, argv);
}
// Clean up and tell the runner to run a different core
else
{
free_particles_thread();
free_profile_thread();
PHYSFS_deinit();
break;
}
// Clean up locks.
cleanupTimerLock(renderingLock, &display_timer_id, &redraw_pending);
cleanupTimerLock(realtimeLock, &realtime_timer_id, &realtime_pending);
// Restore default gamma on exit.
#ifdef SELFEXE_MACOSX
fclose(stdout);
#endif