Beispiel #1
0
//
// 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;
}
Beispiel #2
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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);
}
Beispiel #6
0
// 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;
}
Beispiel #7
0
//
//  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;
}
Beispiel #8
0
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;
}
Beispiel #11
0
//
//  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;
}
Beispiel #12
0
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;
}
Beispiel #13
0
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;
}
Beispiel #14
0
// 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));
}
Beispiel #16
0
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;
}
Beispiel #17
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)
{
  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 */
	{
Beispiel #18
0
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;
}
Beispiel #20
0
// 
//  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;
}
Beispiel #22
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 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;
	}
}