-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
143 lines (121 loc) · 3.42 KB
/
main.cpp
File metadata and controls
143 lines (121 loc) · 3.42 KB
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
still-alive - This program will play a song from Portal closing credits and prints its lyrics with some ascii-art
Copyright (C) 2024 Dmitry Kotov
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of the License
*/
#include <iostream>
#include <ncurses.h>
#include <exception>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#include <argp.h>
#include <readline/readline.h>
#include <readline/history.h>
#include "Player.h"
#include "notes_defenitions.h"
/*argp global variables*/
const char* argp_program_version = "version 1.0";
const char* argp_program_bug_address = "tg: @nullptrHasBeenReturned";
/*argp stuff begin*/
static const char argp_doc[] = "Play Portal ending song \"Still Alive\""
" by motherboard buzzer and show lyrics with some ascii-art. Also it can power off PC. "
"You MUST run this program only in linux tty console otherwise it won't work properly";
static struct argp_option options[] =
{
{"poweroff", 'p', 0, 0, "Shuts down the computer. You have to have superuser privelieges to use this "
"otherwise computer won't be turned off"},
{0}
};
static error_t parse_opt(int key, char *arg, argp_state *state)
{
bool* shutdown = reinterpret_cast<bool*>(state->input);
static int argCount = 1;
switch(key)
{
case 'p':
*shutdown = true;
--argCount;
break;
case ARGP_KEY_END:
if(argCount < 0)
{
argp_failure(state, 1, 0, "too many arguments");
argp_usage(state);
}
break;
}
return 0;
}
/*argp stuff end*/
/*here terminal attributes are stored*/
struct termios Original_Termios;
/*
custom terminate function
which will mute the speaker if it's playing sound
and restore terminal attributes (ncurses(?) affects them without proper closing)
*/
static void terminate(void)
{
silence();
system("clear");
tcsetattr(STDIN_FILENO, TCSANOW, &Original_Termios);
}
/*custom SIGINT handler calls void terminate*/
static void sigintHandler(int sig)
{
terminate();
std::exit(sig);
}
int main(int argc, char** argv)
{
/*start argp*/
bool shutdown = false;
struct argp argp = {options, parse_opt, argp_doc, 0};
argp_parse(&argp, argc, argv, 0, 0, &shutdown);
/*save terminal attributes in case of program termination*/
tcgetattr(STDIN_FILENO, &Original_Termios);
/*set custom terminate function*/
std::set_terminate([]()
{
terminate();
std::abort();
});
/*call custom sigint handler when SIGINT received*/
signal(SIGINT, sigintHandler);
/*
init the screen
set up memory and clear the screen*/
initscr();
/*check for root privelieges*/
bool usrHasPriv = false;
/*check if EUID is root*/
if(geteuid() == 0)
{
usrHasPriv = true;
}
Player player;
/*Set a song to play*/
player.setSong(std::move(notes));
player.setLyrics(std::move(lyrics));
player.printBorders();
/*main loop*/
while(!player.done())
{
player.sing();
player.print();
}
/*stops the sound*/
silence();
/*deallocates memory*/
endwin();
if(usrHasPriv && shutdown)
{
system("systemctl poweroff");
}
return 0;
}