예제 #1
0
파일: psx.c 프로젝트: 9a3eedi/Droidsound
/////////////////////////////////////////////////////////////////////////////
//
// Upload PS-X EXE - must INCLUDE the header.
// If the header includes the strings "North America", "Japan", or "Europe",
// the appropriate refresh rate is set.
// Returns nonzero on error.
// Will return error for PS2.
//
sint32 EMU_CALL psx_upload_psxexe(void *state, void *program, uint32 size) {
  uint32 init_pc;
  uint32 init_sp;
  uint32 text_start;
  uint32 text_size;

  if(PSXSTATE->version != 1) return -1;

  if(size < 0x801) return -1;
  if(memcmp(program, "PS-X EXE", 8)) return -1;

  text_start = get32lsb(((uint8*)program) + 0x18);
  text_size  = get32lsb(((uint8*)program) + 0x1C);
  init_pc    = get32lsb(((uint8*)program) + 0x10);
  init_sp    = get32lsb(((uint8*)program) + 0x30);

  // Try to determine the region, or leave it at the default if it's not found
       if(string_exists(program, 0x800, "North America")) { psx_set_refresh(state, 60); }
  else if(string_exists(program, 0x800, "Japan"        )) { psx_set_refresh(state, 60); }
  else if(string_exists(program, 0x800, "Europe"       )) { psx_set_refresh(state, 50); }

  if(text_size > (size - 0x800)) { text_size = (size - 0x800); }

  iop_upload_to_ram(IOPSTATE, text_start, ((uint8*)program) + 0x800, text_size);

  r3000_setreg(iop_get_r3000_state(IOPSTATE), R3000_REG_PC    , init_pc);
  r3000_setreg(iop_get_r3000_state(IOPSTATE), R3000_REG_GEN+29, init_sp);

  return 0;
}
예제 #2
0
파일: heplug.c 프로젝트: wothke/webpsx
int he_seek_sample (DB_fileinfo_t *_info, int sample) {
    he_info_t *info = (he_info_t *)_info;
    unsigned long int s = sample;
    if (s < info->samples_played) {
        struct psf_load_state state;
        memset( &state, 0, sizeof(state) );

        state.emu = info->emu;

        if ( !info->psf2fs ) {
            psx_clear_state( info->emu, 1 );
            if ( psf_load( info->path, &psf_file_system, 1, psf1_load, &state, psf_info_meta, &state, 0 ) <= 0 ) {
                trace( "he: invalid PSF file\n" );
                return -1;
            }
        } else {
            psx_clear_state( info->emu, 2 );
            if ( psf_load( info->path, &psf_file_system, 2, 0, 0, psf_info_meta, &state, 0 ) <= 0 ) {
                trace( "he: invalid PSF file\n" );
                return -1;
            }
            psx_set_readfile( info->emu, virtual_readfile, info->psf2fs );
        }

        if ( state.refresh )
            psx_set_refresh( info->emu, state.refresh );

        info->samples_played = 0;
		
		free_tags(state.tags);
    }
    while ( info->samples_played < s ) {
        int to_skip = s - info->samples_played;
        if ( to_skip > 32768 ) to_skip = 1024;
        if ( he_read( _info, NULL, to_skip * 2 * sizeof(short) ) < 0 ) {
            return -1;
        }
    }
    _info->readpos = s/(float)_info->fmt.samplerate;
    return 0;
}
예제 #3
0
파일: heplug.c 프로젝트: wothke/webpsx
int he_init (DB_fileinfo_t *_info, const char * uri) {
	
    he_info_t *info = (he_info_t *)_info;
	info->path = strdup( uri );
	
 //   int psf_version = psf_load( uri, &psf_file_system, 0, 0, 0, 0, 0, 0 );
	requiredLib[0]= 0;
    int psf_version = psf_load( uri, &psf_file_system, 0, 0, 0, psf_lib_meta, 0, 0 );
    if (psf_version < 0) {
        trace ("he: failed to open %s\n", uri);
        return -1;
    }
	
	if (strlen(requiredLib)) {
		// lib must be loaded here or else the psf loading will fail..
		// (enter "retry-mode" if something is missing)
		// make sure the file will be available in the FS when the song asks for it later..		
		char tmpFileName[PATH_MAX];   
		char *p= strrchr(uri, '/');		
		int pathlen= p?(p-uri+1):0;
		memcpy(tmpFileName, uri, pathlen);
		snprintf(tmpFileName+pathlen, PATH_MAX-pathlen, "%s", requiredLib);

		int r= psx_request_file(tmpFileName);	// trigger load & check if ready
		if (r <0) {
			return -1; // file not ready
		}
	}
	
    char he_bios_path[PATH_MAX];
	memset(he_bios_path, 0, PATH_MAX);	// set specific BIOS here if needed

	he_install_bios(he_bios_path);		
    psx_init();

    struct psf_load_state state;
    memset( &state, 0, sizeof(state) );

    state.first = 1;
	
	state.emu= set_emu(info, malloc( psx_get_state_size( psf_version ) ));
    if ( !state.emu ) {
        trace( "he: out of memory\n" );
        return -1;
    }

    psx_clear_state( state.emu, psf_version );

    if ( psf_version == 1 ) {
        if ( psf_load( uri, &psf_file_system, 1, psf1_load, &state, psf_info_meta, &state, 0 ) <= 0 ) {
            trace( "he: invalid PSF file\n" );
            return -1;
        }
    } else if ( psf_version == 2 ) {
        info->psf2fs = psf2fs_create();
        if ( !info->psf2fs ) {
            trace( "he: out of memory\n" );
            return -1;
        }
        if ( psf_load( uri, &psf_file_system, 2, psf2fs_load_callback, info->psf2fs, psf_info_meta, &state, 0 ) <= 0 ) {
            trace( "he: invalid PSF file\n" );
            return -1;
        }
        psx_set_readfile( info->emu, virtual_readfile, info->psf2fs );
    }

    if ( state.refresh )
        psx_set_refresh( info->emu, state.refresh );

    int tag_song_ms = state.tag_song_ms;
    int tag_fade_ms = state.tag_fade_ms;

    if (!tag_song_ms)
    {
        tag_song_ms = ( 2 * 60 + 50 ) * 1000;
        tag_fade_ms =            10   * 1000;
    }

    const int srate = psf_version == 2 ? 48000 : 44100;

    info->samples_played = 0;
    info->samples_to_play = (uint64_t)tag_song_ms * (uint64_t)srate / 1000;
    info->samples_to_fade = (uint64_t)tag_fade_ms * (uint64_t)srate / 1000;

    _info->fmt.channels = 2;
    _info->fmt.bps = 16;
    _info->fmt.samplerate = srate;
	_info->readpos = 0;

	free_tags(state.tags);
	
    return 0;
}