diff --git a/.gitignore b/.gitignore index 6cacab9..5180efd 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,8 @@ traversal_server User Sys *.iso +*.ciso *.json scripts/build.log scripts/Ishiiruka +scripts/work diff --git a/Makefile b/Makefile index c28fbaa..e054a13 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CC=cc -CFLAGS=`pkg-config --cflags efl ecore elementary` `curl-config --cflags` -LDFLAGS=`pkg-config --libs efl ecore elementary` `curl-config --libs` -lcjson -OBJS=main.o replay.o home.o +CFLAGS=-g `pkg-config --cflags efl ecore elementary` `sdl2-config --cflags` `curl-config --cflags` +LDFLAGS=`pkg-config --libs efl ecore elementary` `sdl2-config --libs` `curl-config --libs` -lcjson +OBJS=main.o replay.o home.o input.o minilauncher4slippi: $(OBJS) $(CC) -o minilauncher4slippi $(OBJS) $(LDFLAGS) diff --git a/home.c b/home.c index 5eedbcc..cb9db87 100644 --- a/home.c +++ b/home.c @@ -2,7 +2,6 @@ #include #include #include -#include #include "replay.h" Evas_Object* tab_home = NULL; @@ -144,8 +143,7 @@ _tab_home_make_da_damn_request() } - -void +Evas_Object* tab_home_setup(Evas_Object* parent) { curl_global_init(CURL_GLOBAL_ALL); @@ -173,4 +171,5 @@ tab_home_setup(Evas_Object* parent) evas_object_show(tab_home); _tab_home_make_da_damn_request(); + return tab_home; } diff --git a/home.h b/home.h index fd2a28f..464a6fc 100644 --- a/home.h +++ b/home.h @@ -8,7 +8,7 @@ extern Evas_Object* tab_home; -void +Evas_Object* tab_home_setup(Evas_Object* parent); #endif /* HOME_H */ diff --git a/input.c b/input.c new file mode 100644 index 0000000..9bf6e14 --- /dev/null +++ b/input.c @@ -0,0 +1,110 @@ +#include +#include +#include "input.h" + +static SDL_GameController* gamepad; +extern Evas_Object* win, *mainer, *_tab_curr; +void +_launch_slippi_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED); + +void +input_sdl_init_thread() +{ + Ecore_Thread* thread = ecore_thread_run(_input_sdl_setup_thread, NULL, NULL, NULL); + ecore_thread_local_data_set(thread, "win", win, NULL); +} + +static void +input_sdl_eventloop(Ecore_Thread *thread) +{ + SDL_Event e; + while (1) + { + while (SDL_PollEvent(&e)) + { + ecore_thread_main_loop_begin(); + switch (e.type) { + case SDL_CONTROLLERDEVICEADDED: + if (!gamepad) { + gamepad = SDL_GameControllerOpen(e.cdevice.which); + printf("Found\n"); + } + break; + case SDL_CONTROLLERDEVICEREMOVED: + if (gamepad) { + SDL_GameControllerClose(gamepad); + gamepad = NULL; + printf("Removed.\n"); + } + break; + case SDL_CONTROLLERBUTTONDOWN: + { + Evas_Object* focused = ecore_thread_local_data_find(thread, "win"); + switch (e.cbutton.button) + { + case SDL_CONTROLLER_BUTTON_DPAD_UP: + elm_object_focus_next(focused, ELM_FOCUS_UP); + break; + case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: + elm_object_focus_next(focused, ELM_FOCUS_RIGHT); + break; + case SDL_CONTROLLER_BUTTON_DPAD_DOWN: + elm_object_focus_next(focused, ELM_FOCUS_DOWN); + break; + case SDL_CONTROLLER_BUTTON_DPAD_LEFT: + elm_object_focus_next(focused, ELM_FOCUS_LEFT); + break; + case SDL_CONTROLLER_BUTTON_A: + evas_object_smart_callback_call(elm_object_focused_object_get(focused), "clicked", NULL); + evas_object_smart_callback_call(elm_object_focused_object_get(focused), "activate", NULL); + break; + case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: + prev_tab(); + break; + case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: + next_tab(); + break; + case SDL_CONTROLLER_BUTTON_START: + _launch_slippi_cb(NULL, NULL, NULL); + break; + } + //evas_object_smart_callback_call(elm_object_focused_object_get(focused), "selected", elm_object_focused_object_get(focused)); + elm_object_focus_set(elm_object_focused_object_get(focused), EINA_TRUE); + //elm_object_item_focus_set(elm_object_focused_object_get(focused), EINA_TRUE); + break; + } + default: + break; + } + ecore_thread_main_loop_end(); + } + } +} + +void +input_sdl_setup() +{ + if (SDL_Init(SDL_INIT_GAMECONTROLLER) < 0) + { + fprintf(stderr, "Couldn't initialize SDL Gamepad: %s\n", SDL_GetError()); + return; + } + + for (int i = 0; i < SDL_NumJoysticks(); ++i) + { + if (SDL_IsGameController(i)) + { + gamepad = SDL_GameControllerOpen(i); + printf("%i gamepads were found. Using %s (#%i).\n", + SDL_NumJoysticks(), SDL_GameControllerName(gamepad), i+1); + break; + } + } +} + +void +_input_sdl_setup_thread(void *data, Ecore_Thread *thread) +{ + input_sdl_setup(); + input_sdl_eventloop(thread); +} diff --git a/input.h b/input.h new file mode 100644 index 0000000..848f280 --- /dev/null +++ b/input.h @@ -0,0 +1,14 @@ +#ifndef INPUT_H +#define INPUT_H +#include + +void +input_sdl_setup(); + +void +input_sdl_init_thread(); + +void +_input_sdl_setup_thread(); + +#endif /* INPUT_H */ diff --git a/main.c b/main.c index adef5f6..22d4b1f 100644 --- a/main.c +++ b/main.c @@ -5,6 +5,9 @@ #include #include "replay.h" #include "home.h" +#ifndef NO_SDL_INPUT +# include "input.h" +#endif int opt_mallocd = -1; char* game_path = "SSBM.iso"; @@ -14,10 +17,37 @@ char* dolphin_replay_file = "slippi-playback-dolphin"; Evas_Object* mainer; Evas_Object* win; Evas_Object* _tab_curr; -//extern Evas_Object* tab_home; -//extern Evas_Object* tab_replays; +extern Evas_Object* tab_home; +extern Evas_Object* tab_replays; +Evas_Object* _tabs[] = { NULL, NULL }; +int _tabs_len = 2; +int _tabs_i = 0; // home Evas_Object* tab_config; +void update_tab(Evas_Object*); + +void +prev_tab() +{ + --_tabs_i; + if (_tabs_i == -1) + { + _tabs_i = _tabs_len-1; + } + update_tab(_tabs[_tabs_i]); +} + +void +next_tab() +{ + ++_tabs_i; + if (_tabs_i == _tabs_len) + { + _tabs_i = 0; + } + update_tab(_tabs[_tabs_i]); +} + int parse_config(char* file) { @@ -47,30 +77,33 @@ abort: return 0; } +void +update_tab(Evas_Object* newtab) +{ + elm_obj_box_unpack_all(mainer); + evas_object_hide(_tab_curr); + if (newtab) + { + _tab_curr = newtab; + evas_object_size_hint_weight_set(_tab_curr, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_show(mainer); + evas_object_show(_tab_curr); + elm_obj_box_pack_end(mainer, _tab_curr); + } +} + void _tab_switch_cb(void *_data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { Evas_Object** data = _data; - elm_obj_box_unpack_all(mainer); - evas_object_hide(_tab_curr); - _tab_curr = *data; - - evas_object_size_hint_weight_set(_tab_curr, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - - //elm_obj_box_recalculate(mainer); - evas_object_show(mainer); - evas_object_show(_tab_curr); - elm_obj_box_pack_end(mainer, _tab_curr); - - //evas_object_move(_tab_curr, 100, 15); - //evas_object_resize(_tab_curr, 100, 100); - - //Evas_Object* test = elm_button_add(mainer); - //elm_object_text_set(test, "Test button"); - //evas_object_show(test); - //elm_obj_box_pack_end(mainer, test); + update_tab(*data); } +void _prev_tab_cb(void *_data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ prev_tab(); } +void _next_tab_cb(void *_data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ next_tab(); } + void _launch_slippi_job_end_cb(void *data, Ecore_Thread *thread) { @@ -94,10 +127,11 @@ _launch_slippi_job_cb(void *data, Ecore_Thread *thread) } } -static void +void _launch_slippi_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { - elm_object_disabled_set(data, EINA_TRUE); + if (data) + elm_object_disabled_set(data, EINA_TRUE); ecore_thread_run(_launch_slippi_job_cb, _launch_slippi_job_end_cb, _launch_slippi_job_end_cb, data); @@ -116,14 +150,14 @@ _replays_tab_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_ void tabs_init() { - tab_home_setup(mainer); + _tabs[0] = tab_home_setup(mainer); // BEGIN tab_replays - tab_replays_setup(mainer); - // END tab_replays + _tabs[1] = tab_replays_setup(mainer); + // Show home tab at start _tab_curr = tab_home; evas_object_show(_tab_curr); elm_obj_box_pack_end(mainer, _tab_curr); @@ -163,13 +197,25 @@ elm_main(int argc, char **argv) elm_win_resize_object_add(win, main); evas_object_show(main); + elm_win_focus_highlight_enabled_set(win, EINA_TRUE); + elm_win_focus_highlight_animate_set(win, EINA_TRUE); + // Check for a 'b' character, aka big picture mode, big mode, whatever.. + int bigmode = 0; + if (argc > 1 && argv[1] && tolower(argv[1][0]) == 'b') + { + bigmode = 1; + elm_object_scale_set(win, 1.8); + } // END main // BEGIN toolbar tb_box = elm_box_add(win); - tb = elm_toolbar_add(tb_box); elm_box_horizontal_set(tb_box, EINA_TRUE); + if (!bigmode) + { + tb = elm_toolbar_add(tb_box); + elm_object_style_set(tb, "item_horizontal"); elm_toolbar_homogeneous_set(tb, EINA_TRUE); elm_toolbar_shrink_mode_set(tb, ELM_TOOLBAR_SHRINK_MENU); @@ -191,26 +237,61 @@ elm_main(int argc, char **argv) elm_toolbar_item_menu_set(tb_it, EINA_TRUE); elm_toolbar_item_priority_set(tb_it, -9999); elm_toolbar_menu_parent_set(tb, win); + } + // Play button that = elm_button_add(tb_box); elm_object_text_set(that, "Play"); evas_object_smart_callback_add(that, "clicked", _launch_slippi_cb, that); Evas_Object* icon = elm_icon_add(win); elm_icon_standard_set(icon, "input-gaming"); + elm_icon_resizable_set(icon, EINA_TRUE, EINA_FALSE); elm_object_part_content_set(that, "icon", icon); evas_object_show(that); - elm_box_pack_end(tb_box, that); + elm_box_pack_end(tb_box, that); + // End play button - elm_box_pack_end(tb_box, tb); - - that = elm_clock_add(tb_box); + if (bigmode) + { + // Prev button + that = elm_button_add(tb_box); + elm_object_text_set(that, ""); + evas_object_smart_callback_add(that, "clicked", _prev_tab_cb, NULL); + /*ICON*/icon = elm_icon_add(win); + elm_icon_standard_set(icon, "go-previous"); + elm_icon_resizable_set(icon, EINA_TRUE, EINA_FALSE); + elm_object_part_content_set(that, "icon", icon); + /*END ICON*/ evas_object_show(that); - elm_box_pack_end(tb_box, that); + elm_box_pack_start(tb_box, that); - elm_box_pack_end(main, tb_box); + // Next button + that = elm_button_add(tb_box); + elm_object_text_set(that, ""); + evas_object_smart_callback_add(that, "clicked", _next_tab_cb, that); + /*ICON*/icon = elm_icon_add(win); + elm_icon_standard_set(icon, "go-next"); + elm_icon_resizable_set(icon, EINA_TRUE, EINA_FALSE); + elm_object_part_content_set(that, "icon", icon); + /*END ICON*/ + evas_object_show(that); + elm_box_pack_end(tb_box, that); + } + + if (!bigmode) + { + elm_box_pack_end(tb_box, tb); + + that = elm_clock_add(tb_box); + evas_object_size_hint_fill_set(that, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(that); + elm_box_pack_end(tb_box, that); + evas_object_show(tb); + } + + elm_box_pack_end(main, tb_box); evas_object_show(tb_box); - evas_object_show(tb); // END toolbar mainer = elm_box_add(win); @@ -225,10 +306,16 @@ elm_main(int argc, char **argv) tabs_init(); evas_object_resize(win, 520 * elm_config_scale_get(), - 300 * elm_config_scale_get()); + 300 * elm_config_scale_get()); evas_object_show(win); printf("[Current config] %s, %s, %s\n", game_path, dolphin_emu_file, dolphin_replay_file); + + // Setup input +#ifndef NO_SDL_INPUT + input_sdl_init_thread(); +#endif + elm_run(); if (opt_mallocd >= 0) free(game_path); diff --git a/minilauncher4slippi.cfg b/minilauncher4slippi.cfg index 6c3e146..dca09a6 100644 --- a/minilauncher4slippi.cfg +++ b/minilauncher4slippi.cfg @@ -1,3 +1,3 @@ -SSBM.iso +SSBM.ciso slippi-netplay-dolphin slippi-playback-dolphin diff --git a/replay.c b/replay.c index 098937d..ef2f52c 100644 --- a/replay.c +++ b/replay.c @@ -220,7 +220,7 @@ _item_select_cb(void *data, Evas_Object *obj, void *event_info) free(jason); } -void +Evas_Object* tab_replays_setup(Evas_Object* parent) { tab_replays = elm_genlist_add(parent); @@ -248,5 +248,5 @@ tab_replays_setup(Evas_Object* parent) } evas_object_size_hint_align_set(tab_replays, EVAS_HINT_FILL, EVAS_HINT_FILL); - + return tab_replays; } diff --git a/replay.h b/replay.h index e25cad0..b30e217 100644 --- a/replay.h +++ b/replay.h @@ -8,7 +8,7 @@ extern Evas_Object* tab_replays; -void +Evas_Object* tab_replays_setup(Evas_Object* parent); #endif /* REPLAY_H */ diff --git a/scripts/slippi-install-unix.sh b/scripts/slippi-install-unix.sh index 6b00ddd..25e5a80 100755 --- a/scripts/slippi-install-unix.sh +++ b/scripts/slippi-install-unix.sh @@ -15,6 +15,26 @@ then SU="doas" fi +if command -v pkg > /dev/null +then + echo "You're on FreeBSD! This works fine, but be mindful of any errors!" +fi + + +nf() { if ! command -v "$1" > /dev/null; then echo "$1 not found. Set \$IJUSTKNOWOKAY to skip these checks."; exit 2; fi } +npkgcnf() { if ! pkg-config --libs "$1" > /dev/null; then echo "library $1 not found. Set \$IJUSTKNOWOKAY to skip these checks."; exit 3; fi } +# Just some bin tests +if [ ! "$IJUSTKNOWOKAY" ] +then + nf "rustc" + nf "git" + nf "pkg-config" + nf "cmake" + npkgcnf "libcurl" + npkgcnf "libusb-1.0" + npkgcnf "libpng" +fi + if [ "$_IS_INSTALL" = "install" ] then CMAKE_FLAGS="$CMAKE_FLAGS -DINSTALLMODE=true" @@ -37,14 +57,34 @@ if [ "$_PATH" == "git" ] then echo "== Cloning Slippi Ishiiruka..." # Point to my own fork for now until I provide .patch files - git clone --recurse-submodules -j$THREADS "https://github.com/nekobbbbbbit/Ishiiruka.git" work > /dev/null || exit - cd work -else - cd "$_PATH" + if [ ! -d "work" ] + then + git clone --recurse-submodules -j$THREADS "https://github.com/nekobbbbbbit/Ishiiruka.git" work > /dev/null || exit + else + printf "Already git cloned. Checking updates.\n[GIT] " + git -C work pull + echo "git pull returned $?" + echo "You should probably check Minilauncher for updates too =^)" + fi + _PATH=work fi +cd "$_PATH" echo "NOTE: Build logs are stored in build.log" +check_error() +{ + if [ $? -eq 0 ] + then + echo ">>> :-)" + else + echo -e "--------- Command failed. build.log output ---------\n[ *snip* ]" + tail -n 45 "$PWD_/build.log" + echo ">>> :-(" + exit 1 + fi +} + build_slippi() { BUILD_DIR="$1" @@ -57,10 +97,14 @@ build_slippi() DATE=$(date "+%Y-%m-%d %H:%M:%S") echo ">>>>>> BEGIN BUILD LOG ON $DATE" >> "$PWD_/build.log" echo ">>> cmake $CMAKE_F .." >> "$PWD_/build.log" - cmake $CMAKE_F .. >> "$PWD_/build.log" 2>&1 || exit 1 + echo ">>> cmake $CMAKE_F .." + cmake $CMAKE_F .. >> "$PWD_/build.log" 2>&1 + check_error echo "== Building $NEW_BIN_NAME" echo ">>> make -j$THREADS" >> "$PWD_/build.log" - make -j$THREADS >> "$PWD_/build.log" 2>&1 || exit 1 + echo ">>> make -j$THREADS" + make -j$THREADS >> "$PWD_/build.log" 2>&1 + check_error echo ">>>>>> END BUILD LOG ON $DATE" >> "$PWD_/build.log" cd .. # Copy the Sys folder in