aboutsummaryrefslogtreecommitdiff
path: root/funkey/fk_instant_play.c
blob: 8c8fc3366a51bdb8dca0628115eba131e74fee28 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
    FK - FunKey retro gaming console library
    Copyright (C) 2020-2021 Vincent Buso
    Copyright (C) 2020-2021 Michel Stempin

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    Vincent Buso
    vincent.buso@funkey-project.com
    Michel Stempin
    michel.stempin@funkey-project.com
*/

/**
 *  @file FK_Instant_Play.c
 *  This is the Instant Play API for the FunKey retro gaming console library
 */

#include <stdio.h>
#include <unistd.h>
#include "fk_menu.h"
#include "fk_instant_play.h"
#include "core.h"
#include "util.h"

#ifndef SHELL_CMD_POWERDOWN
#define SHELL_CMD_POWERDOWN                 "powerdown"
#define SHELL_CMD_POWERDOWN_HANDLE          "powerdown handle"
#endif

static char *prog_name;

/* Handler for SIGUSR1, caused by closing the console */
static void handle_sigusr1(int signal)
{
    FILE *fp;

    printf("Caught signal USR1(%d)\n", signal);

    /* Exit menu if it was launched */
    FK_EndMenu();

    /* Send command to cancel any previously scheduled powerdown */
    fp = popen(SHELL_CMD_POWERDOWN_HANDLE, "r");
    if (fp == NULL)
    {
        /* Countdown is still ticking, so better do nothing
           than start writing and get interrupted!
        */
        printf("Failed to cancel scheduled shutdown\n");
        exit(0);
    }
    pclose(fp);

    if (in_menu) {
        FK_Suspend();
    } else {
        /* Wait for the core to be ready to save */
        should_suspend = true;
    }
}

void FK_Suspend(void)
{
    FILE *fp;
    char pidcmd[100];

    state_slot = AUTOSAVE_SLOT;
    if(state_write()) {
        printf("Save failed\n");
        state_slot = 0;
    }

    sram_write();
    save_config(CONFIG_TYPE_AUTO);

    PA_INFO("Suspending with %s %s %s %s %s\n", SHELL_CMD_INSTANT_PLAY, "save", prog_name, core_path, content->path);

    snprintf(pidcmd, array_size(pidcmd), "pid record %d", getpid());

    fp = popen(pidcmd, "r");
    if (fp == NULL)
        PA_ERROR("Failed to update stored pid\n");

    pclose(fp);

    fflush(stdout);

    /* Perform Instant Play save and shutdown */
    execlp(SHELL_CMD_INSTANT_PLAY, SHELL_CMD_INSTANT_PLAY, "save", prog_name, core_path, content->path, NULL);

    /* Should not be reached */
    printf("Failed to perform shutdown\n");

    /* Exit application */
    exit(0);
}


void FK_InitInstantPlay(int argc, char **argv)
{
    prog_name = argv[0];
    signal(SIGUSR1, handle_sigusr1);
}