diff --git a/Makefile b/Makefile index aa03f38..aa470a2 100644 --- a/Makefile +++ b/Makefile @@ -3,8 +3,8 @@ # multiple-targets like sparrow3D! # whoops. -SRC = lib/font.c lib/sound.c lib/menu.c -OBJ = font.o sound.o menu.o +SRC = lib/button.c lib/font.c lib/sound.c lib/menu.c +OBJ = button.o font.o sound.o menu.o DEP = $(SRC:.c=.d) DYNAMIC = -lSDL_ttf -lSDL_mixer -lSDL_image -lSDL -lm diff --git a/lib/button.c b/lib/button.c new file mode 100644 index 0000000..855fd11 --- /dev/null +++ b/lib/button.c @@ -0,0 +1,53 @@ +#include +#include "button.h" + +int buttonSteps[20] = { 0 }; +// incrementing each spGetInput()->button[] would be sick but they overflow +// too quick + +// will return the amount of steps a button has been held down consecutively +// if unpressed, returns 0. +int +getButton ( int button, Uint32 steps ) +{ + if ( spGetInput()->button[button] ) { + if ( buttonSteps[button] == 0 ) + buttonSteps[button]++; + else + buttonSteps[button] += steps; + return buttonSteps[button]; + } + else + buttonSteps[button] = 0; + return 0; +} + +// acts like getButton, except it returns 0 (unpressed) if the consective steps +// the button has been held down for isn't within the given range. +// can also reset the button's step counter after it meets the range, or +// completely disable the current button-press after it meets the range. +// pass -1 as min_steps or max_steps to disable that part of the range-check. +// pass 0 as disable/reset to disable resetting/disabling, 1 to enable. +// I recommend 1,0,1 for init_no_min,disable,reset +int +getButtonLim +( int button, Uint32 steps, Uint32 min_steps, Uint32 max_steps, int init_no_min, + int disable, int reset ) +{ + int b_steps = getButton( button, steps ); + int range_pass = 0; + + if ( (min_steps < b_steps && (b_steps < max_steps || max_steps == -1)) ) + range_pass = 1; + if ( init_no_min && b_steps ==1 ) + range_pass = 1; + + if ( disable && range_pass ) + spGetInput()->button[button] = 0; + if ( (reset || disable) && range_pass ) + buttonSteps[button] = 1; + + if ( range_pass ) + return b_steps; + return 0; +} diff --git a/lib/button.h b/lib/button.h new file mode 100644 index 0000000..7f4b51f --- /dev/null +++ b/lib/button.h @@ -0,0 +1,6 @@ +#include + +int buttonSteps[20]; + +int getButton ( int, Uint32 ); +int getButtonLim ( int, Uint32, Uint32, Uint32, int, int, int ); diff --git a/lib/font.c b/lib/font.c index e702693..c027f1b 100644 --- a/lib/font.c +++ b/lib/font.c @@ -10,26 +10,26 @@ char fontPaths[10][512]; // ============================================================================ // add a TTF font at given path to the global `font` array void -add_font ( char ttf_path[512] ) +addFont ( char ttf_path[512] ) { strcpy(fontPaths[fontCount], ttf_path); fontCount++; - resize_fonts(); + resizeFonts(); } // ============================================================================ // resizes/updates all fonts; should be run whenever window resizes void -resize_fonts ( void ) +resizeFonts ( void ) { for ( int i = 0; i < fontCount; i++ ) { - resize_font(&fonts[i], fontPaths[i]); + resizeFont(&fonts[i], fontPaths[i]); } } // resizes/updates a given font void -resize_font ( spFontPointer* font, char ttf_path[512] ) +resizeFont ( spFontPointer* font, char ttf_path[512] ) { spFontShadeButtons(1); @@ -54,7 +54,7 @@ resize_font ( spFontPointer* font, char ttf_path[512] ) // ============================================================================ // cleans up all fonts in global array `fonts` void -cleanup_fonts ( void ) +cleanupFonts ( void ) { for ( int i = 0; i < fontCount; i++ ) { spFontDelete( fonts[i] ); diff --git a/lib/font.h b/lib/font.h index 45a7c5b..13463c2 100644 --- a/lib/font.h +++ b/lib/font.h @@ -5,9 +5,9 @@ spFontPointer fonts[10]; char fontPaths[10][512]; -void add_font ( char ttf_path[512] ); +void addFont ( char ttf_path[512] ); -void resize_fonts ( void ); -void resize_font ( spFontPointer*, char[512] ); +void resizeFonts ( void ); +void resizeFont ( spFontPointer*, char[512] ); -void cleanup_fonts ( void ); +void cleanupFonts ( void ); diff --git a/lib/menu.c b/lib/menu.c index 3ca0100..2b3d258 100644 --- a/lib/menu.c +++ b/lib/menu.c @@ -1,5 +1,6 @@ #include #include +#include "button.h" #include "menu.h" // ============================================================================ @@ -7,7 +8,7 @@ // ============================================================================ // init a menu with the given title text. void -init_menu +initMenu ( struct eMenu* menu, char title[512], spFontPointer* titleFont, spFontPointer* elementFont, int menuBackgroundColor, int selectBackgroundColor ) @@ -26,6 +27,12 @@ init_menu menu->selection = 0; menu->elementCount = 0; + menu->inputDelayStep = 100; + menu->inputCutoffStep = -1; + menu->inputImmediate = 1; + menu->inputDisable = 0; + menu->inputReset = 1; + menu->menuBgColor = menuBackgroundColor; menu->selectBgColor = selectBackgroundColor; @@ -36,7 +43,7 @@ init_menu // init the given eMenuElement with the given text in an eMenu. void -init_menu_element +initMenuElement ( struct eMenu* menu, struct eMenuElement* element, char text[512] ) { int count = menu->elementCount; @@ -50,22 +57,22 @@ init_menu_element // create a new eMenuElement with given text, and append to eMenu. void -add_menu_element +addMenuElement ( struct eMenu* menu, char text[512] ) { struct eMenuElement* element = malloc(sizeof(struct eMenuElement)); - init_menu_element( menu, element, text ); + initMenuElement( menu, element, text ); } // ------------------------------------------------------------------- // resize a menu (executed by resize loop) void -resize_menu ( struct eMenu* menu ) +resizeMenu ( struct eMenu* menu ) { if ( menu->height == 0 ) - menu->height = ideal_menu_height(menu); + menu->height = idealMenuHeight(menu); if ( menu->width == 0 ) - menu->width = ideal_menu_width(menu); + menu->width = idealMenuWidth(menu); menu->scaleFactor = spFixedToInt(spGetSizeFactor()); int height = menu->height * menu->scaleFactor; @@ -84,19 +91,20 @@ resize_menu ( struct eMenu* menu ) // ============================================================================ // draw an eMenu on it's surface. void -draw_menu ( SDL_Surface* surface, struct eMenu* menu ) +drawMenu ( SDL_Surface* surface, struct eMenu* menu ) { SDL_Surface* old_surface = spGetRenderTarget( ); spSelectRenderTarget( menu->surface ); spClearTarget( menu->menuBgColor ); if ( menu->textCentered == 0 ) - spFontDrawMiddle ( menu->width / 2 * menu->scaleFactor,0,0, menu->title, *(menu->font) ); + spFontDrawMiddle( menu->width / 2 * menu->scaleFactor,0,0, + menu->title, *(menu->font) ); else - spFontDraw ( 0,0,0, menu->title, *(menu->font) ); + spFontDraw( 0,0,0, menu->title, *(menu->font) ); for ( int i=0; i < menu->elementCount; i++ ) { - draw_menu_element( menu->elements[i]); + drawMenuElement( menu->elements[i]); } spSelectRenderTarget( old_surface ); @@ -104,7 +112,7 @@ draw_menu ( SDL_Surface* surface, struct eMenu* menu ) // draw an eMenuElement on current target surface void -draw_menu_element ( struct eMenuElement* element ) +drawMenuElement ( struct eMenuElement* element ) { struct eMenu* parent = element->parentMenu; int index = element->index; @@ -123,11 +131,12 @@ draw_menu_element ( struct eMenuElement* element ) else index++; if ( parent->textCentered == 0 ) - spFontDrawMiddle(parent->width / 2 * parent->scaleFactor,index * fontHeight,0, - element->text, *(parent->elementFont)); + spFontDrawMiddle( parent->width / 2 * parent->scaleFactor, + index * fontHeight,0, + element->text, *(parent->elementFont)); else - spFontDraw(20,index * fontHeight,0, - element->text, *(parent->elementFont)); + spFontDraw( 20,index * fontHeight,0, + element->text, *(parent->elementFont)); } @@ -139,24 +148,28 @@ draw_menu_element ( struct eMenuElement* element ) // 0 if not buttons were pressed, // otherwise return the item selected + 1. int -calc_menu ( struct eMenu* menu, int sp_select_button ) +calcMenu ( struct eMenu* menu, int sp_select_button, Uint32 steps ) { - spSleep(50000); - if ( spGetInput()->button[sp_select_button] ) - return menu_select( menu ); - else if ( spGetInput()->button[SP_BUTTON_DOWN] ) - menu_select_down( menu ); - else if ( spGetInput()->button[SP_BUTTON_UP] ) - menu_select_up( menu ); + if ( getButton( sp_select_button, steps ) ) + return menuSelect( menu, steps ); + else if ( getButtonLim( SP_BUTTON_UP, steps, + menu->inputDelayStep,menu->inputCutoffStep, menu->inputImmediate, + menu->inputDisable, menu->inputReset ) ) + menuSelectUp( menu, steps ); + else if ( getButtonLim( SP_BUTTON_DOWN, steps, + menu->inputDelayStep,menu->inputCutoffStep, menu->inputImmediate, + menu->inputDisable, menu->inputReset ) ) + menuSelectDown( menu, steps ); else return CALCMENU_NOINPUT; return CALCMENU_MOVED; } + // ------------------------------------------------------------------- // returns selected menu item, and plays proper sound int -menu_select ( struct eMenu* menu ) +menuSelect ( struct eMenu* menu, Uint32 steps ) { if ( menu->moveSound != NULL ) spSoundPlay( menu->selectSound, menu->soundChannel,0,0,-1 ); @@ -165,7 +178,7 @@ menu_select ( struct eMenu* menu ) // move an eMenu's selected element up by one (if possible) void -menu_select_up ( struct eMenu* menu ) +menuSelectUp ( struct eMenu* menu, Uint32 steps ) { if ( 0 < menu->selection ) { menu->selection -= 1; @@ -176,7 +189,7 @@ menu_select_up ( struct eMenu* menu ) // move an eMenu's selected element down by one (if possible) void -menu_select_down ( struct eMenu* menu ) +menuSelectDown ( struct eMenu* menu, Uint32 steps ) { if ( (menu->elementCount - 1) > menu->selection ) { menu->selection += 1; @@ -191,7 +204,7 @@ menu_select_down ( struct eMenu* menu ) // ============================================================================ // return menu's ideal (smallest while displaying everything) calculated height int -ideal_menu_height ( struct eMenu* menu ) +idealMenuHeight ( struct eMenu* menu ) { spFontPointer font = *(menu->font); spFontPointer elementFont = *(menu->elementFont); @@ -203,7 +216,7 @@ ideal_menu_height ( struct eMenu* menu ) // return menu's ideal (smallest while displaying everything) calculated width int -ideal_menu_width ( struct eMenu* menu ) +idealMenuWidth ( struct eMenu* menu ) { struct eMenuElement* element; int top_len = spFontWidth( menu->title, *(menu->font) ); diff --git a/lib/menu.h b/lib/menu.h index 69375d1..a00389a 100644 --- a/lib/menu.h +++ b/lib/menu.h @@ -28,6 +28,12 @@ struct eMenu int titleCentered; int textCentered; + int inputDelayStep; + int inputCutoffStep; + int inputDisable; + int inputReset; + int inputImmediate; + int menuBgColor; int selectBgColor; @@ -42,21 +48,21 @@ struct eMenu }; -void init_menu ( struct eMenu*, char title[512], +void initMenu ( struct eMenu*, char title[512], spFontPointer*, spFontPointer*, int, int ); -void init_menu_element ( struct eMenu*, struct eMenuElement*, char[512] ); -void add_menu_element ( struct eMenu*, char[512] ); +void initMenuElement ( struct eMenu*, struct eMenuElement*, char[512] ); +void addMenuElement ( struct eMenu*, char[512] ); -void draw_menu ( SDL_Surface*, struct eMenu* ); -void draw_menu_element ( struct eMenuElement* ); +void drawMenu ( SDL_Surface*, struct eMenu* ); +void drawMenuElement ( struct eMenuElement* ); -int calc_menu ( struct eMenu*, int ); +int calcMenu ( struct eMenu*, int, Uint32 ); -void resize_menu ( struct eMenu* ); +void resizeMenu ( struct eMenu* ); -int menu_select ( struct eMenu* ); -void menu_select_up ( struct eMenu* ); -void menu_select_down ( struct eMenu* ); +int menuSelect ( struct eMenu*, Uint32 ); +void menuSelectUp ( struct eMenu*, Uint32 ); +void menuSelectDown ( struct eMenu*, Uint32 ); -int ideal_menu_height ( struct eMenu* ); -int ideal_menu_width ( struct eMenu* ); +int idealMenuHeight ( struct eMenu* ); +int idealMenuWidth ( struct eMenu* ); diff --git a/lib/sound.c b/lib/sound.c index e0e9f07..42db3db 100644 --- a/lib/sound.c +++ b/lib/sound.c @@ -7,7 +7,7 @@ spSound* sounds[10] = { NULL }; // add a sound to the global sounds array void -add_sound ( char soundpath[512] ) +addSound ( char soundpath[512] ) { sounds[soundCount] = spSoundLoad(soundpath); soundCount++; @@ -15,7 +15,7 @@ add_sound ( char soundpath[512] ) // cleanup all sounds void -cleanup_sounds ( void ) +cleanupSounds ( void ) { for ( int i = 0; i < soundCount; i++ ) { spSoundDelete( sounds[i] ); diff --git a/lib/sound.h b/lib/sound.h index af01df7..0a79ddb 100644 --- a/lib/sound.h +++ b/lib/sound.h @@ -3,5 +3,5 @@ int soundCount; spSound* sounds[10]; -void add_sound ( char[512] ); -void cleanup_sounds ( void ); +void addSound ( char[512] ); +void cleanupSounds ( void ); diff --git a/tests/test-menu.c b/tests/test-menu.c index d40817f..d6e5f5e 100644 --- a/tests/test-menu.c +++ b/tests/test-menu.c @@ -41,7 +41,7 @@ draw_test ( void ) spClearTarget( spGetRGB(64,64,64) ); spSelectRenderTarget(spGetWindowSurface()); - draw_menu ( testMenu->surface, testMenu ); + drawMenu ( testMenu->surface, testMenu ); spBlitSurface( spGetWindowSurface()->w/2, spGetWindowSurface()->h/2, 0, testMenu->surface ); @@ -50,25 +50,25 @@ draw_test ( void ) - fonts[FN_COZETTE]->maxheight * 2.5, 0, "Press [S] to select", fonts[FN_COZETTE] ); spFontDrawMiddle( spGetWindowSurface()->w/2, - spGetWindowSurface()->h + spGetWindowSurface()->h - fonts[FN_COZETTE]->maxheight -2, 0, "Press [E] to exit", fonts[FN_COZETTE] ); spFlip(); } // input for the menu test +// if non-zero return int, it's the index of the selected menu item + 1. int calc_test ( Uint32 steps ) { - int menucode = calc_menu ( testMenu, SP_BUTTON_START ); + int menucode = calcMenu( testMenu, SP_BUTTON_START, steps ); // no input? interpret keypress as our own - if ( menucode == CALCMENU_NOINPUT ) + if ( menucode == CALCMENU_NOINPUT ) { if ( spGetInput()->button[SP_BUTTON_SELECT] ) return -1; - else return 0; - - // greater than _moved means it returned the inc'd menu selection index + } + // greater than _MOVED means it returned the inc'd menu selection index if ( menucode > CALCMENU_MOVED ) spSleep(700000); // sleep long enough after selection to play selection sound lol @@ -78,9 +78,9 @@ calc_test ( Uint32 steps ) void resize ( Uint16 w, Uint16 h ) { - spSelectRenderTarget(spGetWindowSurface()); - resize_fonts(); - resize_menu(testMenu); + spSelectRenderTarget( spGetWindowSurface()); + resizeFonts(); + resizeMenu( testMenu ); } @@ -100,26 +100,26 @@ init ( void ) void init_test_menu ( struct eMenu* menu ) { - init_menu( menu, "what do you do? <3", - &fonts[FN_LOVEMECHAIN], &fonts[FN_COZETTE], - spGetRGB(80,80,80), spGetRGB(35,71,107) ); + initMenu( menu, "what do you do? <3", + &fonts[FN_LOVEMECHAIN], &fonts[FN_COZETTE], + spGetRGB(80,80,80), spGetRGB(35,71,107) ); menu->titleCentered = 0; menu->textCentered = 0; menu->moveSound = sounds[SF_TAMBORINE]; menu->selectSound = sounds[SF_EEUH]; - add_menu_element(menu, "give up"); - add_menu_element(menu, "run away"); - add_menu_element(menu, "eat a baby"); - add_menu_element(menu, "wave hello"); - add_menu_element(menu, "hug a stranger until they blush"); - add_menu_element(menu, "oh well"); + addMenuElement(menu, "give up"); + addMenuElement(menu, "run away"); + addMenuElement(menu, "eat a baby"); + addMenuElement(menu, "wave hello"); + addMenuElement(menu, "hug a stranger until they blush"); + addMenuElement(menu, "oh well"); } void init_fonts ( void ) { - add_font("data/font/cozette-vector.ttf"); - add_font("data/font/love_me_chain.ttf"); + addFont("data/font/cozette-vector.ttf"); + addFont("data/font/love_me_chain.ttf"); } void @@ -136,8 +136,8 @@ void init_sounds ( void ) { spSoundInit(); - add_sound("data/sound/tamborine.ogg"); - add_sound("data/sound/eeuh.ogg"); + addSound("data/sound/tamborine.ogg"); + addSound("data/sound/eeuh.ogg"); } @@ -147,8 +147,8 @@ init_sounds ( void ) int cleanup ( void ) { - cleanup_fonts(); - cleanup_sounds(); + cleanupFonts(); + cleanupSounds(); spDeleteSurface( menuSurface ); spQuitCore(); }