/** * projectM -- Milkdrop-esque visualisation SDK * Copyright (C)2003-2004 projectM Team * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * See 'LICENSE.txt' included within this release * */ #include #include #include #include "projectM.h" #ifdef MACOS #include #else #include #endif /** MACOS */ #include "common.h" #include "fatal.h" #include "Param.h" #include "SplayTree.hpp" #include "InitCond.hpp" #include "glConsole.h" #include "Preset.hpp" #include "editor.h" #include "menu.h" #include "wipemalloc.h" #define HIGHLIGHT_COLOR 1 #define DEFAULT_COLOR 0 #define LOCKED_COLOR 2 #if 0 extern Preset *activePreset; extern interface_t current_interface; menu_t * load_waveform_menu(); menu_t * load_augmentations_menu(); menu_t * load_postprocessing_menu(); menu_t * load_motion_menu(); int load_main_menu(); int edit_per_frame_init(); int edit_per_frame_eqn(); int edit_per_pixel_eqn(); int run_bash_shell(); int print_menu_item(menu_item_t * menu_item); int switch_bool_param(Param * param); int adj_float_param(Param * param, adj_t adj); int adj_int_param(Param * param, adj_t adj); int pursue_menu_link(menu_link_t * menu_link); int append_menu_item(menu_t * menu, menu_item_t * new_menu_item); menu_t * new_menu(menu_t * top_menu); menu_item_t * new_menu_item(int menu_entry_type, menu_entry_t * menu_entry); menu_entry_t * new_menu_link(char * print_string, menu_t * menu_ptr); menu_entry_t * new_param_adj(char * print_string, Param * param); menu_entry_t * new_function_mode(char * print_string, int (*func_ptr)()); int free_menu_entry(menu_entry_t * menu_entry); int free_menu_item(menu_item_t * menu_item); int free_menu(menu_t * menu); int menu_lprint(char * string, int col); int init_main_menu(); int destroy_main_menu(); int width, height; float xmin,ymin,xmax,ymax; CValue saved_init_val; /* backups the value of an initial condition */ menu_t * main_menu = NULL; /* Global menu structure */ menu_t * active_menu = NULL; /* the currently loaded menu */ gl_console_t * menu_console = NULL; display_state menu_display_state = HIDE; int initMenu() { if (MENU_DEBUG) { printf("initMenu: loading menu:"); fflush(stdout); } load_main_menu(); if (MENU_DEBUG) printf(" [done]\n"); active_menu = main_menu; return PROJECTM_SUCCESS; } int showMenu() { if ((menu_console = glConsoleCreate(80,24, 81, 25, width*.05, height * .90,0)) == NULL) return PROJECTM_FAILURE; glConsoleSetFlags(CONSOLE_FLAG_CURSOR_HIDDEN|CONSOLE_FLAG_SCROLL_WRAP_DOWN|CONSOLE_FLAG_SCROLL_WRAP_RIGHT, menu_console); active_menu = main_menu; main_menu->start_item = main_menu->selected_item; menu_display_state = SHOW; return PROJECTM_SUCCESS; } int hideMenu() { menu_display_state = HIDE; active_menu = main_menu; active_menu->selected_item = active_menu->start_item; if (active_menu->locked_item != NULL) { // if (active_menu->locked_item->menu_entry_type == PARAM_ADJ_TYPE) // active_menu->locked_item->menu_entry->param_adj.param->init_val = saved_init_val; active_menu->locked_item = NULL; } glConsoleDestroy(menu_console); menu_console = NULL; return PROJECTM_SUCCESS; } int load_main_menu() { menu_t * waveform_menu; menu_t * augmentations_menu; menu_t * motion_menu; menu_t * postprocessing_menu; if ((main_menu = new_menu(NULL)) == NULL) return PROJECTM_OUTOFMEM_ERROR; if (MENU_DEBUG) { printf(" [waveform:"); fflush(stdout); } waveform_menu = load_waveform_menu(); if (waveform_menu == NULL) { free_menu(main_menu); if (MENU_DEBUG) { printf(" failure]\n"); fflush(stdout); } return PROJECTM_FAILURE; } if (MENU_DEBUG) { printf(" success]"); fflush(stdout); } if (MENU_DEBUG) { printf(" [augmentations:"); fflush(stdout); } augmentations_menu = load_augmentations_menu(); if (augmentations_menu == NULL) { free_menu(main_menu); free_menu(waveform_menu); if (MENU_DEBUG) { printf(" failure]\n"); fflush(stdout); } return PROJECTM_FAILURE; } if (MENU_DEBUG) { printf(" success]"); fflush(stdout); } if (MENU_DEBUG) { printf(" [postprocessing:"); fflush(stdout); } postprocessing_menu = load_postprocessing_menu(); if (postprocessing_menu == NULL) { free_menu(main_menu); free_menu(waveform_menu); free_menu(augmentations_menu); if (MENU_DEBUG) { printf(" failure]\n"); fflush(stdout); } return PROJECTM_FAILURE; } if (MENU_DEBUG) { printf(" success]"); fflush(stdout); } if (MENU_DEBUG) { printf(" [motion:"); fflush(stdout); } motion_menu = load_motion_menu(); if (motion_menu == NULL) { free_menu(main_menu); free_menu(waveform_menu); free_menu(augmentations_menu); free_menu(postprocessing_menu); if (MENU_DEBUG) { printf(" failure]\n"); fflush(stdout); } return PROJECTM_FAILURE; } if (MENU_DEBUG) { printf(" success]"); fflush(stdout); } append_menu_item(main_menu, new_menu_item(MENU_LINK_TYPE, new_menu_link("--waveform", waveform_menu))); append_menu_item(main_menu, new_menu_item(MENU_LINK_TYPE, new_menu_link("--augmentations", augmentations_menu))); append_menu_item(main_menu, new_menu_item(MENU_LINK_TYPE, new_menu_link("--motion", motion_menu))); append_menu_item(main_menu, new_menu_item(MENU_LINK_TYPE, new_menu_link("--post processing, global effects", postprocessing_menu))); append_menu_item(main_menu, new_menu_item(FUNCTION_MODE_TYPE, new_function_mode("edit per_frame equations", edit_per_frame_eqn))); append_menu_item(main_menu, new_menu_item(FUNCTION_MODE_TYPE, new_function_mode("edit per_pixel equations", edit_per_pixel_eqn))); append_menu_item(main_menu, new_menu_item(FUNCTION_MODE_TYPE, new_function_mode("edit preset initialization code", edit_per_frame_init))); //append_menu_item(main_menu, new_menu_item(FUNCTION_MODE_TYPE, new_function_mode("bash shell", run_bash_shell))); main_menu->selected_item = main_menu->start_item; return PROJECTM_SUCCESS; } menu_t * load_waveform_menu() { menu_t * waveform_menu; if ((waveform_menu = new_menu(main_menu)) == NULL) return NULL; append_menu_item(waveform_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("wave type", Param::find_param("nWaveMode", activePreset, P_CREATE)))); append_menu_item(waveform_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("size", Param::find_param("fWaveScale", activePreset, P_CREATE)))); append_menu_item(waveform_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("smoothing", Param::find_param("fWaveSmoothing", activePreset, P_CREATE)))); append_menu_item(waveform_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("mystery parameter", Param::find_param("wave_mystery", activePreset, P_CREATE)))); append_menu_item(waveform_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("opacity", Param::find_param("fWaveAlpha", activePreset, P_CREATE)))); append_menu_item(waveform_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("position (x)", Param::find_param("wave_x", activePreset, P_CREATE)))); append_menu_item(waveform_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("position (y)", Param::find_param("wave_y", activePreset, P_CREATE)))); append_menu_item(waveform_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("color (red)", Param::find_param("wave_r", activePreset, P_CREATE)))); append_menu_item(waveform_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("color (green)", Param::find_param("wave_g", activePreset, P_CREATE)))); append_menu_item(waveform_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("color (blue)", Param::find_param("wave_b", activePreset, P_CREATE)))); append_menu_item(waveform_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("use dots", Param::find_param("bWaveDots", activePreset, P_CREATE)))); append_menu_item(waveform_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("draw thick", Param::find_param("bWaveThick", activePreset, P_CREATE)))); append_menu_item(waveform_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("modulate opacity by volume", Param::find_param("bModWaveAlphaByVolume", activePreset, P_CREATE)))); append_menu_item(waveform_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("mod. lower threshold", Param::find_param("fModWaveAlphaStart", activePreset, P_CREATE)))); append_menu_item(waveform_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("mod. uppper threshold", Param::find_param("fModWaveAlphaEnd", activePreset, P_CREATE)))); append_menu_item(waveform_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("additive drawing", Param::find_param("bAdditiveWaves", activePreset, P_CREATE)))); append_menu_item(waveform_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("color brightening", Param::find_param("bMaximizeWaveColor", activePreset, P_CREATE)))); waveform_menu->selected_item = waveform_menu->start_item; return waveform_menu; } menu_t * load_augmentations_menu() { menu_t * augmentations_menu; if ((augmentations_menu = new_menu(main_menu)) == NULL) return NULL; append_menu_item(augmentations_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("outer border thickness", Param::find_param("ob_size", activePreset, P_CREATE)))); append_menu_item(augmentations_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj(" color (red)", Param::find_param("ob_r", activePreset, P_CREATE)))); append_menu_item(augmentations_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj(" color (green)", Param::find_param("ob_g", activePreset, P_CREATE)))); append_menu_item(augmentations_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj(" color (blue)", Param::find_param("ob_b", activePreset, P_CREATE)))); append_menu_item(augmentations_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj(" opacity", Param::find_param("ob_a", activePreset, P_CREATE)))); append_menu_item(augmentations_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("inner border thickness", Param::find_param("ib_size", activePreset, P_CREATE)))); append_menu_item(augmentations_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj(" color (red)", Param::find_param("ib_r", activePreset, P_CREATE)))); append_menu_item(augmentations_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj(" color (green)", Param::find_param("ib_g", activePreset, P_CREATE)))); append_menu_item(augmentations_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj(" color (blue)", Param::find_param("ib_b", activePreset, P_CREATE)))); append_menu_item(augmentations_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj(" opacity", Param::find_param("ib_a", activePreset, P_CREATE)))); append_menu_item(augmentations_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("motion vector opacity", Param::find_param("mv_a", activePreset, P_CREATE)))); append_menu_item(augmentations_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("num. mot. vector (X)", Param::find_param("mv_x", activePreset, P_CREATE)))); append_menu_item(augmentations_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("num. mot. vector (Y)", Param::find_param("mv_y", activePreset, P_CREATE)))); append_menu_item(augmentations_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("offset (X)", Param::find_param("mv_dx", activePreset, P_CREATE)))); append_menu_item(augmentations_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("offset (Y)", Param::find_param("mv_dy", activePreset, P_CREATE)))); append_menu_item(augmentations_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("trail length", Param::find_param("mv_l", activePreset, P_CREATE)))); append_menu_item(augmentations_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("color (red)", Param::find_param("mv_r", activePreset, P_CREATE)))); append_menu_item(augmentations_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("color (green)", Param::find_param("mv_g", activePreset, P_CREATE)))); append_menu_item(augmentations_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("color (blue)", Param::find_param("mv_b", activePreset, P_CREATE)))); augmentations_menu->selected_item = augmentations_menu->start_item; return augmentations_menu; } /* Loads the motion menu, a sub menu of the main menu */ menu_t * load_motion_menu() { menu_t * motion_menu; if ((motion_menu = new_menu(main_menu)) == NULL) return NULL; append_menu_item(motion_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("zoom amount", Param::find_param("zoom", activePreset, P_CREATE)))); append_menu_item(motion_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("zoom exponent", Param::find_param("zoomexp", activePreset, P_CREATE)))); append_menu_item(motion_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("rotation amount", Param::find_param("rot", activePreset, P_CREATE)))); append_menu_item(motion_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("rot., center of (X)", Param::find_param("cx", activePreset, P_CREATE)))); append_menu_item(motion_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("rot., center of (Y)", Param::find_param("cy", activePreset, P_CREATE)))); append_menu_item(motion_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("translation (X)", Param::find_param("dx", activePreset, P_CREATE)))); append_menu_item(motion_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("translation (Y)", Param::find_param("dy", activePreset, P_CREATE)))); append_menu_item(motion_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("scaling (X)", Param::find_param("sx", activePreset, P_CREATE)))); append_menu_item(motion_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("scaling (Y)", Param::find_param("sy", activePreset, P_CREATE)))); motion_menu->selected_item = motion_menu->start_item; return motion_menu; } /* Loads the post processing menu, a sub menu of the main, menu */ menu_t * load_postprocessing_menu() { menu_t * postprocessing_menu; if ((postprocessing_menu = new_menu(main_menu)) == NULL) return NULL; append_menu_item(postprocessing_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("sustain level", Param::find_param("fDecay", activePreset, P_CREATE)))); append_menu_item(postprocessing_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("darken center", Param::find_param("bDarkenCenter", activePreset, P_CREATE)))); append_menu_item(postprocessing_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("gamma adjustment", Param::find_param("fDecay", activePreset, P_CREATE)))); append_menu_item(postprocessing_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("video echo: alpha", Param::find_param("fVideoEchoAlpha", activePreset, P_CREATE)))); append_menu_item(postprocessing_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("video echo: scale", Param::find_param("fVideoEchoZoom", activePreset, P_CREATE)))); append_menu_item(postprocessing_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("video echo: orientation", Param::find_param("nVideoEchoOrientation", activePreset, P_CREATE)))); append_menu_item(postprocessing_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("texture wrapping", Param::find_param("bTexWrap", activePreset, P_CREATE)))); append_menu_item(postprocessing_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("darken filter", Param::find_param("bDarken", activePreset, P_CREATE)))); append_menu_item(postprocessing_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("brighten filter", Param::find_param("bBrighten", activePreset, P_CREATE)))); append_menu_item(postprocessing_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("solarize filter", Param::find_param("bSolarize", activePreset, P_CREATE)))); append_menu_item(postprocessing_menu, new_menu_item(PARAM_ADJ_TYPE, new_param_adj("invert filter", Param::find_param("bInvert", activePreset, P_CREATE)))); postprocessing_menu->selected_item = postprocessing_menu->start_item; return postprocessing_menu; } int refreshMenu() { menu_item_t * menu_item; if (menu_display_state == HIDE) { return PROJECTM_SUCCESS; } if (menu_display_state == SPECIAL) { glConsoleDraw(menu_console); glConsoleClearBuffer(menu_console); return PROJECTM_SUCCESS; } menu_item = active_menu->start_item; glConsoleClearBuffer(menu_console); while (menu_item) { print_menu_item(menu_item); menu_item = menu_item->down; } glConsoleDraw(menu_console); return PROJECTM_SUCCESS; } int destroyMenu() { if (main_menu != NULL) free_menu(main_menu); main_menu = NULL; return PROJECTM_SUCCESS; } /* Prints a line to the opengl screen, second entry is the color, work in progress */ int menu_lprint(char * string, int col) { if (active_menu == NULL) return PROJECTM_FAILURE; if (string == NULL) return PROJECTM_FAILURE; if (col == HIGHLIGHT_COLOR) { glConsoleSetBGColor(CONSOLE_WHITE, menu_console); glConsoleSetFGColor(CONSOLE_BLUE, menu_console); } else if (col == LOCKED_COLOR) { glConsoleSetBGColor(CONSOLE_WHITE, menu_console); glConsoleSetFGColor(CONSOLE_RED, menu_console); } else { glConsoleSetBGColor(CONSOLE_BLACK, menu_console); glConsoleSetFGColor(CONSOLE_WHITE, menu_console); } glConsolePrintString(string, menu_console); glConsolePrintString("\n", menu_console); return PROJECTM_SUCCESS; } int print_menu_item(menu_item_t * menu_item) { param_adj_t param_adj; char string[MAX_TOKEN_SIZE]; int col; InitCond * init_cond; if (menu_item == NULL) return PROJECTM_FAILURE; if (active_menu == NULL) return PROJECTM_FAILURE; if (active_menu->locked_item == menu_item) col = LOCKED_COLOR; else if (active_menu->selected_item == menu_item) col = HIGHLIGHT_COLOR; else col = DEFAULT_COLOR; switch (menu_item->menu_entry_type) { case PARAM_ADJ_TYPE: param_adj = menu_item->menu_entry->param_adj; switch(param_adj.param->type) { case P_TYPE_BOOL: if ((init_cond = projectM::activePreset->get_init_cond(param_adj.param)) == NULL) sprintf(string, "%s ?", param_adj.print_string); else if (init_cond->init_val.bool_val) sprintf(string, "%s [ON]", param_adj.print_string); else sprintf(string, "%s [OFF]", param_adj.print_string); break; case P_TYPE_INT: if ((init_cond = projectM::activePreset->get_init_cond(param_adj.param)) == NULL) sprintf(string, "%s ?", param_adj.print_string); else sprintf(string, "%s %d", param_adj.print_string, init_cond->init_val.int_val); break; case P_TYPE_DOUBLE: if ((init_cond = projectM::activePreset->get_init_cond(param_adj.param)) == NULL) sprintf(string, "%s ?", param_adj.print_string); else sprintf(string, "%s %f", param_adj.print_string, init_cond->init_val.float_val); break; default: /* unknown paramater type */ return PROJECTM_FAILURE; } return menu_lprint(string, col); case FUNCTION_MODE_TYPE: return menu_lprint(menu_item->menu_entry->function_mode.print_string, col); case MENU_LINK_TYPE: return menu_lprint(menu_item->menu_entry->menu_link.print_string, col); default: if (MENU_DEBUG) printf("print_menu_item: invalid menu entry type, val = %d\n", menu_item->menu_entry_type); return PROJECTM_FAILURE; } return PROJECTM_SUCCESS; } /* switchMenuState: changes to another menu item according to the passed direction */ int switchMenuState(dir_t dir) { menu_item_t * new_menu_item; param_adj_t param_adj; InitCond * init_cond; if (active_menu == NULL) return PROJECTM_FAILURE; /* Case on the direction of the key press */ switch (dir) { case PAGEUP: if(active_menu->locked_item != NULL) { if (active_menu->locked_item->menu_entry_type == PARAM_ADJ_TYPE) return adj_float_param(active_menu->locked_item->menu_entry->param_adj.param, BIG_INC); } /* Force to top of menu */ active_menu->selected_item = active_menu->start_item; return PROJECTM_SUCCESS; case PAGEDOWN: if(active_menu->locked_item != NULL) { if (active_menu->locked_item->menu_entry_type == PARAM_ADJ_TYPE) return adj_float_param(active_menu->locked_item->menu_entry->param_adj.param, BIG_DEC); } /* Force to bottom of menu */ while((new_menu_item = active_menu->selected_item->down) != NULL) active_menu->selected_item = new_menu_item; return PROJECTM_SUCCESS; case UP: if(active_menu->locked_item != NULL) { if (active_menu->locked_item->menu_entry_type == PARAM_ADJ_TYPE) return adj_float_param(active_menu->locked_item->menu_entry->param_adj.param, SMALL_INC); } /* Is this the first item of the menu ? */ if ((new_menu_item = active_menu->selected_item->up) == NULL) return PROJECTM_SUCCESS; active_menu->selected_item = new_menu_item; return PROJECTM_SUCCESS; case DOWN: if(active_menu->locked_item != NULL) { if (active_menu->locked_item->menu_entry_type == PARAM_ADJ_TYPE) return adj_float_param(active_menu->locked_item->menu_entry->param_adj.param, SMALL_DEC); } /* Is this the last item of the menu ? */ if ((new_menu_item = active_menu->selected_item->down) == NULL) return PROJECTM_SUCCESS; active_menu->selected_item = new_menu_item; return PROJECTM_SUCCESS; case LEFT: /* Left key unlocks the highlighted item */ if (active_menu->locked_item != NULL) { /* The left arrow cancels the initial condition adjustment */ if (active_menu->locked_item->menu_entry_type == PARAM_ADJ_TYPE) { //active_menu->locked_item->menu_entry->param_adj.param->init_val = saved_init_val; } active_menu->locked_item = NULL; return PROJECTM_SUCCESS; } /* Otherwise go up a menu if it isn't the top menu */ if (active_menu->top_menu == NULL) return PROJECTM_SUCCESS; active_menu = active_menu->top_menu; return PROJECTM_SUCCESS; case RIGHT: switch (active_menu->selected_item->menu_entry_type) { case MENU_LINK_TYPE: return pursue_menu_link(&active_menu->selected_item->menu_entry->menu_link); case PARAM_ADJ_TYPE: param_adj = active_menu->selected_item->menu_entry->param_adj; if (active_menu->locked_item == NULL) { if ((init_cond = projectM::activePreset->get_init_cond(param_adj.param)) == NULL) return PROJECTM_FAILURE; /* Save previous initial condition value */ //saved_init_val = init_cond->init_val; /* If a bool parameter, just switch its value and quit */ if (param_adj.param->type == P_TYPE_BOOL) { init_cond->init_val.bool_val = !init_cond->init_val.bool_val; return PROJECTM_SUCCESS; } /* Otherwise, lock this parameter so the user can adjust it */ active_menu->locked_item = active_menu->selected_item; } /* Unlock the item, but keep the changed initial value intact */ else { active_menu->locked_item = NULL; } break; case FUNCTION_MODE_TYPE: return active_menu->selected_item->menu_entry->function_mode.func_ptr(); default: return PROJECTM_FAILURE; } default: return PROJECTM_FAILURE; } return PROJECTM_SUCCESS; } /* Creates a new menu */ menu_t * new_menu(menu_t * top_menu) { menu_t * menu; if ((menu = (menu_t*)wipemalloc(sizeof(menu_t))) == NULL) return NULL; menu->top_menu = top_menu; menu->start_item = menu->selected_item = NULL; menu->locked_item = NULL; return menu; } /* Frees a menu */ int free_menu(menu_t * menu) { menu_item_t * menu_item, * backup; if (menu == NULL) return PROJECTM_SUCCESS; menu_item = menu->start_item; /* Now we free every entry in this menu */ while (menu_item) { backup = menu_item->down; /* If a menu link, free the sub menu it points to */ if (menu_item->menu_entry_type == MENU_LINK_TYPE) { free_menu(menu_item->menu_entry->menu_link.sub_menu); } /* Now free the menu item */ free_menu_item(menu_item); /* Set menu item to the next item in the list */ menu_item = backup; } /* Finally, we free the menu struct itself */ free(menu); menu = NULL; /* Finished, return success */ return PROJECTM_SUCCESS; } /* Creates a new menu link type */ menu_entry_t * new_menu_link(char * print_string, menu_t * menu_ptr) { menu_entry_t * menu_entry; menu_link_t menu_link; /* Argument Checks */ if (print_string == NULL) return NULL; if (menu_ptr == NULL) return NULL; /* Allocate memory for the menu entry */ if ((menu_entry = (menu_entry_t*)wipemalloc(sizeof(menu_entry_t))) == NULL) return NULL; /* Copy the string parameter */ memset(menu_link.print_string, 0, MAX_TOKEN_SIZE); strncpy(menu_link.print_string, print_string, MAX_TOKEN_SIZE); menu_link.sub_menu = menu_ptr; menu_entry->menu_link = menu_link; return menu_entry; } /* Creates a new parameter adjustment entry */ menu_entry_t * new_param_adj(char * print_string, Param * param) { menu_entry_t * menu_entry; param_adj_t param_adj; /* Argument Checks */ if (print_string == NULL) return NULL; if (param == NULL) { if (MENU_DEBUG) printf("new_param_adj: passed a null parameter!\n"); return NULL; } /* Allocate memory for the menu entry */ if ((menu_entry = (menu_entry_t*)wipemalloc(sizeof(menu_entry_t))) == NULL) return NULL; /* Copy the string parameter */ memset(param_adj.print_string, 0, MAX_TOKEN_SIZE); strncpy(param_adj.print_string, print_string, MAX_TOKEN_SIZE); param_adj.param = param; menu_entry->param_adj = param_adj; return menu_entry; } /* Appends a menu item */ int append_menu_item(menu_t * menu, menu_item_t * new_menu_item) { menu_item_t * menu_item; /* Argument checks */ if (menu == NULL) return PROJECTM_FAILURE; if (new_menu_item == NULL) return PROJECTM_FAILURE; /* Menu is empty, insert here */ if (menu->start_item == NULL) { menu->start_item = new_menu_item; new_menu_item->up = NULL; return PROJECTM_SUCCESS; } menu_item = menu->start_item; /* Traverse down the menu */ while (menu_item->down) { menu_item = menu_item->down; } /* Insert the item at the end */ menu_item->down = new_menu_item; new_menu_item->up = menu_item; return PROJECTM_SUCCESS; } /* Creates a new menu item, up and down entries are null by default */ menu_item_t * new_menu_item(int menu_entry_type, menu_entry_t * menu_entry) { menu_item_t * menu_item; /* Argument check */ if (menu_entry == NULL) return NULL; /* Out of memory check */ if ((menu_item = (menu_item_t*)wipemalloc(sizeof(menu_item_t))) == NULL) { return NULL; } menu_item->menu_entry_type = menu_entry_type; menu_item->menu_entry = menu_entry; menu_item->up = NULL; menu_item->down = NULL; return menu_item; } /* Frees a menu item */ int free_menu_item(menu_item_t * menu_item) { if (menu_item == NULL) return PROJECTM_OK; free(menu_item->menu_entry); free(menu_item); menu_item = NULL; return PROJECTM_SUCCESS; } /* Creates a new editor mode */ menu_entry_t * new_function_mode(char * print_string, int (*func_ptr)()) { menu_entry_t * menu_entry; function_mode_t function_mode; /* Argument Checks */ if (print_string == NULL) return NULL; /* Allocate memory for the menu entry */ if ((menu_entry = (menu_entry_t*)wipemalloc(sizeof(menu_entry_t))) == NULL) return NULL; /* Copy the string parameter */ memset(function_mode.print_string, 0, MAX_TOKEN_SIZE); strncpy(function_mode.print_string, print_string, MAX_TOKEN_SIZE); function_mode.func_ptr = func_ptr; menu_entry->function_mode = function_mode; return menu_entry; } /* Pursues a link in a menu */ int pursue_menu_link(menu_link_t * menu_link) { if (menu_link == NULL) return PROJECTM_FAILURE; active_menu = menu_link->sub_menu; return PROJECTM_SUCCESS; } int edit_per_pixel_eqn() { hideMenu(); current_interface = EDITOR_INTERFACE; // loadEditor(activePreset->per_pixel_eqn_string_buffer,(void (*)()) reloadPerPixel, 80, 24, 140, 60, 0, 0); return PROJECTM_SUCCESS; } int edit_per_frame_eqn() { hideMenu(); current_interface = EDITOR_INTERFACE; // loadEditor(activePreset->per_frame_eqn_string_buffer, (void (*)())reloadPerFrame,80,24,140,60,0,0); return PROJECTM_SUCCESS; } int edit_per_frame_init() { hideMenu(); current_interface = EDITOR_INTERFACE; // loadEditor(activePreset->per_frame_init_eqn_string_buffer,(void (*)()) reloadPerFrameInit,80,24,140,60,0,0); return PROJECTM_SUCCESS; } int run_bash_shell() { printf("setting menu state to special\n"); menu_display_state = SPECIAL; // glConsoleStartShell(menu_console); //menu_display_state = SHOW; return PROJECTM_SUCCESS; } /* Adjust a float parameter */ int adj_float_param(Param * param, adj_t adj) { float inc_val; InitCond * init_cond = NULL; if (param == NULL) return PROJECTM_FAILURE; if (param->type == P_TYPE_INT) return (adj_int_param(param, adj)); if ((init_cond = (InitCond*)projectM::activePreset->init_cond_tree->splay_find(param->name)) == NULL) return PROJECTM_FAILURE; switch (adj) { case VERY_SMALL_INC: inc_val = .001; break; case SMALL_INC: inc_val = .01; break; case BIG_INC: inc_val = .1; break; case VERY_BIG_INC: inc_val = 1.0; break; case VERY_SMALL_DEC: inc_val = -.001; break; case SMALL_DEC: inc_val = -.01; break; case BIG_DEC: inc_val = -0.1; break; case VERY_BIG_DEC: inc_val = -1.0; break; default: return PROJECTM_FAILURE; } /* Beyond upper bounds, normalize to maximum value */ if ((init_cond->init_val.float_val + inc_val) > param->upper_bound.float_val) init_cond->init_val.float_val = param->upper_bound.float_val; else if ((init_cond->init_val.float_val + inc_val) < param->lower_bound.float_val) init_cond->init_val.float_val = param->lower_bound.float_val; else init_cond->init_val.float_val += inc_val; return PROJECTM_SUCCESS; } /* Adjust an integer parameter */ int adj_int_param(Param * param, adj_t adj) { int inc_val; InitCond * init_cond = NULL; if (param == NULL) return PROJECTM_FAILURE; if ((init_cond = (InitCond*)activePreset->init_cond_tree->splay_find(param->name)) == NULL) return PROJECTM_FAILURE; switch (adj) { case VERY_SMALL_INC: inc_val = 1; break; case SMALL_INC: inc_val = 1; break; case BIG_INC: inc_val = 1; break; case VERY_BIG_INC: inc_val = 5; break; case VERY_SMALL_DEC: inc_val = -1; break; case SMALL_DEC: inc_val = -1; break; case BIG_DEC: inc_val = -1; break; case VERY_BIG_DEC: inc_val = -5; break; default: return PROJECTM_FAILURE; } /* Beyond upper bounds, normalize to maximum value */ if ((init_cond->init_val.int_val + inc_val) > param->upper_bound.int_val) init_cond->init_val.int_val = param->upper_bound.int_val; /* Below lower bounds, normalize to lowest value */ else if ((init_cond->init_val.int_val + inc_val) < param->lower_bound.int_val) init_cond->init_val.int_val = param->lower_bound.int_val; else init_cond->init_val.int_val += inc_val; return PROJECTM_SUCCESS; } void menu_key_handler( projectMEvent event, projectMKeycode key ) { switch( event ) { case PROJECTM_KEYDOWN: switch(key) { case PROJECTM_K_f: if (projectM::currentEngine->fullscreen==1) {projectM::currentEngine->renderer->reset(projectM::currentEngine->wvw,projectM::currentEngine->wvh); projectM::currentEngine->fullscreen=0;} else{projectM::currentEngine->renderer->reset(projectM::currentEngine->fvw,projectM::currentEngine->fvh); projectM::currentEngine->fullscreen=1; } // init_display(projectM::currentEngine->vw,projectM::currentEngine->vh,projectM::currentEngine->fullscreen); break; case PROJECTM_K_n: //projectM::currentEngine->switchPreset(ALPHA_NEXT, HARD_CUT); break; case PROJECTM_K_r: //projectM::currentEngine->switchPreset(RANDOM_NEXT, HARD_CUT); break; case PROJECTM_K_p: //projectM::currentEngine->switchPreset(ALPHA_PREVIOUS, HARD_CUT); break; case PROJECTM_K_a: break; case PROJECTM_K_z: break; case PROJECTM_K_0: //nWaveMode=0; break; case PROJECTM_K_6: //nWaveMode=6; break; case PROJECTM_K_7: //nWaveMode=7; break; case PROJECTM_K_UP: switchMenuState(UP); break; case PROJECTM_K_RETURN: case PROJECTM_K_RIGHT: switchMenuState(RIGHT); break; case PROJECTM_K_LEFT: switchMenuState(LEFT); break; case PROJECTM_K_DOWN: switchMenuState(DOWN); break; case PROJECTM_K_PAGEUP: switchMenuState(PAGEUP); break; case PROJECTM_K_PAGEDOWN: switchMenuState(PAGEDOWN); break; case PROJECTM_K_ESCAPE: case PROJECTM_K_m: hideMenu(); current_interface = DEFAULT_INTERFACE; break; case PROJECTM_K_t: break; default: break; } } } #endif