/** * Monotron API header file. * * Copyright (c) Jonathan 'theJPster' Pallant 2019 * * Available under the Blue Oak Council licence * (https://blueoakcouncil.org/license/1.0.0) */ /****************************************************************************** * * Required Header Files * *****************************************************************************/ #include #include /****************************************************************************** * * Public Macros * *****************************************************************************/ #define MAX_VOLUME 255 #define RAND_MAX 32768 #define FRAMES_PER_SECOND 60 #define ELEMOF(x) (sizeof (x) / sizeof (x)[0]) #define NUMELTS ELEMOF #define TERM_ESCAPE_STR "\x1B" #define TERM_FG_RED TERM_ESCAPE_STR "R" #define TERM_FG_GREEN TERM_ESCAPE_STR "G" #define TERM_FG_BLUE TERM_ESCAPE_STR "B" #define TERM_FG_BLACK TERM_ESCAPE_STR "K" #define TERM_FG_WHITE TERM_ESCAPE_STR "W" #define TERM_FG_YELLOW TERM_ESCAPE_STR "Y" #define TERM_FG_CYAN TERM_ESCAPE_STR "C" #define TERM_FG_MAGENTA TERM_ESCAPE_STR "M" #define TERM_BG_RED TERM_ESCAPE_STR "r" #define TERM_BG_GREEN TERM_ESCAPE_STR "g" #define TERM_BG_BLUE TERM_ESCAPE_STR "b" #define TERM_BG_BLACK TERM_ESCAPE_STR "k" #define TERM_BG_WHITE TERM_ESCAPE_STR "w" #define TERM_BG_YELLOW TERM_ESCAPE_STR "y" #define TERM_BG_CYAN TERM_ESCAPE_STR "c" #define TERM_BG_MAGENTA TERM_ESCAPE_STR "m" #define TERM_DOUBLE_UPPER TERM_ESCAPE_STR "^" #define TERM_DOUBLE_LOWER TERM_ESCAPE_STR "v" #define TERM_DOUBLE_CANCEL TERM_ESCAPE_STR "-" #define TERM_CLS TERM_ESCAPE_STR "Z" // Note frequencies are in Centi-hertz #define Note_Rest 0 #define Note_C0 1635 #define Note_CsDb0 1732 #define Note_D0 1835 #define Note_DsEb0 1945 #define Note_E0 2060 #define Note_F0 2183 #define Note_FsGb0 2312 #define Note_G0 2450 #define Note_GsAb0 2596 #define Note_A0 2750 #define Note_AsBb0 2914 #define Note_B0 3087 #define Note_C1 3270 #define Note_CsDb1 3465 #define Note_D1 3671 #define Note_DsEb1 3889 #define Note_E1 4120 #define Note_F1 4365 #define Note_FsGb1 4625 #define Note_G1 4900 #define Note_GsAb1 5191 #define Note_A1 5500 #define Note_AsBb1 5827 #define Note_B1 6174 #define Note_C2 6541 #define Note_CsDb2 6930 #define Note_D2 7342 #define Note_DsEb2 7778 #define Note_E2 8241 #define Note_F2 8731 #define Note_FsGb2 9250 #define Note_G2 9800 #define Note_GsAb2 10383 #define Note_A2 11000 #define Note_AsBb2 11654 #define Note_B2 12347 #define Note_C3 13081 #define Note_CsDb3 13859 #define Note_D3 14683 #define Note_DsEb3 15556 #define Note_E3 16481 #define Note_F3 17461 #define Note_FsGb3 18500 #define Note_G3 19600 #define Note_GsAb3 20765 #define Note_A3 22000 #define Note_AsBb3 23308 #define Note_B3 24694 #define Note_C4 26163 #define Note_CsDb4 27718 #define Note_D4 29366 #define Note_DsEb4 31113 #define Note_E4 32963 #define Note_F4 34923 #define Note_FsGb4 36999 #define Note_G4 39200 #define Note_GsAb4 41530 #define Note_A4 44000 #define Note_AsBb4 46616 #define Note_B4 49388 #define Note_C5 52325 #define Note_CsDb5 55437 #define Note_D5 58733 #define Note_DsEb5 62225 #define Note_E5 65925 #define Note_F5 69846 #define Note_FsGb5 73999 #define Note_G5 78399 #define Note_GsAb5 83061 #define Note_A5 88000 #define Note_AsBb5 93233 #define Note_B5 98777 #define Note_C6 104650 #define Note_CsDb6 110873 #define Note_D6 117466 #define Note_DsEb6 124451 #define Note_E6 131851 #define Note_F6 139691 #define Note_FsGb6 147998 #define Note_G6 156798 #define Note_GsAb6 166122 #define Note_A6 176000 #define Note_AsBb6 186466 #define Note_B6 197553 #define Note_C7 209300 #define Note_CsDb7 221746 #define Note_D7 234932 #define Note_DsEb7 248902 #define Note_E7 263702 #define Note_F7 279383 #define Note_FsGb7 295996 #define Note_G7 313596 #define Note_GsAb7 332244 #define Note_A7 352000 #define Note_AsBb7 372931 #define Note_B7 395107 #define Note_C8 418601 #define Note_CsDb8 443492 #define Note_D8 469863 #define Note_DsEb8 497803 #define Note_E8 527404 #define Note_F8 558765 #define Note_FsGb8 591991 #define Note_G8 627193 #define Note_GsAb8 664488 #define Note_A8 704000 #define Note_AsBb8 745862 #define Note_B8 790213 /****************************************************************************** * * Public Types * *****************************************************************************/ /** * Describes the possible synth channels. */ typedef enum channel_t { CHANNEL_0 = 0, CHANNEL_1 = 1, CHANNEL_2 = 2, } channel_t; /** * Describes the possible waveforms we can get from the synth. */ typedef enum waveform_t { WAVEFORM_SQUARE = 0, WAVEFORM_SINE = 1, WAVEFORM_SAWTOOTH = 2, WAVEFORM_NOISE = 3, } waveform_t; /****************************************************************************** * * Public Function Prototypes * *****************************************************************************/ void init(void); void deinit(void); /** * Convert a number to a string. * * @param value the number to convert * @param str the buffer to write the number to (must be large enough!) * @param base usually 10 for decimal, or 16 for hexadecimal * @return the str pointer */ char* monotron_utoa(unsigned int value, char* str, int base); /** * Entry point to the user's program * * @return 0 for successful termination, else there was an error. */ int monotron_main(void); /** * Write a single character to the screen at the current cursor position. * * @param ch the character to write. * @return TODO Not sure what this returns */ int putchar(int ch); /** * Write a connected sixel to the screen. Assumes you have the Teletext font selected. * * @param ch the numeric value of the sixel to write (0..63) */ void put_connected_sixel(uint8_t ch); /** * Write a separated sixel to the screen. Assumes you have the Teletext font selected. * * @param ch the numeric value of the sixel to write (0..63) */ void put_separated_sixel(uint8_t ch); /** * Write a null-terminated string to the screen at the current cursor position. * * @param s the null-terminated ASCII string to display * @return TODO Not sure what this returns */ int puts(const char* s); /** * Show/hide cursor * * @param visible If true, cursor is visible, else cursor is invisible */ void set_cursor_visible(bool enabled); /** * Get a key from the keyboard. Blocks if no keypress in buffer. * * @return the next buffered keypress. */ int getchar(void); /** * Wait until the screen has been drawn and we're in the vertical blanking interval */ void wfvbi(void); /** * Get a random number from 0 .. RAND_MAX * * @return the new random number */ int rand(void); /** * Seed the random number generator * * @param the seed value */ void srand(unsigned int seed); /** * Check if a key has been pressed. * * @return 1 if a key has been pressed (i.e. getchar() won't blocK), 0 otherwise */ int kbhit(void); /** * Set where the next character will appear on screen. * * @param row the Y-value to set (0..35) * @param col the X-value to set (0..47) */ void move_cursor(unsigned char row, unsigned char col); /** * Configure one channel of the synthesiser to continuously play a note. * * @param frequency the frequency of the note to play (in centi-hertz) * @param channel the channel to play the note on * @param waveform the waveform to play this note with * @param volume the volume to play this note at (0..255) */ int play(uint32_t frequency, channel_t channel, waveform_t waveform, uint8_t volume); /** * Switch to the CodePage 850 font */ void font_normal(void); /** * Switch to the Teletext font */ void font_teletext(void); /** * Set a custom font. Supply 4096 bytes of font data (16 bytes per char, 256 * chars) * * @param p_font pointer to 4 KiB of font data */ void font_custom(const void* p_font); /** * Capture current joystick state. * @return captured state */ uint8_t get_joystick(void); /** * Check if the Joystick was pressed up when the given state was captured. * @return true if up was pressed, else false. */ bool joystick_is_up(uint8_t state); /** * Check if the Joystick was pressed down when the given state was captured. * @return true if down was pressed, else false. */ bool joystick_is_down(uint8_t state); /** * Check if the Joystick was pressed left when the given state was captured. * @return true if down was pressed, else false. */ bool joystick_is_left(uint8_t state); /** * Check if the Joystick was pressed right when the given state was captured. * @return true if down was pressed, else false. */ bool joystick_is_right(uint8_t state); /** * Check if the Joystick fire button was pressed when the given state was * captured. * @return true if button is pressed, else false. */ bool joystick_fire_pressed(uint8_t state); /****************************************************************************** * * End of File * *****************************************************************************/