changeset 477:8fc500c08b61 trunk

[svn] SPC length detection c/o Kiyoshi Aman <kiyoshi.aman -at- gmail.com>
author nenolod
date Thu, 19 Jan 2006 19:31:32 -0800
parents 0389b92ed03f
children 5064517c685c
files Plugins/Input/console/Audacious_Driver.cpp Plugins/Input/console/Spc_Emu.cpp Plugins/Input/console/Spc_Emu.h
diffstat 3 files changed, 126 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/Plugins/Input/console/Audacious_Driver.cpp	Thu Jan 19 15:45:42 2006 -0800
+++ b/Plugins/Input/console/Audacious_Driver.cpp	Thu Jan 19 19:31:32 2006 -0800
@@ -27,6 +27,8 @@
 
 #include <cstring>
 #include <stdio.h>
+#include <cstdlib>
+#include <cctype>
 
 static Spc_Emu *spc = NULL;
 static Nsf_Emu *nsf = NULL;
@@ -81,10 +83,21 @@
 	return 0;
 }
 
+static gint strtoi(gchar *buf,size_t len) {
+	guint num = 0;
+	while (len && isdigit(*buf)) {
+		num *= 10;
+		num += *buf - '0';
+		buf++;
+		len--;
+	}
+	return num;
+}
+
 static gchar *get_title_spc(gchar *filename)
 {
 	gchar *title;
-	Emu_Std_Reader reader;
+	Spc_Reader reader;
 	Spc_Emu::header_t header;
 
 	reader.open(filename);
@@ -257,7 +270,7 @@
 static void play_file_spc(char *filename)
 {
 	gchar *name;
-	Emu_Std_Reader reader;
+	Spc_Reader reader;
 	Spc_Emu::header_t header;
 	gint samplerate;
 
@@ -278,7 +291,12 @@
 
 	name = get_title(filename);
 
-	if (audcfg.loop_length)
+	spc->length = strtoi(header.len_secs,3);
+
+	if (spc->length > 0)
+		console_ip.set_info(name, spc->length * 1000,
+			spc->voice_count() * 1000, samplerate, 2);
+	else if (audcfg.loop_length)
 		console_ip.set_info(name, audcfg.loop_length * 1000, 
 			spc->voice_count() * 1000, samplerate, 2);
 	else
@@ -550,6 +568,9 @@
 
 		my_spc->play(1024, buf);
 
+		if ((console_ip.output->output_time() / 1000) >
+			spc->length && spc->length != 0)
+			break;
 		if ((console_ip.output->output_time() / 1000) > 
 			audcfg.loop_length && audcfg.loop_length != 0)
 			break;
--- a/Plugins/Input/console/Spc_Emu.cpp	Thu Jan 19 15:45:42 2006 -0800
+++ b/Plugins/Input/console/Spc_Emu.cpp	Thu Jan 19 19:31:32 2006 -0800
@@ -4,6 +4,7 @@
 #include "Spc_Emu.h"
 
 #include <string.h>
+#include "abstract_file.h"
 
 /* Copyright (C) 2004-2005 Shay Green. This module is free software; you
 can redistribute it and/or modify it under the terms of the GNU Lesser
@@ -18,6 +19,12 @@
 
 #include BLARGG_SOURCE_BEGIN
 
+#ifndef RAISE_ERROR
+	#define RAISE_ERROR( str ) return str
+#endif
+
+typedef Spc_Reader::error_t error_t;
+
 Spc_Emu::Spc_Emu()
 {
 	resample_ratio = 1.0;
@@ -111,3 +118,73 @@
 	return blargg_success;
 }
 
+Spc_Reader::Spc_Reader() : file( NULL ) {
+}
+
+Spc_Reader::~Spc_Reader() {
+	close();
+}
+
+error_t Spc_Reader::open( const char* path )
+{
+	file = fopen( path, "rb" );
+	if ( !file )
+		RAISE_ERROR( "Couldn't open file" );
+	return NULL;
+}
+
+blargg_err_t Spc_Reader::read_head(Spc_Emu::header_t *header) {
+	fread(&header->tag,     1,35,file);
+	fread(&header->format,  1, 1,file);
+	fread(&header->version, 1, 1,file);
+	fread(&header->pc,      1, 2,file);
+	fread(&header->a,       1, 1,file);
+	fread(&header->x,       1, 1,file);
+	fread(&header->y,       1, 1,file);
+	fread(&header->psw,     1, 1,file);
+	fread(&header->sp,      1, 1,file);
+	fread(&header->unused,  1, 2,file);
+	fread(&header->song,    1,32,file);
+	fread(&header->game,    1,32,file);
+	fread(&header->dumper,  1,16,file);
+	fread(&header->comment, 1,32,file);
+	fread(&header->date,    1,11,file);
+	fread(&header->len_secs,1, 3,file);
+	fread(&header->fade_msec,1,5,file);
+	fread(&header->author,  1,32,file);
+	fread(&header->mute_mask,1,1,file);
+	fread(&header->emulator,1, 1,file);
+	fread(&header->unused2, 1,45,file);
+}
+
+long Spc_Reader::size() const
+{
+	long pos = tell();
+	fseek( file, 0, SEEK_END );
+	long result = tell();
+	fseek( file, pos, SEEK_SET );
+	return result;
+}
+
+long Spc_Reader::read_avail( void* p, long s ) {
+	return fread( p, 1, s, file );
+}
+
+long Spc_Reader::tell() const {
+	return ftell( file );
+}
+
+error_t Spc_Reader::seek( long n )
+{
+	if ( fseek( file, n, SEEK_SET ) != 0 )
+		RAISE_ERROR( "Error seeking in file" );
+	return NULL;
+}
+
+void Spc_Reader::close()
+{
+	if ( file ) {
+		fclose( file );
+		file = NULL;
+	}
+}
--- a/Plugins/Input/console/Spc_Emu.h	Thu Jan 19 15:45:42 2006 -0800
+++ b/Plugins/Input/console/Spc_Emu.h	Thu Jan 19 19:31:32 2006 -0800
@@ -10,6 +10,9 @@
 #include "Music_Emu.h"
 #include "Snes_Spc.h"
 
+#include "blargg_common.h"
+#include "abstract_file.h"
+
 class Spc_Emu : public Music_Emu {
 public:
 	Spc_Emu();
@@ -44,6 +47,8 @@
 		
 		enum { copyright = 0 }; // no copyright field
 	};
+
+	int length;
 	
 	// Load SPC, given its header and reader for remaining data
 	blargg_err_t load( const header_t&, Emu_Reader& );
@@ -75,5 +80,25 @@
 	apu.mute_voices( m );
 }
 
+class Spc_Reader : public File_Reader {
+	FILE* file;
+public:
+	Spc_Reader();
+	~Spc_Reader();
+	
+	error_t open( const char* );
+	
+	// Custom reader for SPC headers [tempfix]
+	blargg_err_t read_head( Spc_Emu::header_t* );
+	
+	long size() const;
+	long read_avail( void*, long );
+	
+	long tell() const;
+	error_t seek( long );
+	
+	void close();
+};
+
 #endif