Improve menu-test, add lib/button abstraction
This commit is contained in:
parent
f117b2c5c8
commit
74966f7877
4
Makefile
4
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
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
#include <sparrow3d.h>
|
||||
#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;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#include <sparrow3d.h>
|
||||
|
||||
int buttonSteps[20];
|
||||
|
||||
int getButton ( int, Uint32 );
|
||||
int getButtonLim ( int, Uint32, Uint32, Uint32, int, int, int );
|
12
lib/font.c
12
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] );
|
||||
|
|
|
@ -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 );
|
||||
|
|
71
lib/menu.c
71
lib/menu.c
|
@ -1,5 +1,6 @@
|
|||
#include <sparrow3d.h>
|
||||
#include <string.h>
|
||||
#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) );
|
||||
|
|
30
lib/menu.h
30
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* );
|
||||
|
|
|
@ -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] );
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Reference in New Issue