substract -> subtract
[anarch.git] / main_ncurses.c
blob6708da455704a21acb70fe1a7aa358ad618a586e
1 /**
2 @file main_ncurses.c
4 This is ncurses (terminal) implementation of the game front end. This isn't
5 a full fledged version but rather a "show off" of what can be done with the
6 game; especially the limited ability of ncurses to handle input makes this
7 version very hard to play.
9 by Miloslav Ciz (drummyfish), 2024
11 Released under CC0 1.0 (https://creativecommons.org/publicdomain/zero/1.0/)
12 plus a waiver of all other intellectual property. The goal of this work is to
13 be and remain completely in the public domain forever, available for any use
14 whatsoever.
17 #include <ncurses.h>
18 #include <stdio.h>
19 #include <time.h>
20 #include <unistd.h>
22 #define SFG_SCREEN_RESOLUTION_X 120
23 #define SFG_SCREEN_RESOLUTION_Y 40
24 #define SFG_FPS 30
26 #include "game.h"
28 uint8_t ncScreen[SFG_SCREEN_RESOLUTION_X * SFG_SCREEN_RESOLUTION_Y];
29 uint8_t ncButtonStates[SFG_KEY_COUNT];
30 uint32_t timeStart;
32 const char asciiPalette[] =
33 #if 1
34 " .',:;lcoxkXK0MW";
35 #else
36 " -.,;!/clfsxaVO#";
37 #endif
39 uint32_t currentTime()
41 struct timespec t;
42 timespec_get(&t,TIME_UTC);
43 return 1000 * ((int64_t) t.tv_sec) + ((int64_t) t.tv_nsec) / 1000000;
46 int8_t SFG_keyPressed(uint8_t key)
48 return ncButtonStates[key];
51 void SFG_getMouseOffset(int16_t *x, int16_t *y)
53 return;
56 uint32_t SFG_getTimeMs()
58 return currentTime() - timeStart;
61 void SFG_sleepMs(uint16_t timeMs)
63 usleep(1000 * timeMs);
66 void SFG_setPixel(uint16_t x, uint16_t y, uint8_t colorIndex)
68 ncScreen[y * SFG_SCREEN_RESOLUTION_X + x] = asciiPalette[colorIndex % 16];
71 void SFG_playSound(uint8_t soundIndex, uint8_t volume)
75 void SFG_setMusic(uint8_t value)
79 void SFG_processEvent(uint8_t event, uint8_t data)
83 void SFG_save(uint8_t data[SFG_SAVE_SIZE])
87 uint8_t SFG_load(uint8_t data[SFG_SAVE_SIZE])
89 return 0;
92 int main(void)
94 timeStart = currentTime();
96 initscr();
97 halfdelay(1);
98 keypad(stdscr,TRUE);
99 noecho();
100 curs_set(0);
102 SFG_init();
104 int goOn = 1;
106 while (goOn)
108 erase();
109 move(0,0);
111 const uint8_t *scr = ncScreen;
113 for (int y = 0; y < SFG_SCREEN_RESOLUTION_Y; ++y)
115 move(y,0);
117 for (int x = 0; x < SFG_SCREEN_RESOLUTION_X; ++x)
119 addch(*scr);
120 scr++;
124 refresh();
126 goOn = SFG_mainLoopBody();
128 for (int i = 0; i < SFG_KEY_COUNT; ++i)
129 ncButtonStates[i] = 0;
131 while (1)
133 int c = getch();
135 if (c == ERR)
136 break;
138 switch (c)
140 case KEY_UP: ncButtonStates[SFG_KEY_UP] = 1; break;
141 case KEY_LEFT: ncButtonStates[SFG_KEY_LEFT] = 1; break;
142 case KEY_RIGHT: ncButtonStates[SFG_KEY_RIGHT] = 1; break;
143 case KEY_DOWN: ncButtonStates[SFG_KEY_DOWN] = 1; break;
144 case 'a':
145 case KEY_ENTER: ncButtonStates[SFG_KEY_A] = 1; break;
146 case KEY_CANCEL:
147 case KEY_CLOSE:
148 case 's': ncButtonStates[SFG_KEY_B] = 1; break;
149 case 'd': ncButtonStates[SFG_KEY_C] = 1; break;
150 case ' ': ncButtonStates[SFG_KEY_JUMP] = 1; break;
151 case 'q': ncButtonStates[SFG_KEY_MENU] = 1; break;
152 case 'f': ncButtonStates[SFG_KEY_NEXT_WEAPON] = 1; break;
153 case 'g': ncButtonStates[SFG_KEY_PREVIOUS_WEAPON] = 1; break;
154 case 'n': ncButtonStates[SFG_KEY_STRAFE_LEFT] = 1; break;
155 case 'm': ncButtonStates[SFG_KEY_STRAFE_RIGHT] = 1; break;
156 default: break;
161 endwin();
163 return 0;