Пример #1
0
static SDL_BlitFunc
SDL_ChooseBlitFunc(Uint32 src_format, Uint32 dst_format, int flags,
                   SDL_BlitFuncEntry * entries)
{
    int i, flagcheck;
    static Uint32 features = 0xffffffff;

    /* Get the available CPU features */
    if (features == 0xffffffff) {
        const char *override = SDL_getenv("SDL_BLIT_CPU_FEATURES");

        features = SDL_CPU_ANY;

        /* Allow an override for testing .. */
        if (override) {
            SDL_sscanf(override, "%u", &features);
        } else {
            if (SDL_HasMMX()) {
                features |= SDL_CPU_MMX;
            }
            if (SDL_HasSSE()) {
                features |= SDL_CPU_SSE;
            }
            if (SDL_HasSSE2()) {
                features |= SDL_CPU_SSE2;
            }
        }
    }
Пример #2
0
/*
=================
Sys_GetProcessorFeatures
=================
*/
cpuFeatures_t Sys_GetProcessorFeatures( void )
{
	cpuFeatures_t features = 0;

#ifndef DEDICATED
	if( SDL_HasRDTSC( ) )    features |= CF_RDTSC;
	if( SDL_HasMMX( ) )      features |= CF_MMX;
	if( SDL_HasSSE( ) )      features |= CF_SSE;
	if( SDL_HasSSE2( ) )     features |= CF_SSE2;
#endif

	return features;
}
Пример #3
0
/*
=================
Sys_GetProcessorFeatures
=================
*/
cpuFeatures_t Sys_GetProcessorFeatures( void )
{
	cpuFeatures_t features = 0;

#ifndef DEDICATED
	if( SDL_HasRDTSC( ) )      features |= CF_RDTSC;
	if( SDL_Has3DNow( ) )      features |= CF_3DNOW;
	if( SDL_HasMMX( ) )        features |= CF_MMX;
	if( SDL_HasSSE( ) )        features |= CF_SSE;
	if( SDL_HasSSE2( ) )       features |= CF_SSE2;
	if( SDL_HasAltiVec( ) )    features |= CF_ALTIVEC;
#endif

	return features;
}
Пример #4
0
CPUfeatures
sysgetprocessorfeatures(void)
{
	CPUfeatures f;
	
	f = 0;
#ifndef DEDICATED
	if(SDL_HasRDTSC()) f |= CF_RDTSC;
	if(SDL_HasMMX()) f |= CF_MMX;
	if(SDL_HasMMXExt()) f |= CF_MMX_EXT;
	if(SDL_Has3DNow()) f |= CF_3DNOW;
	if(SDL_Has3DNowExt()) f |= CF_3DNOW_EXT;
	if(SDL_HasSSE()) f |= CF_SSE;
	if(SDL_HasSSE2()) f |= CF_SSE2;
	if(SDL_HasAltiVec()) f |= CF_ALTIVEC;
#endif
	return f;

}
Пример #5
0
bool allegro_init() {
	cpu_capabilities = 0;
	notes << "Allegro: ";
	
	if(cfgUseSSE && SDL_HasSSE()) cpu_capabilities |= CPU_SSE;
	if(cfgUseMMX && SDL_HasMMX()) cpu_capabilities |= CPU_MMX;
	if(cfgUseMMXExt && SDL_HasMMXExt()) cpu_capabilities |= CPU_MMXPLUS;
	
	if(cpu_capabilities & CPU_SSE) notes << "SSE, "; else notes << "no SSE, ";
	if(cpu_capabilities & CPU_MMX) notes << "MMX, "; else notes << "no MMX, ";
	if(cpu_capabilities & CPU_MMXPLUS) notes << "MMXExt"; else notes << "no MMXExt";
	notes << endl;
	
	screen = create_bitmap_ex(32, SCREEN_W, SCREEN_H);
	notes << "Allegro screen format:" << endl;
	DumpPixelFormat(screen->surf->format);
	
	return true;
}
Пример #6
0
Scale2xScaler::Scale2xScaler() : Scaler()
{
	Scale16Nat = Scale2xScalerInternal<uint16, Manip_Nat2Nat_16, uint16>::Scale;
	Scale16Sta = Scale2xScalerInternal<uint16, Manip_Sta2Nat_16, uint32>::Scale;

	Scale32Nat = Scale2xScalerInternal<uint32, Manip_Nat2Nat_32, uint32>::Scale;
	Scale32Sta = Scale2xScalerInternal<uint32, Manip_Sta2Nat_32, uint32>::Scale;
	Scale32_A888 = Scale2xScalerInternal<uint32, Manip_Nat2Nat_32, uint32>::Scale;
	Scale32_888A = Scale2xScalerInternal<uint32, Manip_Nat2Nat_32, uint32>::Scale;

#if (defined(__GNUC__) && defined(__i386__)) || (defined(_MSC_VER) && defined(_M_IX86))
	if (SDL_HasMMX()) {
		Scale16Nat = Scale2x_16MMX;

		Scale32Nat = Scale2x_32MMX;
		Scale32_A888 = Scale2x_32MMX;
		Scale32_888A = Scale2x_32MMX;
	}
#endif
}
Пример #7
0
void
SDL_BlitCopy(SDL_BlitInfo * info)
{
    SDL_bool overlap;
    Uint8 *src, *dst;
    int w, h;
    int srcskip, dstskip;

    w = info->dst_w * info->dst_fmt->BytesPerPixel;
    h = info->dst_h;
    src = info->src;
    dst = info->dst;
    srcskip = info->src_pitch;
    dstskip = info->dst_pitch;

    /* Properly handle overlapping blits */
    if (src < dst) {
        overlap = (dst < (src + h*srcskip));
    } else {
        overlap = (src < (dst + h*dstskip));
    }
    if (overlap) {
        if ( dst < src ) {
                while ( h-- ) {
                        SDL_memmove(dst, src, w);
                        src += srcskip;
                        dst += dstskip;
                }
        } else {
                src += ((h-1) * srcskip);
                dst += ((h-1) * dstskip);
                while ( h-- ) {
                        SDL_memmove(dst, src, w);
                        src -= srcskip;
                        dst -= dstskip;
                }
        }
        return;
    }

#ifdef __SSE__
    if (SDL_HasSSE() &&
        !((uintptr_t) src & 15) && !(srcskip & 15) &&
        !((uintptr_t) dst & 15) && !(dstskip & 15)) {
        while (h--) {
            SDL_memcpySSE(dst, src, w);
            src += srcskip;
            dst += dstskip;
        }
        return;
    }
#endif

#ifdef __MMX__
    if (SDL_HasMMX() && !(srcskip & 7) && !(dstskip & 7)) {
        while (h--) {
            SDL_memcpyMMX(dst, src, w);
            src += srcskip;
            dst += dstskip;
        }
        _mm_empty();
        return;
    }
#endif

    while (h--) {
        SDL_memcpy(dst, src, w);
        src += srcskip;
        dst += dstskip;
    }
}
Пример #8
0
void SDL_MixAudio (Uint8 *dst, const Uint8 *src, Uint32 len, int volume)
{
	Uint16 format;

	if ( volume == 0 ) {
		return;
	}
	/* Mix the user-level audio format */
	if ( current_audio ) {
		if ( current_audio->convert.needed ) {
			format = current_audio->convert.src_format;
		} else {
			format = current_audio->spec.format;
		}
	} else {
  		/* HACK HACK HACK */
		format = AUDIO_S16;
	}
	switch (format) {

		case AUDIO_U8: {
#if defined(__GNUC__) && defined(__M68000__) && !defined(__mcoldfire__) && defined(SDL_ASSEMBLY_ROUTINES)
			SDL_MixAudio_m68k_U8((char*)dst,(char*)src,(unsigned long)len,(long)volume,(char *)mix8);
#else
			Uint8 src_sample;

			while ( len-- ) {
				src_sample = *src;
				ADJUST_VOLUME_U8(src_sample, volume);
				*dst = mix8[*dst+src_sample];
				++dst;
				++src;
			}
#endif
		}
		break;

		case AUDIO_S8: {
#if defined(SDL_BUGGY_MMX_MIXERS) /* buggy, so we're disabling them. --ryan. */
#if defined(__GNUC__) && defined(__i386__) && defined(SDL_ASSEMBLY_ROUTINES)
			if (SDL_HasMMX())
			{
				SDL_MixAudio_MMX_S8((char*)dst,(char*)src,(unsigned int)len,(int)volume);
			}
			else
#elif ((defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)) && defined(SDL_ASSEMBLY_ROUTINES)
			if (SDL_HasMMX())
			{
				SDL_MixAudio_MMX_S8_VC((char*)dst,(char*)src,(unsigned int)len,(int)volume);
			}
			else
#endif
#endif

#if defined(__GNUC__) && defined(__M68000__) && !defined(__mcoldfire__) && defined(SDL_ASSEMBLY_ROUTINES)
			SDL_MixAudio_m68k_S8((char*)dst,(char*)src,(unsigned long)len,(long)volume);
#else
			{
			Sint8 *dst8, *src8;
			Sint8 src_sample;
			int dst_sample;
			const int max_audioval = ((1<<(8-1))-1);
			const int min_audioval = -(1<<(8-1));

			src8 = (Sint8 *)src;
			dst8 = (Sint8 *)dst;
			while ( len-- ) {
				src_sample = *src8;
				ADJUST_VOLUME(src_sample, volume);
				dst_sample = *dst8 + src_sample;
				if ( dst_sample > max_audioval ) {
					*dst8 = max_audioval;
				} else
				if ( dst_sample < min_audioval ) {
					*dst8 = min_audioval;
				} else {
					*dst8 = dst_sample;
				}
				++dst8;
				++src8;
			}
			}
#endif
		}
		break;

		case AUDIO_S16LSB: {
#if defined(SDL_BUGGY_MMX_MIXERS) /* buggy, so we're disabling them. --ryan. */
#if defined(__GNUC__) && defined(__i386__) && defined(SDL_ASSEMBLY_ROUTINES)
			if (SDL_HasMMX())
			{
				SDL_MixAudio_MMX_S16((char*)dst,(char*)src,(unsigned int)len,(int)volume);
			}
                        else
#elif ((defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)) && defined(SDL_ASSEMBLY_ROUTINES)
			if (SDL_HasMMX())
			{
				SDL_MixAudio_MMX_S16_VC((char*)dst,(char*)src,(unsigned int)len,(int)volume);
			}
			else
#endif
#endif

#if defined(__GNUC__) && defined(__M68000__) && !defined(__mcoldfire__) && defined(SDL_ASSEMBLY_ROUTINES)
			SDL_MixAudio_m68k_S16LSB((short*)dst,(short*)src,(unsigned long)len,(long)volume);
#else
			{
			Sint16 src1, src2;
			int dst_sample;
			const int max_audioval = ((1<<(16-1))-1);
			const int min_audioval = -(1<<(16-1));

			len /= 2;
			while ( len-- ) {
				src1 = ((src[1])<<8|src[0]);
				ADJUST_VOLUME(src1, volume);
				src2 = ((dst[1])<<8|dst[0]);
				src += 2;
				dst_sample = src1+src2;
				if ( dst_sample > max_audioval ) {
					dst_sample = max_audioval;
				} else
				if ( dst_sample < min_audioval ) {
					dst_sample = min_audioval;
				}
				dst[0] = dst_sample&0xFF;
				dst_sample >>= 8;
				dst[1] = dst_sample&0xFF;
				dst += 2;
			}
			}
#endif
		}
		break;

		case AUDIO_S16MSB: {
#if defined(__GNUC__) && defined(__M68000__) && !defined(__mcoldfire__) && defined(SDL_ASSEMBLY_ROUTINES)
			SDL_MixAudio_m68k_S16MSB((short*)dst,(short*)src,(unsigned long)len,(long)volume);
#else
			Sint16 src1, src2;
			int dst_sample;
			const int max_audioval = ((1<<(16-1))-1);
			const int min_audioval = -(1<<(16-1));

			len /= 2;
			while ( len-- ) {
				src1 = ((src[0])<<8|src[1]);
				ADJUST_VOLUME(src1, volume);
				src2 = ((dst[0])<<8|dst[1]);
				src += 2;
				dst_sample = src1+src2;
				if ( dst_sample > max_audioval ) {
					dst_sample = max_audioval;
				} else
				if ( dst_sample < min_audioval ) {
					dst_sample = min_audioval;
				}
				dst[1] = dst_sample&0xFF;
				dst_sample >>= 8;
				dst[0] = dst_sample&0xFF;
				dst += 2;
			}
#endif
		}
		break;

		default: /* If this happens... FIXME! */
			SDL_SetError("SDL_MixAudio(): unknown audio format");
			return;
	}
}
Пример #9
0
bool Application::initialize( int argc, char **argv )
{
    // this is used when hunting for memory leaks
#ifdef YAF3D_ENABLE_HEAPCHECK
    // trigger debugger
    //__asm int 3;
#endif

    std::string arg_levelname;
    // use an ArgumentParser object to manage the program arguments.
    osg::ArgumentParser arguments( &argc,argv );
    osg::ArgumentParser::Parameter levelparam( arg_levelname );
    arguments.read( "-level", arg_levelname ); // read the level file if one given

    int   argpos;
    // set proper game mode
    GameState::get()->setMode( GameState::Standalone );
    if ( ( argpos = arguments.find( "-server" ) ) != 0 )
    {
        GameState::get()->setMode( GameState::Server );
        arguments.remove( argpos );
    }
    else if ( ( argpos = arguments.find( "-client" ) ) != 0 )
    {
        GameState::get()->setMode( GameState::Client );
        arguments.remove( argpos );
    }

    // note: before beginning to initialize the framework modules the media path must be set, 
    //  other modules need it for loading resources etc.
    //-------------------
    std::vector< std::string > path;
    std::string dir;
    {
        char* p_env = getenv( YAF3D_ENV_MEDIA_DIR );
        if ( p_env )
        {
            _mediaPath = p_env;
        }
        else
        {
            dir = getCurrentWorkingDirectory();
            dir = cleanPath( dir );
            dir += "/";
            path.clear();
            explode( dir, "/", &path );
#ifdef LINUX
            dir = "/";
#endif
#ifdef WIN32
            dir = "";
#endif
            for ( size_t cnt = 0; cnt < path.size() - 2; ++cnt )
                dir += path[ cnt ] + "/";

            dir.erase( dir.size() -1 );
            _mediaPath = dir;
            _mediaPath += YAF3D_MEDIA_PATH;
        }
    }

    //-------------------
    // set the ful binary path of application
    _fulBinaryPath = arguments.getApplicationName();
    _fulBinaryPath = cleanPath( _fulBinaryPath );
    _fulBinaryPath = _fulBinaryPath.substr( 0, _fulBinaryPath.rfind( '/' ) );
    //-------------------

    // load the standard configuration before changing to 'Initializing' state
    Configuration::get()->load();

    // set game state
    _p_gameState->setState( GameState::Initializing );

    // setup log system
    {
        std::string loglevel;
        bool        invalidloglevel = false;
        Log::Level  level           = Log::L_ERROR;

        // get the log level from configuration
        Configuration::get()->getSettingValue( YAF3D_GS_LOG_LEVEL, loglevel );

        if ( loglevel == "error" )
            level = Log::L_ERROR;
        else if ( loglevel == "warning" )
            level = Log::L_WARNING;
        else if ( loglevel == "debug" )
            level = Log::L_DEBUG;
        else if ( loglevel == "info" )
            level = Log::L_INFO;
        else 
            invalidloglevel = true;

        // create log sinks with configured log level
        if ( GameState::get()->getMode() != GameState::Server )
            log.addSink( "file", getMediaPath() + std::string( LOG_FILE_NAME ), level );
        else
            log.addSink( "file", getMediaPath() + std::string( LOG_FILE_NAME_SERVER ), level );

        // only the server needs an console stdout
#ifdef YAF3D_HAS_CONSOLE
        log.addSink( "stdout", std::cout, level );
#endif

        // check if we have to report an invalid log level in configuration
        if ( invalidloglevel )
            log_warning << "Application: configuration contains an invalid log level, possible values are: error, warning, debug, info. set to error." << std::endl;
    }

    log.enableSeverityLevelPrinting( false );
    log_info << std::endl;
    log << " *******************************************"    << std::endl;
    log << " * yaf3d -- Yet another Framework 3D       *"    << std::endl;
    log << " * version: " << std::string( YAF3D_VERSION ) << "                          *"  << std::endl;
    log << " * project: Yag2002                        *"    << std::endl;
    log << " * site:    http://yag2002.sourceforge.net *"    << std::endl;
    log << " * contact: [email protected]               *"    << std::endl;
    log << " *******************************************"    << std::endl;
    log << "" << std::endl;
    log.enableSeverityLevelPrinting( true );

    log << "Application: time " << yaf3d::getTimeStamp();

    // print cpu info
    {
        std::stringstream cpuinfo;
        cpuinfo << "Application: CPU supports ";
        if ( SDL_HasRDTSC() ) 
            cpuinfo << "RDTSC ";
        if ( SDL_HasMMX() ) 
            cpuinfo << "MMX ";
        if ( SDL_HasMMXExt() ) 
            cpuinfo << "MMXExt ";
        if ( SDL_Has3DNow() ) 
            cpuinfo << "3DNow ";
        if ( SDL_Has3DNowExt() ) 
            cpuinfo << "3DNowExt ";
        if ( SDL_HasSSE() ) 
            cpuinfo << "SSE ";
        if ( SDL_HasSSE2() ) 
            cpuinfo << "SSE2 ";
        if ( SDL_HasAltiVec() ) 
            cpuinfo << "AltiVec ";

        log << cpuinfo.str() << std::endl;
    }

    log << "Application: initializing viewer" << std::endl;
    log << "Application: using media path: " << _mediaPath << std::endl;

    // setup the viewer
    //----------
    
    // load the display settings
    Configuration::get()->getSettingValue( YAF3D_GS_SCREENWIDTH,  _screenWidth  );
    Configuration::get()->getSettingValue( YAF3D_GS_SCREENHEIGHT, _screenHeight );
    Configuration::get()->getSettingValue( YAF3D_GS_FULLSCREEN,   _fullScreen   );
    unsigned int colorBits = 24;
    Configuration::get()->getSettingValue( YAF3D_GS_COLORBITS, colorBits );

    // init SDL
    SDL_Init( SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE );
    // set the icon and caption title
    SDL_WM_SetCaption( YAF3D_APP_TITLE, NULL );
    SDL_Surface* p_bmpsurface = SDL_LoadBMP( YAF3D_APP_ICON );
    if ( p_bmpsurface )
    {
        Uint32 col = SDL_MapRGB( p_bmpsurface->format, 255, 255, 255 );
        SDL_SetColorKey( p_bmpsurface, SDL_SRCCOLORKEY, col );
        SDL_WM_SetIcon( p_bmpsurface, NULL );
    }
    // enable unicode translation
    SDL_EnableUNICODE( 1 ); 
    SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL ); // enable key repeating

    _p_viewer = new osgSDL::Viewer;
    _rootSceneNode = new osg::Group;
    _rootSceneNode->setName( "_topSceneGroup_" );
	osgSDL::Viewport*   p_viewport = new osgSDL::Viewport( _rootSceneNode.get() );
	osgUtil::SceneView* p_sceneView = p_viewport->getSceneView();
    p_sceneView->setDefaults( osgUtil::SceneView::COMPILE_GLOBJECTS_AT_INIT );
	_p_viewer->addViewport( p_viewport );
    _p_viewer->requestContinuousUpdate( true ); // force event generation for FRAMEs, we need this for animations, etc.
    int flags = SDL_HWSURFACE;
    if ( _fullScreen )
        flags |= SDL_FULLSCREEN;
    if ( GameState::get()->getMode() == GameState::Server )
    {
        SDL_WM_SetCaption( YAF3D_APP_TITLE "-server", NULL );
    }
  	_p_viewer->setDisplayMode( _screenWidth, _screenHeight, colorBits, flags );
    _p_viewer->setCursorEnabled( false );    
    //------------

    // setup keyboard map
    std::string keybType;
    Configuration::get()->getSettingValue( YAF3D_GS_KEYBOARD, keybType );
    log_info << "Application: setup keyboard map to: " << keybType << std::endl;
    if ( keybType == YAF3D_GS_KEYBOARD_ENGLISH )
        KeyMap::get()->setup( KeyMap::English );
    else
        KeyMap::get()->setup( KeyMap::German );

    // get the instance of gui manager
    _p_guiManager = GuiManager::get();
    // setup networking
    _p_networkDevice = NetworkDevice::get();
    // avoid creating of remote clients so long we are initializing the system
    _p_networkDevice->lockObjects();
    if ( GameState::get()->getMode() == GameState::Server )
    {
        log_info << "Application: loading level file '" << arg_levelname << "'" << std::endl;
        // load the level and setup things
        osg::ref_ptr< osg::Group > sceneroot = LevelManager::get()->loadLevel( YAF3D_LEVEL_SERVER_DIR + arg_levelname );
        if ( !sceneroot.valid() )
            return false;

        // start networking before setting up entities
        std::string servername;
        Configuration::get()->getSettingValue( YAF3D_GS_SERVER_NAME, servername );
        NodeInfo nodeinfo( arg_levelname, servername );
        unsigned int channel;
        Configuration::get()->getSettingValue( YAF3D_GS_SERVER_PORT, channel );

        // try to setup server
        try
        {
            _p_networkDevice->setupServer( channel, nodeinfo );
        }
        catch ( const NetworkExpection& e )
        {
            log_error << "Application: error starting server, reason: " << e.what() << std::endl;
            return false;
        }

        // complete level loading
        LevelManager::get()->finalizeLoading();

        // the server needs no drawing
        _p_viewer->setUpdateAllViewports( false );
    }
    else if ( GameState::get()->getMode() == GameState::Client )
    {
        std::string url;
        Configuration::get()->getSettingValue( YAF3D_GS_SERVER_IP, url );
        std::string clientname( "vrc-client" );
        NodeInfo nodeinfo( "", clientname );
        unsigned int channel;
        Configuration::get()->getSettingValue( YAF3D_GS_SERVER_PORT, channel );

        // try to setup client networking
        try
        {
            _p_networkDevice->setupClient( url, channel, nodeinfo );
        }
        catch ( const NetworkExpection& e )
        {
            log_error << "Application: error setting up client networking, reason: " << e.what() << std::endl;
            return false;
        }

        // now load level
        std::string levelname = YAF3D_LEVEL_CLIENT_DIR + _p_networkDevice->getNodeInfo()->getLevelName();
        log_info << "Application: loading level file '" << levelname << "'" << std::endl;
        // load the level and setup things
        osg::ref_ptr< osg::Group > sceneroot = LevelManager::get()->loadLevel( levelname );
        if ( !sceneroot.valid() )
            return false;
        // complete level loading
        LevelManager::get()->finalizeLoading();

        // if we directly start a client with cmd line option then we must send a leave-menu notification to entities
        //  as many entities do special steps when leaving the menu
        EntityNotification notification( YAF3D_NOTIFY_MENU_LEAVE );
        EntityManager::get()->sendNotification( notification );
    }
    else // check for any level file name, so we try to start in Standalone mode
    {
        std::string defaultlevel = arg_levelname.length() ? ( std::string( YAF3D_LEVEL_SALONE_DIR ) + arg_levelname ) : std::string( YAF3D_DEFAULT_LEVEL );
        log_info << "Application: loading level file '" << defaultlevel << "'" << std::endl;
        // set game mode
        GameState::get()->setMode( GameState::Standalone );
        // load the level and setup things
        osg::ref_ptr< osg::Group > sceneroot = LevelManager::get()->loadLevel( defaultlevel );
        if ( !sceneroot.valid() )
            return false;
        // complete level loading
        LevelManager::get()->finalizeLoading();

        // if we directly start a client with cmd line option then we must send a leave-menu notification to entities
        //  as many entities do special steps when leaving the menu
        EntityNotification notification( YAF3D_NOTIFY_MENU_LEAVE );
        EntityManager::get()->sendNotification( notification );
    }

    return true;
}
Пример #10
0
/*  Fill a surface with a gradient which is generated by bilinearly 
    interpolating between four corner color values.  Can take
    a source surface and multiply it into the gradient, but if 
    'src' is NULL, it will generate the gradient without multiplying  */
static void fillBlend(
    SDL_Surface *dst, SDL_Surface *src, BROGUE_DRAW_COLOR *color)
{
    int x, y;
    int lr, lg, lb, rr, rg, rb;
    int ldr, ldg, ldb, rdr, rdg, rdb;
    int w, h;
    BROGUE_DRAW_COLOR ul = color[0];
    BROGUE_DRAW_COLOR ur = color[1];
    BROGUE_DRAW_COLOR bl = color[2];
    BROGUE_DRAW_COLOR br = color[3];
#if defined(__MMX__)
    int mmx = SDL_HasMMX();
#endif
    
    w = dst->w;
    h = dst->h;

    if (src != NULL)
    {
	assert(dst->w == src->w);
	assert(dst->h == src->h);
    }

    lr = clamp(ul.red * 0xFFFF, 0, 0xFFFF);
    lg = clamp(ul.green * 0xFFFF, 0, 0xFFFF);
    lb = clamp(ul.blue * 0xFFFF, 0, 0xFFFF);

    rr = clamp(ur.red * 0xFFFF, 0, 0xFFFF);
    rg = clamp(ur.green * 0xFFFF, 0, 0xFFFF);
    rb = clamp(ur.blue * 0xFFFF, 0, 0xFFFF);

    ldr = (clamp(bl.red * 0xFFFF, 0, 0xFFFF) - lr) / h;
    ldg = (clamp(bl.green * 0xFFFF, 0, 0xFFFF) - lg) / h;
    ldb = (clamp(bl.blue * 0xFFFF, 0, 0xFFFF) - lb) / h;

    rdr = (clamp(br.red * 0xFFFF, 0, 0xFFFF) - rr) / h;
    rdg = (clamp(br.green * 0xFFFF, 0, 0xFFFF) - rg) / h;
    rdb = (clamp(br.blue * 0xFFFF, 0, 0xFFFF) - rb) / h;

    for (y = 0; y < h; y++)
    {
	unsigned char *pix;
	int dr, dg, db;
	int rpp, gpp, bpp, raccum, gaccum, baccum;

	pix = (unsigned char *)dst->pixels + dst->pitch * y;

	dr = rr - lr;
	dg = rg - lg;
	db = rb - lb;

	rpp = dr / w;
	gpp = dg / w;
	bpp = db / w;

	raccum = lr;
	gaccum = lg;
	baccum = lb;

	lr += ldr;
	lg += ldg;
	lb += ldb;

	rr += rdr;
	rg += rdg;
	rb += rdb;

	if (src != NULL)
	{
	    unsigned char *src_pix = (unsigned char *)src->pixels 
		+ src->pitch * y;
	    x = w;

#if defined(__MMX__)
	    /*  MMX is significantly faster.  Use it if the CPU supports it  */
	    if (mmx)
	    {
		__m64 mmx_zero = _m_from_int(0);

		long long ll_color = 
		    ((long long)0xFFFF << 48)
		    | ((long long)raccum << 32)
		    | ((long long)gaccum << 16)
		    | ((long long)baccum);
		__m64 mmx_color = *(__m64 *)&ll_color;

		long long ll_pp = 
		    ((long long)(rpp & 0xFFFF) << 32)
		    | ((long long)(gpp & 0xFFFF) << 16)
		    | ((long long)(bpp & 0xFFFF));
		__m64 mmx_pp = *(__m64 *)&ll_pp;

		while (x >= 2)
		{
		    __m64 src_pair = *(__m64 *)src_pix;
		
		    /*  Separate the left pixel and right pixel  */
		    __m64 left_pix = _mm_unpacklo_pi8(src_pair, mmx_zero);
		    __m64 right_pix = _mm_unpackhi_pi8(src_pair, mmx_zero);
		
		    /*  Multiply the left source by the gradient color  */
		    left_pix = _mm_mullo_pi16(left_pix, 
					      _mm_srli_pi16(mmx_color, 8));
		    /*  Advance the gradient color for the next pixel */
		    mmx_color = _mm_add_pi16(mmx_color, mmx_pp);

		    /*  Multiply the right source by the gradient color  */
		    right_pix = _mm_mullo_pi16(right_pix,
					       _mm_srli_pi16(mmx_color, 8));
		    /*  Advance the gradient  */
		    mmx_color = _mm_add_pi16(mmx_color, mmx_pp); 

		    /*  Recombine the pixels  */
		    __m64 result_pix = _mm_packs_pu16(
			_mm_srli_pi16(left_pix, 8),
			_mm_srli_pi16(right_pix, 8));
		    
		    *(__m64 *)pix = result_pix;

		    src_pix += 8;
		    pix += 8;
		    x -= 2;
		}

		/*  Extract the accumulated gradient value for the potential
		    odd remaining pixel  */
		short *s_color = (short *)&mmx_color;
		raccum = s_color[2];
		gaccum = s_color[1];
		baccum = s_color[0];
	    }
#endif

	    /*  The equivalent slow loop for odd pixels or CPUs without MMX  */
	    while (x > 0)
	    {
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
		pix[3] = src_pix[3];
		pix[2] = (src_pix[2] * raccum) >> 16;
		pix[1] = (src_pix[1] * gaccum) >> 16;
		pix[0] = (src_pix[0] * baccum) >> 16;
#else
		pix[0] = src_pix[0];
		pix[1] = (src_pix[1] * raccum) >> 16;
		pix[2] = (src_pix[2] * gaccum) >> 16;
		pix[3] = (src_pix[3] * baccum) >> 16;
#endif

		raccum += rpp;
		gaccum += gpp;
		baccum += bpp;

		src_pix += 4;
		pix += 4;
		x--;
	    }
	}
	else
	{
Пример #11
0
bool Application::initialize( int argc, char **argv )
{
    // this is used when hunting for memory leaks
#ifdef YAF3D_ENABLE_HEAPCHECK
    // trigger debugger
    //__asm int 3;
#endif

    //! NOTE: on multi-core systems running win32, sometimes a noticable performance drop has been observed
    //        when the application uses more than one cpu for its threads. here we assign only one cpu to the entire app.
#ifdef WIN32
    SYSTEM_INFO sysInfo;
    GetSystemInfo( &sysInfo );
    if ( sysInfo.dwNumberOfProcessors > 1 )
    {
        // take the first cpu for our application
        DWORD_PTR  processAffinityMask = 0x1;
        SetProcessAffinityMask( GetCurrentProcess(), processAffinityMask );
    }
#endif

    // seed the standard pseudo random generator
    time_t t = time( NULL );
    srand( static_cast< unsigned int >( t ) );

    std::string arg_levelname;
    bool        arg_nodefaultlvl = false;
    // use an ArgumentParser object to manage the program arguments.
    osg::ArgumentParser arguments( &argc,argv );
    osg::ArgumentParser::Parameter levelparam( arg_levelname );
    arguments.read( "-level", arg_levelname ); // read the level file if one given

    int   argpos;
    // set proper game mode
    GameState::get()->setMode( GameState::Standalone );
    if ( ( argpos = arguments.find( "-server" ) ) > 0 )
    {
        GameState::get()->setMode( GameState::Server );
        arguments.remove( argpos );
    }
    else if ( ( argpos = arguments.find( "-client" ) ) > 0 )
    {
        GameState::get()->setMode( GameState::Client );
        arguments.remove( argpos );
    }
    if ( ( argpos = arguments.find( "-nodefaultlevel" ) ) > 0 )
    {
        arg_nodefaultlvl = true;
        arguments.remove( argpos );
    }

    // note: before beginning to initialize the framework modules the media path must be set,
    //  other modules need it for loading resources etc.
    //-------------------
    std::vector< std::string > path;
    std::string dir;
    {
        char* p_env = getenv( YAF3D_ENV_MEDIA_DIR );
        if ( p_env )
        {
            _mediaPath = p_env;
        }
        else
        {
            dir = getCurrentWorkingDirectory();
            dir = cleanPath( dir );
            dir += "/";
            path.clear();
            explode( dir, "/", &path );
#ifdef LINUX
            dir = "/";
#endif
#ifdef WIN32
            dir = "";
#endif
            for ( size_t cnt = 0; cnt < path.size() - 2; ++cnt )
                dir += path[ cnt ] + "/";

            dir.erase( dir.size() -1 );
            _mediaPath = dir;
            _mediaPath += YAF3D_MEDIA_PATH;
        }
    }

    //-------------------
    // set the ful binary path of application
    _fulBinaryPath = arguments.getApplicationName();
    _fulBinaryPath = cleanPath( _fulBinaryPath );
    _fulBinaryPath = _fulBinaryPath.substr( 0, _fulBinaryPath.rfind( '/' ) );
    //-------------------

    // load the standard configuration before changing to 'Initializing' state
    Configuration::get()->load();

    // set game state
    _p_gameState->setState( GameState::Initializing );

    // setup log system
    {
        std::string loglevel;
        Log::Level  level = Log::L_ERROR;

        // get the log level from configuration
        Configuration::get()->getSettingValue( YAF3D_GS_LOG_LEVEL, loglevel );

        // check if we have to report an invalid log level in configuration
        if ( loglevel == "error" )
            level = Log::L_ERROR;
        else if ( loglevel == "warning" )
            level = Log::L_WARNING;
        else if ( loglevel == "debug" )
            level = Log::L_DEBUG;
        else if ( loglevel == "info" )
            level = Log::L_INFO;
        else if ( loglevel == "verbose" )
            level = Log::L_VERBOSE;
        else
            log_warning << "Application: configuration contains an invalid log level, possible values are: error, warning, debug, info, verbose. set to error." << std::endl;

        // create log sinks with configured log level
        if ( GameState::get()->getMode() != GameState::Server )
            log_out.addSink( "file", getMediaPath() + std::string( LOG_FILE_NAME ), level );
        else
            log_out.addSink( "file", getMediaPath() + std::string( LOG_FILE_NAME_SERVER ), level );

        // only the server needs an console stdout
#ifdef YAF3D_HAS_CONSOLE
        log_out.addSink( "stdout", std::cout, level );
#endif

    }

    log_out.enableSeverityLevelPrinting( false );
    log_info << std::endl;
    log_out << " *******************************************"    << std::endl;
    log_out << " * yaf3d -- Yet another Framework 3D       *"    << std::endl;
    log_out << " * version: " << std::string( YAF3D_VERSION ) << "                          *"  << std::endl;
    log_out << " * project: Yag2002                        *"    << std::endl;
    log_out << " * site:    http://yag2002.sourceforge.net *"    << std::endl;
    log_out << " * contact: [email protected] *"    << std::endl;
    log_out << " *******************************************"    << std::endl;
    log_out << "" << std::endl;
    log_out.enableSeverityLevelPrinting( true );

    log_out << "Application: time " << yaf3d::getTimeStamp();

    // print cpu info
    {
        std::stringstream cpuinfo;
        cpuinfo << "Application: CPU supports ";
        if ( SDL_HasRDTSC() )
            cpuinfo << "RDTSC ";
        if ( SDL_HasMMX() )
            cpuinfo << "MMX ";
        if ( SDL_HasMMXExt() )
            cpuinfo << "MMXExt ";
        if ( SDL_Has3DNow() )
            cpuinfo << "3DNow ";
        if ( SDL_Has3DNowExt() )
            cpuinfo << "3DNowExt ";
        if ( SDL_HasSSE() )
            cpuinfo << "SSE ";
        if ( SDL_HasSSE2() )
            cpuinfo << "SSE2 ";
        if ( SDL_HasAltiVec() )
            cpuinfo << "AltiVec ";

        log_out << cpuinfo.str() << std::endl;
    }

    // implement the signal handler
    implementSignalHandler();

    log_out << "Application: using media path: " << _mediaPath << std::endl;
    log_out << "Application: setup virtual file system" << std::endl;

    try
    {
        FileSystem::get()->initialize( argv );
        FileSystem::get()->mountResource( _mediaPath, "/" );
        if ( fileExists( _mediaPath + YAF3D_MEDIA_PACK ) )
        {
            FileSystem::get()->mountResource( _mediaPath + YAF3D_MEDIA_PACK, "/" );
        }
    }
    catch ( const FileSystemException& e )
    {
        log_error << "Application: problem occured while setting up the virtual file system!" << std::endl;
        log_error << " reason:" << e.what() << std::endl;
        return false;
    }

    // setup the viewer
    //----------

    // load the display settings
    log_out << "Application: initializing viewer" << std::endl;
    Configuration::get()->getSettingValue( YAF3D_GS_SCREENWIDTH,  _screenWidth  );
    Configuration::get()->getSettingValue( YAF3D_GS_SCREENHEIGHT, _screenHeight );
    Configuration::get()->getSettingValue( YAF3D_GS_FULLSCREEN,   _fullScreen   );
    unsigned int colorBits = 24;
    Configuration::get()->getSettingValue( YAF3D_GS_COLORBITS, colorBits );

    // set the icon and caption title only for non-servers
    if ( GameState::get()->getMode() != GameState::Server )
    {
       // init SDL with video
        SDL_Init( SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE );

        // set application window's title
        _appWindowTitle = YAF3D_APP_TITLE " " YAF3D_VERSION;
        setWindowTitle( _appWindowTitle );

        SDL_Surface* p_bmpsurface = SDL_LoadBMP( YAF3D_APP_ICON );
        if ( p_bmpsurface )
        {
            Uint32 col = SDL_MapRGB( p_bmpsurface->format, 255, 255, 255 );
            SDL_SetColorKey( p_bmpsurface, SDL_SRCCOLORKEY, col );
            SDL_WM_SetIcon( p_bmpsurface, NULL );
        }
    }
    else
    {
        // init SDl witout video for server
        SDL_Init( SDL_INIT_NOPARACHUTE );
    }
    // enable unicode translation
    SDL_EnableUNICODE( 1 );
    SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL ); // enable key repeating

    _p_viewer = new osgSDL::Viewer;
    _rootSceneNode = new osg::Group;
    _rootSceneNode->setName( "_topSceneGroup_" );
    osgSDL::Viewport*   p_viewport = new osgSDL::Viewport( _rootSceneNode.get() );
    osgUtil::SceneView* p_sceneView = p_viewport->getSceneView();
    p_sceneView->setDefaults( osgUtil::SceneView::COMPILE_GLOBJECTS_AT_INIT );
    _p_viewer->addViewport( p_viewport );
    _p_viewer->requestContinuousUpdate( true ); // force event generation for FRAMEs, we need this for animations, etc.

    int flags = SDL_HWSURFACE;
    if ( _fullScreen )
        flags |= SDL_FULLSCREEN;

    _p_viewer->setDisplayMode( _screenWidth, _screenHeight, colorBits, flags );
    _p_viewer->setCursorEnabled( false );
    //------------

    // setup keyboard map
    std::string keybType;
    Configuration::get()->getSettingValue( YAF3D_GS_KEYBOARD, keybType );
    log_info << "Application: setup keyboard map to: " << keybType << std::endl;
    if ( keybType == YAF3D_GS_KEYBOARD_ENGLISH )
        KeyMap::get()->setup( KeyMap::English );
    else
        KeyMap::get()->setup( KeyMap::German );

    // get the instance of gui manager
    _p_guiManager = GuiManager::get();

    // setup networking
    _p_networkDevice = NetworkDevice::get();
    if ( GameState::get()->getMode() == GameState::Server )
    {
        log_info << "Application: loading level file '" << arg_levelname << "'" << std::endl;
        // load the level and setup things
        osg::ref_ptr< osg::Group > sceneroot = LevelManager::get()->loadLevel( YAF3D_LEVEL_SERVER_DIR + arg_levelname );
        if ( !sceneroot.valid() )
        {
            log_error << "Application: could not load level '" << YAF3D_LEVEL_SERVER_DIR + arg_levelname << "'" << std::endl;
            return false;
        }

        // append the level node to scene root node
        _rootSceneNode->addChild( sceneroot.get() );

        // start networking before setting up entities
        std::string servername;
        Configuration::get()->getSettingValue( YAF3D_GS_SERVER_NAME, servername );
        NodeInfo nodeinfo( arg_levelname, servername );
        unsigned int channel = 0;
        Configuration::get()->getSettingValue( YAF3D_GS_SERVER_PORT, channel );
        bool needsAuth = false;
        Configuration::get()->getSettingValue( YAF3D_GS_SERVER_AUTH, needsAuth );
        nodeinfo.setNeedAuthentification( needsAuth );

        // try to setup server
        try
        {
            _p_networkDevice->setupServer( channel, nodeinfo );
        }
        catch ( const NetworkException& e )
        {
            log_error << "Application: error starting server, reason: " << e.what() << std::endl;
            return false;
        }

        // complete level loading
        LevelManager::get()->finalizeLoading();

        // the server needs no drawing
        _p_viewer->setUpdateAllViewports( false );
    }
    else if ( GameState::get()->getMode() == GameState::Client )
    {
        std::string url;
        Configuration::get()->getSettingValue( YAF3D_GS_SERVER_IP, url );
        std::string clientname( "vrc-client" );
        NodeInfo nodeinfo( "", clientname );
        unsigned int channel = 0;
        Configuration::get()->getSettingValue( YAF3D_GS_SERVER_PORT, channel );

        // try to setup client networking
        try
        {
            _p_networkDevice->setupClient( url, channel, nodeinfo );
        }
        catch ( const NetworkException& e )
        {
            log_error << "Application: error setting up client networking, reason: " << e.what() << std::endl;
            return false;
        }

        // now load level
        std::string levelname = YAF3D_LEVEL_CLIENT_DIR + nodeinfo.getLevelName();
        log_info << "Application: loading level file '" << levelname << "'" << std::endl;
        // load the level and setup things
        osg::ref_ptr< osg::Group > sceneroot = LevelManager::get()->loadLevel( levelname );
        if ( !sceneroot.valid() )
        {
            log_error << "Application: could not load level '" << levelname << "'" << std::endl;
            return false;
        }

        // append the level node to scene root node
        _rootSceneNode->addChild( sceneroot.get() );

        // complete level loading
        LevelManager::get()->finalizeLoading();

        // if we directly start a client with cmd line option then we must send a leave-menu notification to entities
        //  as many entities do special steps when leaving the menu
        EntityNotification notification( YAF3D_NOTIFY_MENU_LEAVE );
        EntityManager::get()->sendNotification( notification );
    }
    else if ( !arg_nodefaultlvl ) // check for any level file name, so we try to start in Standalone mode if not no-default-level option is given
    {
        std::string defaultlevel = arg_levelname.length() ? ( std::string( YAF3D_LEVEL_SALONE_DIR ) + arg_levelname ) : std::string( YAF3D_DEFAULT_LEVEL );
        log_info << "Application: loading level file '" << defaultlevel << "'" << std::endl;
        // set game mode
        GameState::get()->setMode( GameState::Standalone );
        // load the level and setup things
        osg::ref_ptr< osg::Group > sceneroot = LevelManager::get()->loadLevel( defaultlevel );
        if ( !sceneroot.valid() )
        {
            log_error << "Application: could not load level '" << defaultlevel << "'" << std::endl;
            return false;
        }

        // append the level node to scene root node
        _rootSceneNode->addChild( sceneroot.get() );

        // complete level loading
        LevelManager::get()->finalizeLoading();

        // if we directly start a level with cmd line option then we must send a leave-menu notification to entities
        //  as many entities do special steps when leaving the menu
        if ( arg_levelname.length() )
        {
            EntityNotification notification( YAF3D_NOTIFY_MENU_LEAVE );
            EntityManager::get()->sendNotification( notification );
        }
    }

    if ( arg_nodefaultlvl )
    {
        // set game mode to standalone
        GameState::get()->setMode( GameState::Standalone );

        // setup the level manager
        LevelManager::get()->finalizeLoading();
        // setup the root node
        _rootSceneNode->addChild( LevelManager::get()->getTopNodeGroup().get() );
    }

    // setup the shadow mananger now
    if ( GameState::get()->getMode() != GameState::Server )
    {
        bool shadow = true;
        // if glsl is not available then disable dynamic shadow flag in configuration
        if ( !yaf3d::isGlslAvailable() )
        {
            log_info << "Dynamic shadows disabled as GLSL is not available!" << std::endl;
            shadow = false;
            yaf3d::Configuration::get()->setSettingValue( YAF3D_GS_SHADOW_ENABLE, shadow );
            yaf3d::Configuration::get()->store();
        }

        bool shadowEnable = false;
        Configuration::get()->getSettingValue( YAF3D_GS_SHADOW_ENABLE, shadowEnable );

        if ( shadow && shadowEnable )
        {
            unsigned int shadowTexSizeX = 0, shadowTexSizeY = 0, shadowTexChannel = 0;
            yaf3d::Configuration::get()->getSettingValue( YAF3D_GS_SHADOW_TEXSIZEX, shadowTexSizeX );
            yaf3d::Configuration::get()->getSettingValue( YAF3D_GS_SHADOW_TEXSIZEY, shadowTexSizeY );
            yaf3d::Configuration::get()->getSettingValue( YAF3D_GS_SHADOW_TEXCHANNEL, shadowTexChannel );
            ShadowManager::get()->setup( shadowTexSizeX, shadowTexSizeY, shadowTexChannel );
        }
    }

    // store sound manager reference for faster access in loop
    _p_soundManager = SoundManager::get();

    // from now on game state can handle application window state changes
    _p_gameState->initAppWindowStateHandler();

    // setup local app window state handler
    _p_appWindowStateHandler = new AppWindowStateHandler( this );

    return true;
}
Пример #12
0
/*
================
Sys_GetCPUId
================
*/
cpuid_t Sys_GetCPUId()
{
    int flags;

    // check for an AMD
    flags = CPUID_GENERIC;

    // check for Multi Media Extensions
    if( SDL_HasMMX() )
    {
        flags |= CPUID_MMX;
    }

    // check for 3DNow!
    if( SDL_Has3DNow() )
    {
        flags |= CPUID_3DNOW;
    }

    // check for Streaming SIMD Extensions
    if( SDL_HasSSE() )
    {
        flags |= CPUID_SSE | CPUID_FTZ;
    }

    // check for Streaming SIMD Extensions 2
    if( SDL_HasSSE2() )
    {
        flags |= CPUID_SSE2;
    }

    // check for Streaming SIMD Extensions 3 aka Prescott's New Instructions
#if 0 //SDL_VERSION_ATLEAST(2,0,0)
    if( SDL_HasSSE3() )
    {
        flags |= CPUID_SSE3;
    }
#endif

    /*
    // check for Hyper-Threading Technology
    if( HasHTT() )
    {
    	flags |= CPUID_HTT;
    }

    // check for Conditional Move (CMOV) and fast floating point comparison (FCOMI) instructions
    if( HasCMOV() )
    {
    	flags |= CPUID_CMOV;
    }

    // check for Denormals-Are-Zero mode
    if( HasDAZ() )
    {
    	flags |= CPUID_DAZ;
    }
    */

    return ( cpuid_t )flags;
}
void
SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
                   Uint32 len, int volume)
{
    if (volume == 0) {
        return;
    }

    switch (format) {

    case AUDIO_U8:
        {
#if defined(__GNUC__) && defined(__M68000__) && !defined(__mcoldfire__) && defined(SDL_ASSEMBLY_ROUTINES)
            SDL_MixAudio_m68k_U8((char *) dst, (char *) src,
                                 (unsigned long) len, (long) volume,
                                 (char *) mix8);
#else
            Uint8 src_sample;

            while (len--) {
                src_sample = *src;
                ADJUST_VOLUME_U8(src_sample, volume);
                *dst = mix8[*dst + src_sample];
                ++dst;
                ++src;
            }
#endif
        }
        break;

    case AUDIO_S8:
        {
#if defined(SDL_BUGGY_MMX_MIXERS) /* buggy, so we're disabling them. --ryan. */
#if defined(__GNUC__) && defined(__i386__) && defined(SDL_ASSEMBLY_ROUTINES)
            if (SDL_HasMMX()) {
                SDL_MixAudio_MMX_S8((char *) dst, (char *) src,
                                    (unsigned int) len, (int) volume);
            } else
#elif ((defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)) && defined(SDL_ASSEMBLY_ROUTINES)
            if (SDL_HasMMX()) {
                SDL_MixAudio_MMX_S8_VC((char *) dst, (char *) src,
                                       (unsigned int) len, (int) volume);
            } else
#endif
#endif
#if defined(__GNUC__) && defined(__M68000__) && !defined(__mcoldfire__) && defined(SDL_ASSEMBLY_ROUTINES)
                SDL_MixAudio_m68k_S8((char *) dst, (char *) src,
                                     (unsigned long) len, (long) volume);
#else
            {
                Sint8 *dst8, *src8;
                Sint8 src_sample;
                int dst_sample;
                const int max_audioval = ((1 << (8 - 1)) - 1);
                const int min_audioval = -(1 << (8 - 1));

                src8 = (Sint8 *) src;
                dst8 = (Sint8 *) dst;
                while (len--) {
                    src_sample = *src8;
                    ADJUST_VOLUME(src_sample, volume);
                    dst_sample = *dst8 + src_sample;
                    if (dst_sample > max_audioval) {
                        *dst8 = max_audioval;
                    } else if (dst_sample < min_audioval) {
                        *dst8 = min_audioval;
                    } else {
                        *dst8 = dst_sample;
                    }
                    ++dst8;
                    ++src8;
                }
            }
#endif
        }
        break;

    case AUDIO_S16LSB:
        {
#if defined(SDL_BUGGY_MMX_MIXERS) /* buggy, so we're disabling them. --ryan. */
#if defined(__GNUC__) && defined(__i386__) && defined(SDL_ASSEMBLY_ROUTINES)
            if (SDL_HasMMX()) {
                SDL_MixAudio_MMX_S16((char *) dst, (char *) src,
                                     (unsigned int) len, (int) volume);
            } else
#elif ((defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)) && defined(SDL_ASSEMBLY_ROUTINES)
            if (SDL_HasMMX()) {
                SDL_MixAudio_MMX_S16_VC((char *) dst, (char *) src,
                                        (unsigned int) len, (int) volume);
            } else
#endif
#endif
#if defined(__GNUC__) && defined(__M68000__) && !defined(__mcoldfire__) && defined(SDL_ASSEMBLY_ROUTINES)
                SDL_MixAudio_m68k_S16LSB((short *) dst, (short *) src,
                                         (unsigned long) len, (long) volume);
#else
            {
                Sint16 src1, src2;
                int dst_sample;
                const int max_audioval = ((1 << (16 - 1)) - 1);
                const int min_audioval = -(1 << (16 - 1));

                len /= 2;
                while (len--) {
                    src1 = ((src[1]) << 8 | src[0]);
                    ADJUST_VOLUME(src1, volume);
                    src2 = ((dst[1]) << 8 | dst[0]);
                    src += 2;
                    dst_sample = src1 + src2;
                    if (dst_sample > max_audioval) {
                        dst_sample = max_audioval;
                    } else if (dst_sample < min_audioval) {
                        dst_sample = min_audioval;
                    }
                    dst[0] = dst_sample & 0xFF;
                    dst_sample >>= 8;
                    dst[1] = dst_sample & 0xFF;
                    dst += 2;
                }
            }
#endif
        }
        break;

    case AUDIO_S16MSB:
        {
#if defined(__GNUC__) && defined(__M68000__) && !defined(__mcoldfire__) && defined(SDL_ASSEMBLY_ROUTINES)
            SDL_MixAudio_m68k_S16MSB((short *) dst, (short *) src,
                                     (unsigned long) len, (long) volume);
#else
            Sint16 src1, src2;
            int dst_sample;
            const int max_audioval = ((1 << (16 - 1)) - 1);
            const int min_audioval = -(1 << (16 - 1));

            len /= 2;
            while (len--) {
                src1 = ((src[0]) << 8 | src[1]);
                ADJUST_VOLUME(src1, volume);
                src2 = ((dst[0]) << 8 | dst[1]);
                src += 2;
                dst_sample = src1 + src2;
                if (dst_sample > max_audioval) {
                    dst_sample = max_audioval;
                } else if (dst_sample < min_audioval) {
                    dst_sample = min_audioval;
                }
                dst[1] = dst_sample & 0xFF;
                dst_sample >>= 8;
                dst[0] = dst_sample & 0xFF;
                dst += 2;
            }
#endif
        }
        break;

    case AUDIO_S32LSB:
        {
            const Uint32 *src32 = (Uint32 *) src;
            Uint32 *dst32 = (Uint32 *) dst;
            Sint64 src1, src2;
            Sint64 dst_sample;
            const Sint64 max_audioval = ((((Sint64) 1) << (32 - 1)) - 1);
            const Sint64 min_audioval = -(((Sint64) 1) << (32 - 1));

            len /= 4;
            while (len--) {
                src1 = (Sint64) ((Sint32) SDL_SwapLE32(*src32));
                src32++;
                ADJUST_VOLUME(src1, volume);
                src2 = (Sint64) ((Sint32) SDL_SwapLE32(*dst32));
                dst_sample = src1 + src2;
                if (dst_sample > max_audioval) {
                    dst_sample = max_audioval;
                } else if (dst_sample < min_audioval) {
                    dst_sample = min_audioval;
                }
                *(dst32++) = SDL_SwapLE32((Uint32) ((Sint32) dst_sample));
            }
        }
        break;

    case AUDIO_S32MSB:
        {
            const Uint32 *src32 = (Uint32 *) src;
            Uint32 *dst32 = (Uint32 *) dst;
            Sint64 src1, src2;
            Sint64 dst_sample;
            const Sint64 max_audioval = ((((Sint64) 1) << (32 - 1)) - 1);
            const Sint64 min_audioval = -(((Sint64) 1) << (32 - 1));

            len /= 4;
            while (len--) {
                src1 = (Sint64) ((Sint32) SDL_SwapBE32(*src32));
                src32++;
                ADJUST_VOLUME(src1, volume);
                src2 = (Sint64) ((Sint32) SDL_SwapBE32(*dst32));
                dst_sample = src1 + src2;
                if (dst_sample > max_audioval) {
                    dst_sample = max_audioval;
                } else if (dst_sample < min_audioval) {
                    dst_sample = min_audioval;
                }
                *(dst32++) = SDL_SwapBE32((Uint32) ((Sint32) dst_sample));
            }
        }
        break;

    case AUDIO_F32LSB:
        {
            const float fmaxvolume = 1.0f / ((float) SDL_MIX_MAXVOLUME);
            const float fvolume = (float) volume;
            const float *src32 = (float *) src;
            float *dst32 = (float *) dst;
            float src1, src2;
            double dst_sample;
            /* !!! FIXME: are these right? */
            const double max_audioval = 3.402823466e+38F;
            const double min_audioval = -3.402823466e+38F;

            len /= 4;
            while (len--) {
                src1 = ((SDL_SwapFloatLE(*src32) * fvolume) * fmaxvolume);
                src2 = SDL_SwapFloatLE(*dst32);
                src32++;

                dst_sample = ((double) src1) + ((double) src2);
                if (dst_sample > max_audioval) {
                    dst_sample = max_audioval;
                } else if (dst_sample < min_audioval) {
                    dst_sample = min_audioval;
                }
                *(dst32++) = SDL_SwapFloatLE((float) dst_sample);
            }
        }
        break;

    case AUDIO_F32MSB:
        {
            const float fmaxvolume = 1.0f / ((float) SDL_MIX_MAXVOLUME);
            const float fvolume = (float) volume;
            const float *src32 = (float *) src;
            float *dst32 = (float *) dst;
            float src1, src2;
            double dst_sample;
            /* !!! FIXME: are these right? */
            const double max_audioval = 3.402823466e+38F;
            const double min_audioval = -3.402823466e+38F;

            len /= 4;
            while (len--) {
                src1 = ((SDL_SwapFloatBE(*src32) * fvolume) * fmaxvolume);
                src2 = SDL_SwapFloatBE(*dst32);
                src32++;

                dst_sample = ((double) src1) + ((double) src2);
                if (dst_sample > max_audioval) {
                    dst_sample = max_audioval;
                } else if (dst_sample < min_audioval) {
                    dst_sample = min_audioval;
                }
                *(dst32++) = SDL_SwapFloatBE((float) dst_sample);
            }
        }
        break;

    default:                   /* If this happens... FIXME! */
        SDL_SetError("SDL_MixAudio(): unknown audio format");
        return;
    }
}
Пример #14
0
static mrb_value
mrb_sdl2_cpuinfo_has_mmx(mrb_state *mrb, mrb_value self)
{
  return (SDL_HasMMX() == SDL_FALSE) ? mrb_false_value() : mrb_true_value();
}