// // WeaponList -- Tells the hud about a new weapon type. // int CHudAmmo::MsgFunc_WeaponList(const char *pszName, int iSize, void *pbuf) { BEGIN_READ(pbuf, iSize); WEAPON Weapon; strcpy(Weapon.szName, READ_STRING()); Weapon.iAmmoType = (int)READ_CHAR(); Weapon.iMax1 = READ_BYTE(); if(Weapon.iMax1 == 255) Weapon.iMax1 = -1; Weapon.iAmmo2Type = READ_CHAR(); Weapon.iMax2 = READ_BYTE(); if(Weapon.iMax2 == 255) Weapon.iMax2 = -1; Weapon.iSlot = READ_CHAR(); Weapon.iSlotPos = READ_CHAR(); Weapon.iId = READ_CHAR(); Weapon.iFlags = READ_BYTE(); Weapon.iClip = 0; gWR.AddWeapon(&Weapon); return 1; }
static int load_constants(struct load_state *S, ktap_proto *f) { int i,n; n = READ_INT(S); f->sizek = n; f->k = NEW_VECTOR(S, n * sizeof(ktap_value)); for (i = 0; i < n; i++) setnilvalue(&f->k[i]); for (i=0; i < n; i++) { ktap_value *o = &f->k[i]; int t = READ_CHAR(S); switch (t) { case KTAP_TNIL: setnilvalue(o); break; case KTAP_TBOOLEAN: setbvalue(o, READ_CHAR(S)); break; case KTAP_TNUMBER: /* * todo: kernel not support fp, check double when * loading */ setnvalue(o, READ_NUMBER(S)); break; case KTAP_TSTRING: setsvalue(o, READ_STRING(S)); break; default: kp_error(S->ks, "ktap: load_constants: " "unknow ktap_value\n"); return -1; } } n = READ_INT(S); f->p = NEW_VECTOR(S, n * sizeof(ktap_proto)); f->sizep = n; for (i = 0; i < n; i++) f->p[i] = NULL; for (i = 0; i < n; i++) { f->p[i] = kp_newproto(S->ks); if (load_function(S, f->p[i])) return -1; } return 0; }
static inline bool extract_uint16(serial_context *ser_cont, uint16_t *value) { int32_t ch1 = READ_CHAR(ser_cont->fd, ser_cont->line_no, ser_cont->col_no, ser_cont->bytes); int32_t ch2 = READ_CHAR(ser_cont->fd, ser_cont->line_no, ser_cont->col_no, ser_cont->bytes); if (ch1 == EOF || ch2 == EOF) { err("Error while reading 16-bit value"); return false; } *value = (uint16_t)(ch1 << 8 | ch2); return true; }
char* READ_STRING( void ) { static char string[2048]; int l; char c; string[0] = 0; l = 0; do { if ( giRead+1 > giSize ) break; // no more characters c = static_cast<signed char>(READ_CHAR()); // Vit_amiN: we must cast it back: int -> signed char -> char if (c == STR_NETW_EOF_CHAR || c == '\0') break; string[l] = (c == STR_SUBS_EOF_CHAR) ? STR_NETW_EOF_CHAR : c; // Vit_amiN: substituting 0xFF chars back l++; } while (l < sizeof(string)-1); string[l] = 0; return string; }
Vector2 Font::MeasureString(const string& s, int w, int h, int flags){ int len = s.length(); int xx = 0; int yy = 0; vector<int> ws, cs; int wi = 0, c = 0; for (int i = 0; i<len;){ char_type cc; int rs = READ_CHAR(&cc, s.c_str() + i, len - i); if (rs>0) i += rs; else break; bool n = cc == L'\n' || cc == 0x0085 || cc == 0x2028 || cc == 0x2029; PutChar(cc); int ww = n ? 0 : map[cc]->width; if ((flags & FontFlag_NoWrap) == 0 && (n || (w >= 0 && wi + ww>w))){ if (c == 0){ ws.push_back(ww); cs.push_back(1); wi = 0; c = 0; } else{ ws.push_back(wi); cs.push_back(c); wi = ww; c = 1; if (n){ wi = 0; } } } else { wi += ww; c++; } } if (c > 0){ ws.push_back(wi); cs.push_back(c); } int max = 0; for (int i : ws){ if (i > max){ max = i; } } return Vector2(max, cs.size() * face->size->metrics.y_ppem); }
// Message handler for ShowMenu message // takes four values: // short: a bitfield of keys that are valid input // char : the duration, in seconds, the menu should stay up. -1 means is stays until something is chosen. // byte : a boolean, TRUE if there is more string yet to be received before displaying the menu, FALSE if it's the last string // string: menu string to display // if this message is never received, then scores will simply be the combined totals of the players. int CHudMenu :: MsgFunc_ShowMenu( const char *pszName, int iSize, void *pbuf ) { char *temp = NULL; BEGIN_READ( pszName, pbuf, iSize ); m_bitsValidSlots = READ_SHORT(); int DisplayTime = READ_CHAR(); int NeedMore = READ_BYTE(); if( DisplayTime > 0 ) m_flShutoffTime = DisplayTime + gHUD.m_flTime; else m_flShutoffTime = -1; if( m_bitsValidSlots ) { if( !m_fWaitingForMore ) { // this is the start of a new menu Q_strncpy( g_szPrelocalisedMenuString, READ_STRING(), MAX_MENU_STRING ); } else { // append to the current menu string Q_strncat( g_szPrelocalisedMenuString, READ_STRING(), MAX_MENU_STRING - Q_strlen( g_szPrelocalisedMenuString )); } g_szPrelocalisedMenuString[MAX_MENU_STRING-1] = 0; // ensure null termination (strncat/strncpy does not) if( !NeedMore ) { // we have the whole string, so we can localise it now Q_strcpy( g_szMenuString, gHUD.m_TextMessage.BufferedLocaliseTextString( g_szPrelocalisedMenuString )); // Swap in characters if( KB_ConvertString( g_szMenuString, &temp )) { Q_strcpy( g_szMenuString, temp ); free( temp ); } } m_fMenuDisplayed = 1; m_iFlags |= HUD_ACTIVE; } else { m_fMenuDisplayed = 0; // no valid slots means that the menu should be turned off m_iFlags &= ~HUD_ACTIVE; } m_fWaitingForMore = NeedMore; END_READ(); return 1; }
// // CurWeapon: Update hud state with the current weapon and clip count. Ammo // counts are updated with AmmoX. Server assures that the Weapon ammo type // numbers match a real ammo type. // int CHudAmmo::MsgFunc_CurWeapon(const char *pszName, int iSize, void *pbuf) { static wrect_t nullrc; int fOnTarget = FALSE; BEGIN_READ(pbuf, iSize); int iState = READ_BYTE(); int iId = READ_BYTE(); int iClip = READ_CHAR(); // detect if we're also on target if(iState > 1) { fOnTarget = TRUE; } if(iId < 1) { SetCrosshair(0, nullrc, 0, 0, 0); return 0; } // Is player dead??? if((iId == -1) && (iClip == -1)) { gHUD.m_fPlayerDead = TRUE; gpActiveSel = NULL; return 1; } gHUD.m_fPlayerDead = FALSE; WEAPON *pWeapon = gWR.GetWeapon(iId); if(!pWeapon) return 0; if(iClip < -1) pWeapon->iClip = abs(iClip); else pWeapon->iClip = iClip; if(iState == 0) // we're not the current weapon, so update no more return 1; m_pWeapon = pWeapon; m_fFade = 200.0f; //!!! m_iFlags |= HUD_ACTIVE; return 1; }
static void options_load_color_profiles(GQParserData *parser_data, GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer data, GError **error) { while (*attribute_names) { const gchar *option = *attribute_names++; const gchar *value = *attribute_values++; if (READ_BOOL(options->color_profile, enabled)) continue; if (READ_BOOL(options->color_profile, use_image)) continue; if (READ_INT(options->color_profile, input_type)) continue; if (READ_CHAR(options->color_profile, screen_file)) continue; if (READ_BOOL(options->color_profile, use_x11_screen_profile)) continue; log_printf("unknown attribute %s = %s\n", option, value); } }
bool GET_LIST_SIZE(serial_context *ser_cont, uint32_t *size) { int32_t type = READ_CHAR(ser_cont->fd, ser_cont->line_no, ser_cont->col_no, ser_cont->bytes); if (type == EOF) { err("Error while reading list type"); return false; } if (type == 0xdc) { uint16_t tmp; if (!extract_uint16(ser_cont, &tmp)) { err("Error while reading 16-bit list size"); return false; } *size = tmp; return true; } if (type == 0xdd) { uint32_t tmp; if (!extract_uint32(ser_cont, &tmp)) { err("Error while reading 32-bit list size"); return false; } *size = tmp; return true; } if ((type & 0xf0) == 0x90) { *size = type & 0x0f; return true; } err("Serialized value is not a list"); return false; }
char* READ_STRING( void ) { static char string[2048]; int l,c; string[0] = 0; l = 0; do { if ( giRead+1 > giSize ) break; // no more characters c = READ_CHAR(); if (c == -1 || c == 0) break; string[l] = c; l++; } while (l < sizeof(string)-1); string[l] = 0; return string; }
// // CurWeapon: Update hud state with the current weapon and clip count. Ammo // counts are updated with AmmoX. Server assures that the Weapon ammo type // numbers match a real ammo type. // int CHudAmmo::MsgFunc_CurWeapon(const char *pszName, int iSize, void *pbuf) { static wrect_t nullrc; int fOnTarget = FALSE; BEGIN_READ(pbuf, iSize); int iState = READ_BYTE(); int iId = READ_CHAR(); int iClip = READ_CHAR(); // detect if we're also on target if(iState > 1) { fOnTarget = TRUE; } if(iId < 1) { SetCrosshair(0, nullrc, 0, 0, 0); return 0; } // Is player dead??? if((iId == -1) && (iClip == -1)) { gHUD.m_fPlayerDead = TRUE; gpActiveSel = NULL; return 1; } gHUD.m_fPlayerDead = FALSE; WEAPON *pWeapon = gWR.GetWeapon(iId); if(!pWeapon) return 0; if(iClip < -1) pWeapon->iClip = abs(iClip); else pWeapon->iClip = iClip; if(iState == 0) // we're not the current weapon, so update no more return 1; m_pWeapon = pWeapon; if(!(gHUD.m_iHideHUDDisplay & (HIDEHUD_WEAPONS | HIDEHUD_ALL))) { if(gHUD.m_iFOV >= 90) { // normal crosshairs if(fOnTarget && m_pWeapon->hAutoaim) SetCrosshair(m_pWeapon->hAutoaim, m_pWeapon->rcAutoaim, 255, 255, 255); else SetCrosshair(m_pWeapon->hCrosshair, m_pWeapon->rcCrosshair, 255, 255, 255); } else { // zoomed crosshairs if(fOnTarget && m_pWeapon->hZoomedAutoaim) SetCrosshair(m_pWeapon->hZoomedAutoaim, m_pWeapon->rcZoomedAutoaim, 255, 255, 255); else SetCrosshair(m_pWeapon->hZoomedCrosshair, m_pWeapon->rcZoomedCrosshair, 255, 255, 255); } } m_fFade = 200.0f; //!!! m_iFlags |= HUD_ACTIVE; return 1; }
int CHudParticules::MsgFunc_ClientDecal( const char *pszName, int iSize, void *pbuf ) { BEGIN_READ( pbuf, iSize ); Vector vecSrc, vecNormal; char chTextureType; vecSrc.x = READ_COORD(); vecSrc.y = READ_COORD(); vecSrc.z = READ_COORD(); vecNormal.x = READ_COORD(); vecNormal.y = READ_COORD(); vecNormal.z = READ_COORD(); chTextureType = READ_CHAR(); int decal = READ_BYTE(); if ( decal == 4 ) // explo electro-roquette { AddDecal ( vecSrc, Vector ( 90,0,0 ), "sprites/rpg_disk.spr", gHUD.m_flTime + ELECTRO_DISK_MAX / ELECTRO_DISK_SPEED + 0.5, FLAG_DECAL_DISK ); return 1; } if ( decal == 5 ) // explo supergun { Vector angDir; VectorAngles ( -vecNormal, angDir ); angDir.y += 180; AddDecal ( vecSrc, angDir, "sprites/rpg_disk.spr", gHUD.m_flTime + 0.5, FLAG_DECAL_SG ); return 1; } if ( decal == 6 ) // muzzle outro { Vector vecDir = vecNormal, velocity (0,0,0), avelocity(0,0,0), src = vecSrc; float largeur, brightness; //gros for ( int j=0; j<4; j++ ) { avelocity = Vector (0.0f, 0.0f, gEngfuncs.pfnRandomFloat(30,60)* ((j%2)==0?1:-1) ); velocity = Vector (vecDir - vecSrc) * 0/*( 0.08 - j*0.02 )*/; largeur = 5; brightness = 0.3; AddParticule ( src, Vector (largeur,brightness,0.0f), velocity, avelocity , "sprites/outro_muzzle.spr", gHUD.m_flTime + 7, FLAG_PARTICULE_OUTRO1 ); } // petits for ( int i=0; i<10; i++ ) { brightness = 0.3; avelocity = Vector (0.0f, 0.0f, gEngfuncs.pfnRandomFloat(-300,300) ); // velocity = Vector (vecDir - vecSrc) * ( 0.3 - i*0.03 ) * 2.5; velocity = Vector (vecDir - vecSrc).Normalize() * 0.1; largeur = 1.2 + i*0.3; src = vecSrc + 0.1*(vecDir-vecSrc); AddParticule ( src, Vector (largeur,brightness,0.0f), velocity, avelocity, "sprites/outro_muzzle.spr", gHUD.m_flTime + 7, FLAG_PARTICULE_OUTRO2 ); } return 1; } EV_HLDM_EjectParticules ( vecSrc, vecNormal, chTextureType, decal, 1 ); return 1; }
static gboolean load_global_params(const gchar **attribute_names, const gchar **attribute_values) { while (*attribute_names) { const gchar *option = *attribute_names++; const gchar *value = *attribute_values++; /* General options */ if (READ_BOOL(*options, show_icon_names)) continue; if (READ_BOOL(*options, tree_descend_subdirs)) continue; if (READ_BOOL(*options, view_dir_list_single_click_enter)) continue; if (READ_BOOL(*options, lazy_image_sync)) continue; if (READ_BOOL(*options, update_on_time_change)) continue; if (READ_UINT_CLAMP(*options, duplicates_similarity_threshold, 0, 100)) continue; if (READ_UINT_CLAMP(*options, duplicates_match, 0, DUPE_MATCH_NAME_CI)) continue; if (READ_UINT_CLAMP(*options, duplicates_select_type, 0, DUPE_SELECT_GROUP2)) continue; if (READ_BOOL(*options, duplicates_thumbnails)) continue; if (READ_BOOL(*options, rot_invariant_sim)) continue; if (READ_BOOL(*options, progressive_key_scrolling)) continue; if (READ_UINT_CLAMP(*options, keyboard_scroll_step, 1, 32)) continue; if (READ_BOOL(*options, mousewheel_scrolls)) continue; if (READ_BOOL(*options, image_lm_click_nav)) continue; if (READ_INT(*options, open_recent_list_maxsize)) continue; if (READ_INT(*options, dnd_icon_size)) continue; if (READ_BOOL(*options, place_dialogs_under_mouse)) continue; if (READ_BOOL(*options, save_window_positions)) continue; if (READ_BOOL(*options, use_saved_window_positions_for_new_windows)) continue; if (READ_BOOL(*options, tools_restore_state)) continue; /* Properties dialog options */ if (READ_CHAR(*options, properties.tabs_order)) continue; /* Image options */ if (READ_UINT_CLAMP(*options, image.zoom_mode, 0, ZOOM_RESET_NONE)) continue; if (READ_BOOL(*options, image.zoom_2pass)) continue; if (READ_BOOL(*options, image.zoom_to_fit_allow_expand)) continue; if (READ_BOOL(*options, image.fit_window_to_image)) continue; if (READ_BOOL(*options, image.limit_window_size)) continue; if (READ_INT(*options, image.max_window_size)) continue; if (READ_BOOL(*options, image.limit_autofit_size)) continue; if (READ_INT(*options, image.max_autofit_size)) continue; if (READ_UINT_CLAMP(*options, image.scroll_reset_method, 0, PR_SCROLL_RESET_COUNT - 1)) continue; if (READ_INT(*options, image.tile_cache_max)) continue; if (READ_INT(*options, image.image_cache_max)) continue; if (READ_UINT_CLAMP(*options, image.zoom_quality, GDK_INTERP_NEAREST, GDK_INTERP_HYPER)) continue; if (READ_INT(*options, image.zoom_increment)) continue; if (READ_BOOL(*options, image.enable_read_ahead)) continue; if (READ_BOOL(*options, image.exif_rotate_enable)) continue; if (READ_BOOL(*options, image.use_custom_border_color)) continue; if (READ_BOOL(*options, image.use_custom_border_color_in_fullscreen)) continue; if (READ_COLOR(*options, image.border_color)) continue; if (READ_BOOL(*options, image.use_clutter_renderer)) continue; /* Thumbnails options */ if (READ_INT_CLAMP(*options, thumbnails.max_width, 16, 512)) continue; if (READ_INT_CLAMP(*options, thumbnails.max_height, 16, 512)) continue; if (READ_BOOL(*options, thumbnails.enable_caching)) continue; if (READ_BOOL(*options, thumbnails.cache_into_dirs)) continue; if (READ_BOOL(*options, thumbnails.use_xvpics)) continue; if (READ_BOOL(*options, thumbnails.spec_standard)) continue; if (READ_UINT_CLAMP(*options, thumbnails.quality, GDK_INTERP_NEAREST, GDK_INTERP_HYPER)) continue; if (READ_BOOL(*options, thumbnails.use_exif)) continue; /* File sorting options */ if (READ_UINT(*options, file_sort.method)) continue; if (READ_BOOL(*options, file_sort.ascending)) continue; if (READ_BOOL(*options, file_sort.case_sensitive)) continue; if (READ_BOOL(*options, file_sort.natural)) continue; /* File operations *options */ if (READ_BOOL(*options, file_ops.enable_in_place_rename)) continue; if (READ_BOOL(*options, file_ops.confirm_delete)) continue; if (READ_BOOL(*options, file_ops.enable_delete_key)) continue; if (READ_BOOL(*options, file_ops.safe_delete_enable)) continue; if (READ_CHAR(*options, file_ops.safe_delete_path)) continue; if (READ_INT(*options, file_ops.safe_delete_folder_maxsize)) continue; /* Fullscreen options */ if (READ_INT(*options, fullscreen.screen)) continue; if (READ_BOOL(*options, fullscreen.clean_flip)) continue; if (READ_BOOL(*options, fullscreen.disable_saver)) continue; if (READ_BOOL(*options, fullscreen.above)) continue; /* Image overlay */ if (READ_CHAR(*options, image_overlay.template_string)) continue; if (READ_INT(*options, image_overlay.x)) continue; if (READ_INT(*options, image_overlay.y)) continue; if (READ_USHORT(*options, image_overlay.text_red)) continue; if (READ_USHORT(*options, image_overlay.text_green)) continue; if (READ_USHORT(*options, image_overlay.text_blue)) continue; if (READ_USHORT(*options, image_overlay.text_alpha)) continue; if (READ_USHORT(*options, image_overlay.background_red)) continue; if (READ_USHORT(*options, image_overlay.background_green)) continue; if (READ_USHORT(*options, image_overlay.background_blue)) continue; if (READ_USHORT(*options, image_overlay.background_alpha)) continue; if (READ_CHAR(*options, image_overlay.font)) continue; /* Slideshow options */ if (READ_INT_UNIT(*options, slideshow.delay, SLIDESHOW_SUBSECOND_PRECISION)) continue; if (READ_BOOL(*options, slideshow.random)) continue; if (READ_BOOL(*options, slideshow.repeat)) continue; /* Collection options */ if (READ_BOOL(*options, collections.rectangular_selection)) continue; /* Filtering options */ if (READ_BOOL(*options, file_filter.show_hidden_files)) continue; if (READ_BOOL(*options, file_filter.show_parent_directory)) continue; if (READ_BOOL(*options, file_filter.show_dot_directory)) continue; if (READ_BOOL(*options, file_filter.disable_file_extension_checks)) continue; if (READ_BOOL(*options, file_filter.disable)) continue; if (READ_CHAR(*options, sidecar.ext)) continue; /* Color Profiles */ /* Shell command */ if (READ_CHAR(*options, shell.path)) continue; if (READ_CHAR(*options, shell.options)) continue; /* Helpers */ if (READ_CHAR(*options, helpers.html_browser.command_name)) continue; if (READ_CHAR(*options, helpers.html_browser.command_line)) continue; /* Metadata */ if (READ_BOOL(*options, metadata.enable_metadata_dirs)) continue; if (READ_BOOL(*options, metadata.save_in_image_file)) continue; if (READ_BOOL(*options, metadata.save_legacy_IPTC)) continue; if (READ_BOOL(*options, metadata.warn_on_write_problems)) continue; if (READ_BOOL(*options, metadata.save_legacy_format)) continue; if (READ_BOOL(*options, metadata.sync_grouped_files)) continue; if (READ_BOOL(*options, metadata.confirm_write)) continue; if (READ_BOOL(*options, metadata.confirm_after_timeout)) continue; if (READ_INT(*options, metadata.confirm_timeout)) continue; if (READ_BOOL(*options, metadata.confirm_on_image_change)) continue; if (READ_BOOL(*options, metadata.confirm_on_dir_change)) continue; if (READ_BOOL(*options, metadata.keywords_case_sensitive)) continue; if (READ_BOOL(*options, metadata.write_orientation)) continue; if (READ_INT(*options, stereo.mode)) continue; if (READ_INT(*options, stereo.fsmode)) continue; if (READ_BOOL(*options, stereo.enable_fsmode)) continue; if (READ_INT(*options, stereo.fixed_w)) continue; if (READ_INT(*options, stereo.fixed_h)) continue; if (READ_INT(*options, stereo.fixed_x1)) continue; if (READ_INT(*options, stereo.fixed_y1)) continue; if (READ_INT(*options, stereo.fixed_x2)) continue; if (READ_INT(*options, stereo.fixed_y2)) continue; /* Dummy options */ if (READ_DUMMY(*options, image.dither_quality, "deprecated since 2012-08-13")) continue; /* Unknown options */ log_printf("unknown attribute %s = %s\n", option, value); } return TRUE; }
// Message handler for ShowMenu message // takes four values: // short: a bitfield of keys that are valid input // char : the duration, in seconds, the menu should stay up. -1 means is stays until something is chosen. // byte : a boolean, TRUE if there is more string yet to be received before displaying the menu, FALSE if it's the last string // string: menu string to display // if this message is never received, then scores will simply be the combined totals of the players. int CHudMenu :: MsgFunc_ShowMenu( const char *pszName, int iSize, void *pbuf ) { char *temp = NULL, *menustring; BEGIN_READ( pbuf, iSize ); m_bitsValidSlots = READ_SHORT(); int DisplayTime = READ_CHAR(); int NeedMore = READ_BYTE(); if ( DisplayTime > 0 ) m_flShutoffTime = DisplayTime + gHUD.m_flTime; else m_flShutoffTime = -1; if ( !m_bitsValidSlots ) { m_fMenuDisplayed = 0; // no valid slots means that the menu should be turned off m_iFlags &= ~HUD_ACTIVE; ClientCmd("touch_removebutton _menu_*"); return 1; } menustring = READ_STRING(); // menu will be replaced by scripted touch config // so execute it and exit if( _extended_menus->value != 0.0f ) { if( !strcmp(menustring, "#RadioA") ) { ShowVGUIMenu(MENU_RADIOA); return 1; } else if( !strcmp(menustring, "#RadioB")) { ShowVGUIMenu(MENU_RADIOB); return 1; } else if( !strcmp(menustring, "#RadioC")) { ShowVGUIMenu(MENU_RADIOC); return 1; } else { // we just show touch screen numbers ShowVGUIMenu(MENU_NUMERICAL_MENU); } } else { // we just show touch screen numbers ShowVGUIMenu(MENU_NUMERICAL_MENU); } if ( !m_fWaitingForMore ) // this is the start of a new menu { strncpy( g_szPrelocalisedMenuString, menustring, MAX_MENU_STRING ); } else { // append to the current menu string strncat( g_szPrelocalisedMenuString, menustring, MAX_MENU_STRING - strlen(g_szPrelocalisedMenuString) ); } g_szPrelocalisedMenuString[MAX_MENU_STRING-1] = 0; // ensure null termination (strncat/strncpy does not) if ( !NeedMore ) { // we have the whole string, so we can localise it now strncpy( g_szMenuString, gHUD.m_TextMessage.BufferedLocaliseTextString( g_szPrelocalisedMenuString ), MAX_MENU_STRING ); // Swap in characters if ( KB_ConvertString( g_szMenuString, &temp ) ) { strncpy( g_szMenuString, temp, MAX_MENU_STRING ); free( temp ); } } m_fMenuDisplayed = 1; m_iFlags |= HUD_ACTIVE; m_fWaitingForMore = NeedMore; return 1; }
float READ_ANGLE( void ) { return (float)(READ_CHAR() * (360.0/256)); }
bool RankBattleTable::SetTableData(void* pvTable, WCHAR* pwszSheetName, std::wstring* pstrDataName, BSTR bstrData) { static char szTemp[1024] = { 0x00, }; if (0 == wcscmp(pwszSheetName, L"Table_Data_KOR")) { sRANKBATTLE_TBLDAT * pTbldat = (sRANKBATTLE_TBLDAT*)pvTable; if (0 == wcscmp(pstrDataName->c_str(), L"Tblidx")) { pTbldat->tblidx = READ_TBLIDX(bstrData); } else if (0 == wcscmp(pstrDataName->c_str(), L"Name")) { CheckNegativeInvalid(pstrDataName->c_str(), bstrData); READ_STRINGW(bstrData, pTbldat->wszName, _countof(pTbldat->wszName)); } else if (0 == wcscmp(pstrDataName->c_str(), L"Rule_Type")) { BYTE byMatchRule = READ_BYTE(bstrData, pstrDataName->c_str()); if (1 == byMatchRule) { pTbldat->byRuleType = GAMERULE_RANKBATTLE; } else if (100 == byMatchRule) { pTbldat->byRuleType = GAMERULE_MINORMATCH; } else if (101 == byMatchRule) { pTbldat->byRuleType = GAMERULE_MAJORMATCH; } else if (102 == byMatchRule) { pTbldat->byRuleType = GAMERULE_FINALMATCH; } else { Table::CallErrorCallbackFunction(L"[File] : %s\n[Error] : invalid \"Rule_Type\"[%u] (Field Name = %s)", m_wszXmlFileName, byMatchRule, pstrDataName->c_str()); return false; } } else if (0 == wcscmp(pstrDataName->c_str(), L"Battle_Mode")) { pTbldat->byBattleMode = READ_BYTE(bstrData, pstrDataName->c_str()); } else if (0 == wcscmp(pstrDataName->c_str(), L"Map_Index")) { pTbldat->worldTblidx = READ_TBLIDX(bstrData); } else if (0 == wcscmp(pstrDataName->c_str(), L"Need_Item")) { pTbldat->needItemTblidx = READ_TBLIDX(bstrData); } else if (0 == wcscmp(pstrDataName->c_str(), L"Need_Zenny")) { pTbldat->dwZenny = READ_DWORD(bstrData); } else if (0 == wcscmp(pstrDataName->c_str(), L"Min_Level")) { pTbldat->byMinLevel = READ_BYTE(bstrData, pstrDataName->c_str()); } else if (0 == wcscmp(pstrDataName->c_str(), L"Max_Level")) { pTbldat->byMaxLevel = READ_BYTE(bstrData, pstrDataName->c_str()); } else if (0 == wcscmp(pstrDataName->c_str(), L"Battle_Count")) { pTbldat->byBattleCount = READ_BYTE(bstrData, pstrDataName->c_str()); } else if (0 == wcscmp(pstrDataName->c_str(), L"WaitTime")) { pTbldat->dwWaitTime = READ_DWORD(bstrData); } else if (0 == wcscmp(pstrDataName->c_str(), L"DirectionTime")) { pTbldat->dwDirectionTime = READ_DWORD(bstrData); } else if (0 == wcscmp(pstrDataName->c_str(), L"MatchReadyTime")) { pTbldat->dwMatchReadyTime = READ_DWORD(bstrData); } else if (0 == wcscmp(pstrDataName->c_str(), L"StageReadyTime")) { pTbldat->dwStageReadyTime = READ_DWORD(bstrData); } else if (0 == wcscmp(pstrDataName->c_str(), L"StageRunTime")) { pTbldat->dwStageRunTime = READ_DWORD(bstrData); } else if (0 == wcscmp(pstrDataName->c_str(), L"StageFinishTime")) { pTbldat->dwStageFinishTime = READ_DWORD(bstrData); } else if (0 == wcscmp(pstrDataName->c_str(), L"MatchFinishTime")) { pTbldat->dwMatchFinishTime = READ_DWORD(bstrData); } else if (0 == wcscmp(pstrDataName->c_str(), L"BossDirection_Time")) { pTbldat->dwBossDirectionTime = READ_DWORD(bstrData); } else if (0 == wcscmp(pstrDataName->c_str(), L"BossKill_Time")) { pTbldat->dwBossKillTime = READ_DWORD(bstrData); } else if (0 == wcscmp(pstrDataName->c_str(), L"BossEndingTime")) { pTbldat->dwBossEndingTime = READ_DWORD(bstrData); } else if (0 == wcscmp(pstrDataName->c_str(), L"EndTime")) { pTbldat->dwEndTime = READ_DWORD(bstrData); } else if (0 == wcscmp(pstrDataName->c_str(), L"KO_Score")) { pTbldat->chScoreKO = READ_CHAR(bstrData, pstrDataName->c_str()); } else if (0 == wcscmp(pstrDataName->c_str(), L"OutofArea_Score")) { pTbldat->chScoreOutOfArea = READ_CHAR(bstrData, pstrDataName->c_str()); } else if (0 == wcscmp(pstrDataName->c_str(), L"Pointwin_Score")) { pTbldat->chScorePointWin = READ_CHAR(bstrData, pstrDataName->c_str()); } else if (0 == wcscmp(pstrDataName->c_str(), L"Draw_Score")) { pTbldat->chScoreDraw = READ_CHAR(bstrData, pstrDataName->c_str()); } else if (0 == wcscmp(pstrDataName->c_str(), L"Lost_Score")) { pTbldat->chScoreLose = READ_CHAR(bstrData, pstrDataName->c_str()); } else if (0 == wcscmp(pstrDataName->c_str(), L"Excellent_Result")) { pTbldat->chResultExcellent = READ_CHAR(bstrData, pstrDataName->c_str()); } else if (0 == wcscmp(pstrDataName->c_str(), L"Greate_Result")) { pTbldat->chResultGreate = READ_CHAR(bstrData, pstrDataName->c_str()); } else if (0 == wcscmp(pstrDataName->c_str(), L"Good_Result")) { pTbldat->chResultGood = READ_CHAR(bstrData, pstrDataName->c_str()); } else if (0 == wcscmp(pstrDataName->c_str(), L"Draw_Result")) { pTbldat->chResultDraw = READ_CHAR(bstrData, pstrDataName->c_str()); } else if (0 == wcscmp(pstrDataName->c_str(), L"Lost_Result")) { pTbldat->chResultLose = READ_CHAR(bstrData, pstrDataName->c_str()); } else if (0 == wcscmp(pstrDataName->c_str(), L"PerfectWinner_Score")) { pTbldat->chBonusPerfectWinner = READ_CHAR(bstrData, pstrDataName->c_str()); } else if (0 == wcscmp(pstrDataName->c_str(), L"NormalWinner_Score")) { pTbldat->chBonusNormalWinner = READ_CHAR(bstrData, pstrDataName->c_str()); } else { Table::CallErrorCallbackFunction(L"[File] : %s\n[Error] : Unknown field name found!(Field Name = %s)", m_wszXmlFileName, pstrDataName->c_str()); return false; } } else { return false; } return true; }
/* If panning or note_to_use != -1, it will be used for all samples, instead of the sample-specific values in the instrument file. For note_to_use, any value <0 or >127 will be forced to 0. For other parameters, 1 means yes, 0 means no, other values are undefined. TODO: do reverse loops right */ static Instrument *load_instrument(char *name, int percussion, int panning, int amp, int note_to_use, int strip_loop, int strip_envelope, int strip_tail) { Instrument *ip; Sample *sp; FILE *fp; uint8 tmp[1024]; int i,j,noluck=0; #ifdef PATCH_EXT_LIST static char *patch_ext[] = PATCH_EXT_LIST; #endif if (!name) return 0; /* Open patch file */ if ((fp=open_file(name, 1, OF_NORMAL)) == NULL) { noluck=1; #ifdef PATCH_EXT_LIST /* Try with various extensions */ for (i=0; patch_ext[i]; i++) { if (strlen(name)+strlen(patch_ext[i])<1024) { char path[1024]; strcpy(path,DEFAULT_PATH); #ifdef __linux__ strcat(path,"/"); #else strcat(path,"\\"); #endif strcat(path, name); strcat(path, patch_ext[i]); if ((fp=open_file(path, 1, OF_NORMAL)) != NULL) { noluck=0; break; } } } #endif } if (noluck) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Instrument `%s' can't be found.", name); return 0; } ctl->cmsg(CMSG_INFO, VERB_NOISY, "Loading instrument %s", current_filename); /* Read some headers and do cursory sanity checks. There are loads of magic offsets. This could be rewritten... */ if ((239 != fread(tmp, 1, 239, fp)) || (memcmp(tmp, "GF1PATCH110\0ID#000002", 22) && memcmp(tmp, "GF1PATCH100\0ID#000002", 22))) /* don't know what the differences are */ { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: not an instrument", name); return 0; } if (tmp[82] != 1 && tmp[82] != 0) /* instruments. To some patch makers, 0 means 1 */ { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Can't handle patches with %d instruments", tmp[82]); return 0; } if (tmp[151] != 1 && tmp[151] != 0) /* layers. What's a layer? */ { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Can't handle instruments with %d layers", tmp[151]); return 0; } ip=safe_malloc(sizeof(Instrument)); ip->samples = tmp[198]; ip->sample = safe_malloc(sizeof(Sample) * ip->samples); for (i=0; i<ip->samples; i++) { uint8 fractions; int32 tmplong; uint16 tmpshort; uint8 tmpchar; #define READ_CHAR(thing) \ if (1 != fread(&tmpchar, 1, 1, fp)) goto fail; \ thing = tmpchar; #define READ_SHORT(thing) \ if (1 != fread(&tmpshort, 2, 1, fp)) goto fail; \ thing = LE_SHORT(tmpshort); #define READ_LONG(thing) \ if (1 != fread(&tmplong, 4, 1, fp)) goto fail; \ thing = LE_LONG(tmplong); skip(fp, 7); /* Skip the wave name */ if (1 != fread(&fractions, 1, 1, fp)) { fail: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Error reading sample %d", i); for (j=0; j<i; j++) free(ip->sample[j].data); free(ip->sample); free(ip); return 0; } sp=&(ip->sample[i]); READ_LONG(sp->data_length); READ_LONG(sp->loop_start); READ_LONG(sp->loop_end); READ_SHORT(sp->sample_rate); READ_LONG(sp->low_freq); READ_LONG(sp->high_freq); READ_LONG(sp->root_freq); skip(fp, 2); /* Why have a "root frequency" and then "tuning"?? */ READ_CHAR(tmp[0]); if (panning==-1) sp->panning = (tmp[0] * 8 + 4) & 0x7f; else sp->panning=(uint8)(panning & 0x7F); /* envelope, tremolo, and vibrato */ if (18 != fread(tmp, 1, 18, fp)) goto fail; if (!tmp[13] || !tmp[14]) { sp->tremolo_sweep_increment= sp->tremolo_phase_increment=sp->tremolo_depth=0; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * no tremolo"); } else { sp->tremolo_sweep_increment=convert_tremolo_sweep(tmp[12]); sp->tremolo_phase_increment=convert_tremolo_rate(tmp[13]); sp->tremolo_depth=tmp[14]; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * tremolo: sweep %d, phase %d, depth %d", sp->tremolo_sweep_increment, sp->tremolo_phase_increment, sp->tremolo_depth); } if (!tmp[16] || !tmp[17]) { sp->vibrato_sweep_increment= sp->vibrato_control_ratio=sp->vibrato_depth=0; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * no vibrato"); } else { sp->vibrato_control_ratio=convert_vibrato_rate(tmp[16]); sp->vibrato_sweep_increment= convert_vibrato_sweep(tmp[15], sp->vibrato_control_ratio); sp->vibrato_depth=tmp[17]; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * vibrato: sweep %d, ctl %d, depth %d", sp->vibrato_sweep_increment, sp->vibrato_control_ratio, sp->vibrato_depth); } READ_CHAR(sp->modes); skip(fp, 40); /* skip the useless scale frequency, scale factor (what's it mean?), and reserved space */ /* Mark this as a fixed-pitch instrument if such a deed is desired. */ if (note_to_use!=-1) sp->note_to_use=(uint8)(note_to_use); else sp->note_to_use=0; /* seashore.pat in the Midia patch set has no Sustain. I don't understand why, and fixing it by adding the Sustain flag to all looped patches probably breaks something else. We do it anyway. */ if (sp->modes & MODES_LOOPING) sp->modes |= MODES_SUSTAIN; /* Strip any loops and envelopes we're permitted to */ if ((strip_loop==1) && (sp->modes & (MODES_SUSTAIN | MODES_LOOPING | MODES_PINGPONG | MODES_REVERSE))) { ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Removing loop and/or sustain"); sp->modes &=~(MODES_SUSTAIN | MODES_LOOPING | MODES_PINGPONG | MODES_REVERSE); } if (strip_envelope==1) { if (sp->modes & MODES_ENVELOPE) ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Removing envelope"); sp->modes &= ~MODES_ENVELOPE; } else if (strip_envelope != 0) { /* Have to make a guess. */ if (!(sp->modes & (MODES_LOOPING | MODES_PINGPONG | MODES_REVERSE))) { /* No loop? Then what's there to sustain? No envelope needed either... */ sp->modes &= ~(MODES_SUSTAIN|MODES_ENVELOPE); ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - No loop, removing sustain and envelope"); } else if (!memcmp(tmp, "??????", 6) || tmp[11] >= 100) { /* Envelope rates all maxed out? Envelope end at a high "offset"? That's a weird envelope. Take it out. */ sp->modes &= ~MODES_ENVELOPE; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Weirdness, removing envelope"); } else if (!(sp->modes & MODES_SUSTAIN)) { /* No sustain? Then no envelope. I don't know if this is justified, but patches without sustain usually don't need the envelope either... at least the Gravis ones. They're mostly drums. I think. */ sp->modes &= ~MODES_ENVELOPE; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - No sustain, removing envelope"); } } for (j=0; j<6; j++) { sp->envelope_rate[j]= convert_envelope_rate(tmp[j]); sp->envelope_offset[j]= convert_envelope_offset(tmp[6+j]); } /* Then read the sample data */ sp->data = safe_malloc(sp->data_length); if (1 != fread(sp->data, sp->data_length, 1, fp)) goto fail; if (!(sp->modes & MODES_16BIT)) /* convert to 16-bit data */ { int32 i=sp->data_length; uint8 *cp=(uint8 *)(sp->data); uint16 *tmp,*new; tmp=new=safe_malloc(sp->data_length*2); while (i--) *tmp++ = (uint16)(*cp++) << 8; cp=(uint8 *)(sp->data); sp->data = (sample_t *)new; free(cp); sp->data_length *= 2; sp->loop_start *= 2; sp->loop_end *= 2; } #ifndef LITTLE_ENDIAN else /* convert to machine byte order */ {
void Font::DrawString(const Graphics& g, const Brush& brush, const string& s, int len, int x, int y, int w, int h, int flags){ int xx = x; int yy = y; int rr = x + w; int bb = y + h; //g.DrawRect(Pens::Blue, x, y, w, h); if(len < 0) len = s.length(); vector<int> ws, cs; int wi = 0, c = 0; for (int i = 0; i<len;){ char_type cc; int rs = READ_CHAR(&cc, s.c_str() + i, len-i); if (rs>0) i += rs; else break; bool n = cc == L'\n' || cc == 0x0085 || cc == 0x2028 || cc == 0x2029; //if (!n && cc != L'\r') PutChar(cc); int ww = n ? 0 : map[cc]->width; if ((flags & FontFlag_NoWrap) == 0 && (n || (w >= 0 && wi + ww>w))){ if (c == 0){ ws.push_back(ww); cs.push_back(1); wi = 0; c = 0; } else{ ws.push_back(wi); cs.push_back(c); wi = ww; c = 1; if (n){ wi = 0; } } } else { wi += ww; c++; } } if (c > 0){ ws.push_back(wi); cs.push_back(c); } int rh = cs.size()*face->size->metrics.y_ppem; // real height // vertical alignment switch ((flags >> 2) & 3) { case 1: yy += (h-rh) / 2; break; case 2: yy += h-rh; break; } //bool clip_not_whole = (flags & FontFlag_ClipNotWhole) != 0; glUniform1i(Program::CurrentShader()->useTex2, 1); int line = -1; int row = 0; yy -= face->size->metrics.y_ppem; for (int i = 0; i < len; ){ if (row == 0){ line++; xx = x; yy += face->size->metrics.y_ppem; switch (flags & 0x03) { case 1: xx += (w - ws[line]) / 2; break; case 2: xx += w - ws[line]; break; } } char_type cc; int rs = READ_CHAR(&cc, s.c_str() + i, len - i); if (rs>0) i += rs; else return; if (++row == cs[line]) row = 0; if (cc == L'\r') continue; bool n = cc == L'\n' || cc == 0x0085 || cc == 0x2028 || cc == 0x2029; // new line if (!n){ Char& c = *map[cc]; Rect& r = c.bounds; float ss = TEXTURE_SIZE; float L = r.Left() / ss; float T = ((int)r.Top() % TEXTURE_SIZE) / ss; float R = r.Right() / ss; float B = T + c.height / ss; float ps[] = { L, T, R, T, R, B, L, B }; glEnableVertexAttribArray(TEXCOORD_ATTRIB_LOC); glVertexAttribPointer(TEXCOORD_ATTRIB_LOC, 2, GL_FLOAT, GL_FALSE, 0, ps); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textures[r.Top() / TEXTURE_SIZE]); glActiveTexture(GL_TEXTURE0); g.FillRect(brush, xx + c.left, yy - c.top, c.width, c.height); glDisableVertexAttribArray(TEXCOORD_ATTRIB_LOC); //glUniform1i(Program::CurrentShader()->useTex2, 0); //g.DrawRect(Pens::Green, xx + c.left, yy - c.top, c.width, c.height); //glUniform1i(Program::CurrentShader()->useTex2, 1); xx += c.width; } } glUniform1i(Program::CurrentShader()->useTex2, 0); }
/* If panning or note_to_use != -1, it will be used for all samples, instead of the sample-specific values in the instrument file. For note_to_use, any value <0 or >127 will be forced to 0. For other parameters, 1 means yes, 0 means no, other values are undefined. TODO: do reverse loops right */ static Instrument *load_instrument(char *name, int percussion, int panning, int amp, int note_to_use, int strip_loop, int strip_envelope, int strip_tail) { ignore_unused_variable_warning(percussion); Instrument *ip; Sample *sp; FILE *fp; uint8 tmp[1024]; int i,j,noluck=0; #ifdef PATCH_EXT_LIST static const char *patch_ext[] = PATCH_EXT_LIST; #endif if (!name) return 0; /* Open patch file */ if ((fp=open_file(name, 1, OF_NORMAL)) == NULL) { noluck=1; #ifdef PATCH_EXT_LIST /* Try with various extensions */ for (i=0; patch_ext[i]; i++) { if (strlen(name)+strlen(patch_ext[i])<1024) { char path[1024]; strcpy(path, name); strcat(path, patch_ext[i]); if ((fp=open_file(path, 1, OF_NORMAL)) != NULL) { noluck=0; break; } } } #endif } if (noluck) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Instrument `%s' can't be found.", name); return 0; } ctl->cmsg(CMSG_INFO, VERB_NOISY, "Loading instrument %s", current_filename); /* Read some headers and do cursory sanity checks. There are loads of magic offsets. This could be rewritten... */ if ((239 != fread(tmp, 1, 239, fp)) || (memcmp(tmp, "GF1PATCH110\0ID#000002", 22) && memcmp(tmp, "GF1PATCH100\0ID#000002", 22))) /* don't know what the differences are */ { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: not an instrument", name); return 0; } if (tmp[82] != 1 && tmp[82] != 0) /* instruments. To some patch makers, 0 means 1 */ { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Can't handle patches with %d instruments", tmp[82]); return 0; } if (tmp[151] != 1 && tmp[151] != 0) /* layers. What's a layer? */ { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Can't handle instruments with %d layers", tmp[151]); return 0; } ip=safe_Malloc<Instrument>(); ip->samples = tmp[198]; ip->sample = safe_Malloc<Sample>(ip->samples); for (i=0; i<ip->samples; i++) { uint8 fractions; sint32 tmplong; uint16 tmpshort; uint8 tmpchar; #define READ_CHAR(thing) \ if (1 != fread(&tmpchar, 1, 1, fp)) goto fail; \ thing = tmpchar; #define READ_SHORT(thing) \ if (1 != fread(&tmpshort, 2, 1, fp)) goto fail; \ thing = LE_SHORT(tmpshort); #define READ_LONG(thing) \ if (1 != fread(&tmplong, 4, 1, fp)) goto fail; \ thing = LE_LONG(tmplong); skip(fp, 7); /* Skip the wave name */ if (1 != fread(&fractions, 1, 1, fp)) { fail: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Error reading sample %d", i); for (j=0; j<i; j++) free(ip->sample[j].data); free(ip->sample); free(ip); return 0; } sp=&(ip->sample[i]); READ_LONG(sp->data_length); READ_LONG(sp->loop_start); READ_LONG(sp->loop_end); READ_SHORT(sp->sample_rate); READ_LONG(sp->low_freq); READ_LONG(sp->high_freq); READ_LONG(sp->root_freq); skip(fp, 2); /* Why have a "root frequency" and then "tuning"?? */ READ_CHAR(tmp[0]); if (panning==-1) sp->panning = (tmp[0] * 8 + 4) & 0x7f; else sp->panning=static_cast<uint8>(panning & 0x7F); /* envelope, tremolo, and vibrato */ if (18 != fread(tmp, 1, 18, fp)) goto fail; if (!tmp[13] || !tmp[14]) { sp->tremolo_sweep_increment= sp->tremolo_phase_increment=sp->tremolo_depth=0; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * no tremolo"); } else { sp->tremolo_sweep_increment=convert_tremolo_sweep(tmp[12]); sp->tremolo_phase_increment=convert_tremolo_rate(tmp[13]); sp->tremolo_depth=tmp[14]; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * tremolo: sweep %d, phase %d, depth %d", sp->tremolo_sweep_increment, sp->tremolo_phase_increment, sp->tremolo_depth); } if (!tmp[16] || !tmp[17]) { sp->vibrato_sweep_increment= sp->vibrato_control_ratio=sp->vibrato_depth=0; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * no vibrato"); } else { sp->vibrato_control_ratio=convert_vibrato_rate(tmp[16]); sp->vibrato_sweep_increment= convert_vibrato_sweep(tmp[15], sp->vibrato_control_ratio); sp->vibrato_depth=tmp[17]; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * vibrato: sweep %d, ctl %d, depth %d", sp->vibrato_sweep_increment, sp->vibrato_control_ratio, sp->vibrato_depth); } READ_CHAR(sp->modes); skip(fp, 40); /* skip the useless scale frequency, scale factor (what's it mean?), and reserved space */ /* Mark this as a fixed-pitch instrument if such a deed is desired. */ if (note_to_use!=-1) sp->note_to_use=static_cast<uint8>(note_to_use); else sp->note_to_use=0; /* seashore.pat in the Midia patch set has no Sustain. I don't understand why, and fixing it by adding the Sustain flag to all looped patches probably breaks something else. We do it anyway. */ if (sp->modes & MODES_LOOPING) sp->modes |= MODES_SUSTAIN; /* Strip any loops and envelopes we're permitted to */ if ((strip_loop==1) && (sp->modes & (MODES_SUSTAIN | MODES_LOOPING | MODES_PINGPONG | MODES_REVERSE))) { ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Removing loop and/or sustain"); sp->modes &=~(MODES_SUSTAIN | MODES_LOOPING | MODES_PINGPONG | MODES_REVERSE); } if (strip_envelope==1) { if (sp->modes & MODES_ENVELOPE) ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Removing envelope"); sp->modes &= ~MODES_ENVELOPE; } else if (strip_envelope != 0) { /* Have to make a guess. */ if (!(sp->modes & (MODES_LOOPING | MODES_PINGPONG | MODES_REVERSE))) { /* No loop? Then what's there to sustain? No envelope needed either... */ sp->modes &= ~(MODES_SUSTAIN|MODES_ENVELOPE); ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - No loop, removing sustain and envelope"); } else if (!memcmp(tmp, "??????", 6) || tmp[11] >= 100) { /* Envelope rates all maxed out? Envelope end at a high "offset"? That's a weird envelope. Take it out. */ sp->modes &= ~MODES_ENVELOPE; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Weirdness, removing envelope"); } else if (!(sp->modes & MODES_SUSTAIN)) { /* No sustain? Then no envelope. I don't know if this is justified, but patches without sustain usually don't need the envelope either... at least the Gravis ones. They're mostly drums. I think. */ sp->modes &= ~MODES_ENVELOPE; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - No sustain, removing envelope"); } } for (j=0; j<6; j++) { sp->envelope_rate[j]= convert_envelope_rate(tmp[j]); sp->envelope_offset[j]= convert_envelope_offset(tmp[6+j]); } /* Then read the sample data */ sp->data = safe_Malloc<sample_t>(sp->data_length); if (1 != fread(sp->data, sp->data_length, 1, fp)) goto fail; if (!(sp->modes & MODES_16BIT)) /* convert to 16-bit data */ { sint32 i=sp->data_length; uint8 *cp=reinterpret_cast<uint8 *>(sp->data); uint16 *tmp,*new_dat; tmp=new_dat=safe_Malloc<uint16>(sp->data_length); while (i--) *tmp++ = static_cast<uint16>(*cp++) << 8; cp=reinterpret_cast<uint8 *>(sp->data); sp->data = reinterpret_cast<sample_t *>(new_dat); free(cp); sp->data_length *= 2; sp->loop_start *= 2; sp->loop_end *= 2; } #ifndef TIMIDITY_LITTLE_ENDIAN else /* convert to machine byte order */ { sint32 i=sp->data_length/2; sint16 *tmp=reinterpret_cast<sint16 *>(sp->data),s; while (i--) { s=LE_SHORT(*tmp); *tmp++=s; } } #endif if (sp->modes & MODES_UNSIGNED) /* convert to signed data */ { sint32 i=sp->data_length/2; sint16 *tmp = sp->data; while (i--) *tmp++ ^= 0x8000; } /* Reverse reverse loops and pass them off as normal loops */ if (sp->modes & MODES_REVERSE) { sint32 t; /* The GUS apparently plays reverse loops by reversing the whole sample. We do the same because the GUS does not SUCK. */ ctl->cmsg(CMSG_WARNING, VERB_NORMAL, "Reverse loop in %s", name); reverse_data(sp->data, 0, sp->data_length/2); t=sp->loop_start; sp->loop_start=sp->data_length - sp->loop_end; sp->loop_end=sp->data_length - t; sp->modes &= ~MODES_REVERSE; sp->modes |= MODES_LOOPING; /* just in case */ } /* If necessary do some anti-aliasing filtering */ if (antialiasing_allowed) antialiasing(sp,play_mode->rate); #ifdef ADJUST_SAMPLE_VOLUMES if (amp!=-1) sp->volume=static_cast<float>((amp) / 100.0); else { /* Try to determine a volume scaling factor for the sample. This is a very crude adjustment, but things sound more balanced with it. Still, this should be a runtime option. */ sint32 i=sp->data_length/2; sint16 maxamp=0,a; sint16 *tmp = sp->data; while (i--) { a=*tmp++; if (a<0) a=-a; if (a>maxamp) maxamp=a; } sp->volume=static_cast<float>(32768.0 / maxamp); ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * volume comp: %f", sp->volume); } #else if (amp!=-1) sp->volume=static_cast<double>(amp) / 100.0; else sp->volume=1.0; #endif sp->data_length /= 2; /* These are in bytes. Convert into samples. */ sp->loop_start /= 2; sp->loop_end /= 2; /* Then fractional samples */ sp->data_length <<= FRACTION_BITS; sp->loop_start <<= FRACTION_BITS; sp->loop_end <<= FRACTION_BITS; /* Adjust for fractional loop points. This is a guess. Does anyone know what "fractions" really stands for? */ sp->loop_start |= (fractions & 0x0F) << (FRACTION_BITS-4); sp->loop_end |= ((fractions>>4) & 0x0F) << (FRACTION_BITS-4); /* If this instrument will always be played on the same note, and it's not looped, we can resample it now. */ if (sp->note_to_use && !(sp->modes & MODES_LOOPING)) pre_resample(sp); #ifdef LOOKUP_HACK /* Squash the 16-bit data into 8 bits. */ { uint8 *gulp,*ulp; sint16 *swp; int l=sp->data_length >> FRACTION_BITS; gulp=ulp=safe_Malloc<uint8>(l+1); swp=(sint16 *)sp->data; while(l--) *ulp++ = (*swp++ >> 8) & 0xFF; free(sp->data); sp->data=(sample_t *)gulp; } #endif if (strip_tail==1) { /* Let's not really, just say we did. */ ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Stripping tail"); sp->data_length = sp->loop_end; } } close_file(fp); return ip; }
// // CurWeapon: Update hud state with the current weapon and clip count. Ammo // counts are updated with AmmoX. Server assures that the Weapon ammo type // numbers match a real ammo type. // int CHudAmmo::MsgFunc_CurWeapon(const char *pszName, int iSize, void *pbuf ) { static wrect_t nullrc; BEGIN_READ( pbuf, iSize ); int iState = READ_BYTE(); int iId = READ_CHAR(); int iClip = READ_CHAR(); if ( iId < 1 ) { SetCrosshair(0, nullrc, 0, 0, 0); return 0; } if ( g_iUser1 != OBS_IN_EYE ) { // Is player dead??? if ((iId == -1) && (iClip == -1)) { gHUD.m_fPlayerDead = TRUE; gpActiveSel = NULL; return 1; } gHUD.m_fPlayerDead = FALSE; } WEAPON *pWeapon = gWR.GetWeapon( iId ); if ( !pWeapon ) return 0; if ( iClip < -1 ) pWeapon->iClip = abs(iClip); else pWeapon->iClip = iClip; if ( iState == 0 ) // we're not the current weapon, so update no more return 1; m_pWeapon = pWeapon; /*if( gHUD.m_iFOV <= 40 ) { // zoomed crosshairs if (fOnTarget && m_pWeapon->hZoomedAutoaim) SetCrosshair(m_pWeapon->hZoomedAutoaim, m_pWeapon->rcZoomedAutoaim, 255, 255, 255); else SetCrosshair(m_pWeapon->hZoomedCrosshair, m_pWeapon->rcZoomedCrosshair, 255, 255, 255); } else { SetCrosshair( 0, nullrc, 0, 0, 0); }*/ m_fFade = 200.0f; //!!! m_iFlags |= HUD_ACTIVE; return 1; }
static bool unpack_blob(serial_context *ser_cont, uint32_t size, as_val **value) { int32_t type = READ_CHAR(ser_cont->fd, ser_cont->line_no, ser_cont->col_no, ser_cont->bytes); if (type == EOF) { err("Error while reading BLOB type"); return false; } --size; if (VERBOSE) { ver("%sBLOB, %u byte(s), type 0x%02x", indent(ser_cont), size, type); } // Waste one byte... void *buffer = safe_malloc(size + 1); // ... so that we can NUL-terminate all strings for as_string_val_hashcode(). char *chars = buffer; chars[size] = 0; if (!READ_BLOCK(ser_cont->fd, ser_cont->line_no, ser_cont->col_no, ser_cont->bytes, buffer, size)) { err("Error while reading BLOB data"); cf_free(buffer); return false; } if (type == AS_BYTES_STRING) { if (VERBOSE) { ver("%s -> string BLOB: \"%s\"", indent(ser_cont), chars); } as_string *string = as_string_new_wlen(buffer, size, true); if (string == NULL) { err("Error while allocating string"); cf_free(buffer); return false; } *value = (as_val *)string; return true; } if (type == AS_BYTES_GEOJSON) { if (VERBOSE) { ver("%s -> geo BLOB: \"%s\"", indent(ser_cont), chars); } as_geojson *geo = as_geojson_new_wlen(buffer, size, true); if (geo == NULL) { err("Error while allocating geo value"); cf_free(buffer); return false; } *value = (as_val *)geo; return true; } as_bytes *blob = as_bytes_new_wrap(buffer, size, true); if (blob == NULL) { err("Error while allocating BLOB"); return false; } blob->type = (as_bytes_type)type; *value = (as_val *)blob; return true; }
/* If panning or note_to_use != -1, it will be used for all samples, instead of the sample-specific values in the instrument file. For note_to_use, any value <0 or >127 will be forced to 0. For other parameters, 1 means yes, 0 means no, other values are undefined. TODO: do reverse loops right */ static InstrumentLayer *load_instrument(char *name, int font_type, int percussion, int panning, int amp, int cfg_tuning, int note_to_use, int strip_loop, int strip_envelope, int strip_tail, int bank, int gm_num, int sf_ix) { InstrumentLayer *lp, *lastlp, *headlp; Instrument *ip; FILE *fp; uint8 tmp[1024]; int i,j,noluck=0; #ifdef PATCH_EXT_LIST static char *patch_ext[] = PATCH_EXT_LIST; #endif int sf2flag = 0; int right_samples = 0; int stereo_channels = 1, stereo_layer; int vlayer_list[19][4], vlayer, vlayer_count; if (!name) return 0; /* Open patch file */ if ((fp=open_file(name, 1, OF_NORMAL)) == NULL) { noluck=1; #ifdef PATCH_EXT_LIST /* Try with various extensions */ for (i=0; patch_ext[i]; i++) { if (strlen(name)+strlen(patch_ext[i])<1024) { char path[1024]; strcpy(path, name); strcat(path, patch_ext[i]); if ((fp=open_file(path, 1, OF_NORMAL)) != NULL) { noluck=0; break; } } } #endif } if (noluck) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Instrument `%s' can't be found.", name); return 0; } /*ctl->cmsg(CMSG_INFO, VERB_NOISY, "Loading instrument %s", current_filename);*/ /* Read some headers and do cursory sanity checks. There are loads of magic offsets. This could be rewritten... */ if ((239 != fread(tmp, 1, 239, fp)) || (memcmp(tmp, "GF1PATCH110\0ID#000002", 22) && memcmp(tmp, "GF1PATCH100\0ID#000002", 22))) /* don't know what the differences are */ { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: not an instrument", name); return 0; } /* patch layout: * bytes: info: starts at offset: * 22 id (see above) 0 * 60 copyright 22 * 1 instruments 82 * 1 voices 83 * 1 channels 84 * 2 number of waveforms 85 * 2 master volume 87 * 4 datasize 89 * 36 reserved, but now: 93 * 7 "SF2EXT\0" id 93 * 1 right samples 100 * 28 reserved 101 * 2 instrument number 129 * 16 instrument name 131 * 4 instrument size 147 * 1 number of layers 151 * 40 reserved 152 * 1 layer duplicate 192 * 1 layer number 193 * 4 layer size 194 * 1 number of samples 198 * 40 reserved 199 * 239 * THEN, for each sample, see below */ if (!memcmp(tmp + 93, "SF2EXT", 6)) { sf2flag = 1; vlayer_count = tmp[152]; } if (tmp[82] != 1 && tmp[82] != 0) /* instruments. To some patch makers, 0 means 1 */ { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Can't handle patches with %d instruments", tmp[82]); return 0; } if (tmp[151] != 1 && tmp[151] != 0) /* layers. What's a layer? */ { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Can't handle instruments with %d layers", tmp[151]); return 0; } if (sf2flag && vlayer_count > 0) { for (i = 0; i < 9; i++) for (j = 0; j < 4; j++) vlayer_list[i][j] = tmp[153+i*4+j]; for (i = 9; i < 19; i++) for (j = 0; j < 4; j++) vlayer_list[i][j] = tmp[199+(i-9)*4+j]; } else { for (i = 0; i < 19; i++) for (j = 0; j < 4; j++) vlayer_list[i][j] = 0; vlayer_list[0][0] = 0; vlayer_list[0][1] = 127; vlayer_list[0][2] = tmp[198]; vlayer_list[0][3] = 0; vlayer_count = 1; } lastlp = 0; for (vlayer = 0; vlayer < vlayer_count; vlayer++) { lp=(InstrumentLayer *)safe_malloc(sizeof(InstrumentLayer)); lp->size = sizeof(InstrumentLayer); lp->lo = vlayer_list[vlayer][0]; lp->hi = vlayer_list[vlayer][1]; ip=(Instrument *)safe_malloc(sizeof(Instrument)); lp->size += sizeof(Instrument); lp->instrument = ip; lp->next = 0; if (lastlp) lastlp->next = lp; else headlp = lp; lastlp = lp; if (sf2flag) ip->type = INST_SF2; else ip->type = INST_GUS; ip->samples = vlayer_list[vlayer][2]; ip->sample = (Sample *)safe_malloc(sizeof(Sample) * ip->samples); lp->size += sizeof(Sample) * ip->samples; ip->left_samples = ip->samples; ip->left_sample = ip->sample; right_samples = vlayer_list[vlayer][3]; ip->right_samples = right_samples; if (right_samples) { ip->right_sample = (Sample *)safe_malloc(sizeof(Sample) * right_samples); lp->size += sizeof(Sample) * right_samples; stereo_channels = 2; } else ip->right_sample = 0; ip->contents = 0; ctl->cmsg(CMSG_INFO, VERB_NOISY, "%s%s[%d,%d] %s(%d-%d layer %d of %d)", (percussion)? " ":"", name, (percussion)? note_to_use : gm_num, bank, (right_samples)? "(2) " : "", lp->lo, lp->hi, vlayer+1, vlayer_count); for (stereo_layer = 0; stereo_layer < stereo_channels; stereo_layer++) { int sample_count; if (stereo_layer == 0) sample_count = ip->left_samples; else if (stereo_layer == 1) sample_count = ip->right_samples; for (i=0; i < sample_count; i++) { uint8 fractions; int32 tmplong; uint16 tmpshort; uint16 sample_volume; uint8 tmpchar; Sample *sp; uint8 sf2delay; #define READ_CHAR(thing) \ if (1 != fread(&tmpchar, 1, 1, fp)) goto fail; \ thing = tmpchar; #define READ_SHORT(thing) \ if (1 != fread(&tmpshort, 2, 1, fp)) goto fail; \ thing = LE_SHORT(tmpshort); #define READ_LONG(thing) \ if (1 != fread(&tmplong, 4, 1, fp)) goto fail; \ thing = LE_LONG(tmplong); /* * 7 sample name * 1 fractions * 4 length * 4 loop start * 4 loop end * 2 sample rate * 4 low frequency * 4 high frequency * 2 finetune * 1 panning * 6 envelope rates | * 6 envelope offsets | 18 bytes * 3 tremolo sweep, rate, depth | * 3 vibrato sweep, rate, depth | * 1 sample mode * 2 scale frequency * 2 scale factor * 2 sample volume (??) * 34 reserved * Now: 1 delay * 33 reserved */ skip(fp, 7); /* Skip the wave name */ if (1 != fread(&fractions, 1, 1, fp)) { fail: ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Error reading sample %d", i); if (stereo_layer == 1) { for (j=0; j<i; j++) free(ip->right_sample[j].data); free(ip->right_sample); i = ip->left_samples; } for (j=0; j<i; j++) free(ip->left_sample[j].data); free(ip->left_sample); free(ip); free(lp); return 0; } if (stereo_layer == 0) sp=&(ip->left_sample[i]); else if (stereo_layer == 1) sp=&(ip->right_sample[i]); READ_LONG(sp->data_length); READ_LONG(sp->loop_start); READ_LONG(sp->loop_end); READ_SHORT(sp->sample_rate); READ_LONG(sp->low_freq); READ_LONG(sp->high_freq); READ_LONG(sp->root_freq); skip(fp, 2); /* Why have a "root frequency" and then "tuning"?? */ READ_CHAR(tmp[0]); if (panning==-1) sp->panning = (tmp[0] * 8 + 4) & 0x7f; else sp->panning=(uint8)(panning & 0x7F); sp->resonance=0; sp->cutoff_freq=0; sp->reverberation=0; sp->chorusdepth=0; sp->exclusiveClass=0; sp->keyToModEnvHold=0; sp->keyToModEnvDecay=0; sp->keyToVolEnvHold=0; sp->keyToVolEnvDecay=0; if (cfg_tuning) { double tune_factor = (double)(cfg_tuning)/1200.0; tune_factor = pow(2.0, tune_factor); sp->root_freq = (uint32)( tune_factor * (double)sp->root_freq ); } /* envelope, tremolo, and vibrato */ if (18 != fread(tmp, 1, 18, fp)) goto fail; if (!tmp[13] || !tmp[14]) { sp->tremolo_sweep_increment= sp->tremolo_phase_increment=sp->tremolo_depth=0; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * no tremolo"); } else { sp->tremolo_sweep_increment=convert_tremolo_sweep(tmp[12]); sp->tremolo_phase_increment=convert_tremolo_rate(tmp[13]); sp->tremolo_depth=tmp[14]; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * tremolo: sweep %d, phase %d, depth %d", sp->tremolo_sweep_increment, sp->tremolo_phase_increment, sp->tremolo_depth); } if (!tmp[16] || !tmp[17]) { sp->vibrato_sweep_increment= sp->vibrato_control_ratio=sp->vibrato_depth=0; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * no vibrato"); } else { sp->vibrato_control_ratio=convert_vibrato_rate(tmp[16]); sp->vibrato_sweep_increment= convert_vibrato_sweep(tmp[15], sp->vibrato_control_ratio); sp->vibrato_depth=tmp[17]; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * vibrato: sweep %d, ctl %d, depth %d", sp->vibrato_sweep_increment, sp->vibrato_control_ratio, sp->vibrato_depth); } READ_CHAR(sp->modes); READ_SHORT(sp->freq_center); READ_SHORT(sp->freq_scale); if (sf2flag) { READ_SHORT(sample_volume); READ_CHAR(sf2delay); READ_CHAR(sp->exclusiveClass); skip(fp, 32); } else { skip(fp, 36); } /* Mark this as a fixed-pitch instrument if such a deed is desired. */ if (note_to_use!=-1) sp->note_to_use=(uint8)(note_to_use); else sp->note_to_use=0; /* seashore.pat in the Midia patch set has no Sustain. I don't understand why, and fixing it by adding the Sustain flag to all looped patches probably breaks something else. We do it anyway. */ if (sp->modes & MODES_LOOPING) sp->modes |= MODES_SUSTAIN; /* Strip any loops and envelopes we're permitted to */ if ((strip_loop==1) && (sp->modes & (MODES_SUSTAIN | MODES_LOOPING | MODES_PINGPONG | MODES_REVERSE))) { ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Removing loop and/or sustain"); sp->modes &=~(MODES_SUSTAIN | MODES_LOOPING | MODES_PINGPONG | MODES_REVERSE); } if (strip_envelope==1) { if (sp->modes & MODES_ENVELOPE) ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Removing envelope"); sp->modes &= ~MODES_ENVELOPE; } else if (strip_envelope != 0) { /* Have to make a guess. */ if (!(sp->modes & (MODES_LOOPING | MODES_PINGPONG | MODES_REVERSE))) { /* No loop? Then what's there to sustain? No envelope needed either... */ sp->modes &= ~(MODES_SUSTAIN|MODES_ENVELOPE); ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - No loop, removing sustain and envelope"); } else if (!memcmp(tmp, "??????", 6) || tmp[11] >= 100) { /* Envelope rates all maxed out? Envelope end at a high "offset"? That's a weird envelope. Take it out. */ sp->modes &= ~MODES_ENVELOPE; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Weirdness, removing envelope"); } else if (!(sp->modes & MODES_SUSTAIN)) { /* No sustain? Then no envelope. I don't know if this is justified, but patches without sustain usually don't need the envelope either... at least the Gravis ones. They're mostly drums. I think. */ sp->modes &= ~MODES_ENVELOPE; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - No sustain, removing envelope"); } } sp->attenuation = 0; for (j=ATTACK; j<DELAY; j++) { sp->envelope_rate[j]= (j<3)? convert_envelope_rate_attack(tmp[j], 11) : convert_envelope_rate(tmp[j]); sp->envelope_offset[j]= convert_envelope_offset(tmp[6+j]); } if (sf2flag) { if (sf2delay > 5) sf2delay = 5; sp->envelope_rate[DELAY] = (int32)( (sf2delay*play_mode->rate) / 1000 ); } else { sp->envelope_rate[DELAY]=0; } sp->envelope_offset[DELAY]=0; for (j=ATTACK; j<DELAY; j++) { sp->modulation_rate[j]=sp->envelope_rate[j]; sp->modulation_offset[j]=sp->envelope_offset[j]; } sp->modulation_rate[DELAY] = sp->modulation_offset[DELAY] = 0; sp->modEnvToFilterFc=0; sp->modEnvToPitch=0; sp->lfo_sweep_increment = 0; sp->lfo_phase_increment = 0; sp->modLfoToFilterFc = 0; sp->vibrato_delay = 0; /* Then read the sample data */ if (sp->data_length/2 > MAX_SAMPLE_SIZE) { goto fail; } sp->data = safe_malloc(sp->data_length + 1); lp->size += sp->data_length + 1; if (1 != fread(sp->data, sp->data_length, 1, fp)) goto fail; if (!(sp->modes & MODES_16BIT)) /* convert to 16-bit data */ { int32 i=sp->data_length; uint8 *cp=(uint8 *)(sp->data); uint16 *tmp,*newdta; tmp=newdta=safe_malloc(sp->data_length*2 + 2); while (i--) *tmp++ = (uint16)(*cp++) << 8; cp=(uint8 *)(sp->data); sp->data = (sample_t *)newdta; free(cp); sp->data_length *= 2; sp->loop_start *= 2; sp->loop_end *= 2; } #ifndef LITTLE_ENDIAN else /* convert to machine byte order */ { int32 i=sp->data_length/2; int16 *tmp=(int16 *)sp->data,s; while (i--) { s=LE_SHORT(*tmp); *tmp++=s; } } #endif if (sp->modes & MODES_UNSIGNED) /* convert to signed data */ { int32 i=sp->data_length/2; int16 *tmp=(int16 *)sp->data; while (i--) *tmp++ ^= 0x8000; } /* Reverse reverse loops and pass them off as normal loops */ if (sp->modes & MODES_REVERSE) { int32 t; /* The GUS apparently plays reverse loops by reversing the whole sample. We do the same because the GUS does not SUCK. */ ctl->cmsg(CMSG_WARNING, VERB_NORMAL, "Reverse loop in %s", name); reverse_data((int16 *)sp->data, 0, sp->data_length/2); t=sp->loop_start; sp->loop_start=sp->data_length - sp->loop_end; sp->loop_end=sp->data_length - t; sp->modes &= ~MODES_REVERSE; sp->modes |= MODES_LOOPING; /* just in case */ } /* If necessary do some anti-aliasing filtering */ if (antialiasing_allowed) antialiasing(sp,play_mode->rate); #ifdef ADJUST_SAMPLE_VOLUMES if (amp!=-1) sp->volume=(FLOAT_T)((amp) / 100.0); else if (sf2flag) sp->volume=(FLOAT_T)((sample_volume) / 255.0); else { /* Try to determine a volume scaling factor for the sample. This is a very crude adjustment, but things sound more balanced with it. Still, this should be a runtime option. */ uint32 i, numsamps=sp->data_length/2; uint32 higher=0, highcount=0; int16 maxamp=0,a; int16 *tmp=(int16 *)sp->data; i = numsamps; while (i--) { a=*tmp++; if (a<0) a=-a; if (a>maxamp) maxamp=a; } tmp=(int16 *)sp->data; i = numsamps; while (i--) { a=*tmp++; if (a<0) a=-a; if (a > 3*maxamp/4) { higher += a; highcount++; } } if (highcount) higher /= highcount; else higher = 10000; sp->volume = (32768.0 * 0.875) / (double)higher ; ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * volume comp: %f", sp->volume); } #else if (amp!=-1) sp->volume=(double)(amp) / 100.0; else sp->volume=1.0; #endif sp->data_length /= 2; /* These are in bytes. Convert into samples. */ sp->loop_start /= 2; sp->loop_end /= 2; sp->data[sp->data_length] = sp->data[sp->data_length-1]; /* Then fractional samples */ sp->data_length <<= FRACTION_BITS; sp->loop_start <<= FRACTION_BITS; sp->loop_end <<= FRACTION_BITS; /* trim off zero data at end */ { int ls = sp->loop_start>>FRACTION_BITS; int le = sp->loop_end>>FRACTION_BITS; int se = sp->data_length>>FRACTION_BITS; while (se > 1 && !sp->data[se-1]) se--; if (le > se) le = se; if (ls >= le) sp->modes &= ~MODES_LOOPING; sp->loop_end = le<<FRACTION_BITS; sp->data_length = se<<FRACTION_BITS; } /* Adjust for fractional loop points. This is a guess. Does anyone know what "fractions" really stands for? */ sp->loop_start |= (fractions & 0x0F) << (FRACTION_BITS-4); sp->loop_end |= ((fractions>>4) & 0x0F) << (FRACTION_BITS-4); /* If this instrument will always be played on the same note, and it's not looped, we can resample it now. */ if (sp->note_to_use && !(sp->modes & MODES_LOOPING)) pre_resample(sp); #ifdef LOOKUP_HACK /* Squash the 16-bit data into 8 bits. */ { uint8 *gulp,*ulp; int16 *swp; int l=sp->data_length >> FRACTION_BITS; gulp=ulp=safe_malloc(l+1); swp=(int16 *)sp->data; while(l--) *ulp++ = (*swp++ >> 8) & 0xFF; free(sp->data); sp->data=(sample_t *)gulp; } #endif if (strip_tail==1) { /* Let's not really, just say we did. */ ctl->cmsg(CMSG_INFO, VERB_DEBUG, " - Stripping tail"); sp->data_length = sp->loop_end; } } /* end of sample loop */ } /* end of stereo layer loop */ } /* end of vlayer loop */ close_file(fp); return headlp; }
bool UNPACK_VALUE(serial_context *ser_cont, as_val **value) { int32_t type = READ_CHAR(ser_cont->fd, ser_cont->line_no, ser_cont->col_no, ser_cont->bytes); if (type == EOF) { err("Error while reading value type"); return false; } switch (type) { case 0xc0: // nil return unpack_nil(ser_cont, value); case 0xc3: // boolean true return unpack_boolean(ser_cont, true, value); case 0xc2: // boolean false return unpack_boolean(ser_cont, false, value); case 0xca: { // float float tmp; return extract_float(ser_cont, &tmp) && unpack_double(ser_cont, tmp, value); } case 0xcb: { // double double tmp; return extract_double(ser_cont, &tmp) && unpack_double(ser_cont, tmp, value); } case 0xd0: { // signed 8 bit integer int8_t tmp; return extract_uint8(ser_cont, (uint8_t *)&tmp) && unpack_integer(ser_cont, tmp, value); } case 0xcc: { // unsigned 8 bit integer uint8_t tmp; return extract_uint8(ser_cont, &tmp) && unpack_integer(ser_cont, tmp, value); } case 0xd1: { // signed 16 bit integer int16_t tmp; return extract_uint16(ser_cont, (uint16_t *)&tmp) && unpack_integer(ser_cont, tmp, value); } case 0xcd: { // unsigned 16 bit integer uint16_t tmp; return extract_uint16(ser_cont, &tmp) && unpack_integer(ser_cont, tmp, value); } case 0xd2: { // signed 32 bit integer int32_t tmp; return extract_uint32(ser_cont, (uint32_t *)&tmp) && unpack_integer(ser_cont, tmp, value); } case 0xce: { // unsigned 32 bit integer uint32_t tmp; return extract_uint32(ser_cont, &tmp) && unpack_integer(ser_cont, tmp, value); } case 0xd3: { // signed 64 bit integer int64_t tmp; return extract_uint64(ser_cont, (uint64_t *)&tmp) && unpack_integer(ser_cont, tmp, value); } case 0xcf: { // unsigned 64 bit integer uint64_t tmp; return extract_uint64(ser_cont, &tmp) && unpack_integer(ser_cont, (int64_t)tmp, value); } case 0xc4: case 0xd9: { // raw bytes with 8 bit header uint8_t size; return extract_uint8(ser_cont, &size) && unpack_blob(ser_cont, size, value); } case 0xc5: case 0xda: { // raw bytes with 16 bit header uint16_t size; return extract_uint16(ser_cont, &size) && unpack_blob(ser_cont, size, value); } case 0xc6: case 0xdb: { // raw bytes with 32 bit header uint32_t size; return extract_uint32(ser_cont, &size) && unpack_blob(ser_cont, size, value); } case 0xdc: { // list with 16 bit header uint16_t size; return extract_uint16(ser_cont, &size) && unpack_list(ser_cont, size, value); } case 0xdd: { // list with 32 bit header uint32_t size; return extract_uint32(ser_cont, &size) && unpack_list(ser_cont, size, value); } case 0xde: { // map with 16 bit header uint16_t size; return extract_uint16(ser_cont, &size) && unpack_map(ser_cont, size, value); } case 0xdf: { // map with 32 bit header uint32_t size; return extract_uint32(ser_cont, &size) && unpack_map(ser_cont, size, value); } default: if ((type & 0xe0) == 0xa0) { // raw bytes with 8 bit combined header return unpack_blob(ser_cont, type & 0x1f, value); } if ((type & 0xf0) == 0x80) { // map with 8 bit combined header return unpack_map(ser_cont, type & 0x0f, value); } if ((type & 0xf0) == 0x90) { // list with 8 bit combined header return unpack_list(ser_cont, type & 0x0f, value); } if (type < 0x80) { // 8 bit combined unsigned integer return unpack_integer(ser_cont, type, value); } if (type >= 0xe0) { // 8 bit combined signed integer return unpack_integer(ser_cont, type - 0xe0 - 32, value); } return false; } }