⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dc.c

📁 DC的SEGA_GG模拟器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        return;
}

int init_machine() {
        int i;

        mcont1 = maple_first_controller();
        mvmu1 = maple_first_vmu();
        mkeyb1 = maple_first_kb();

        /* Initialize display bitmap */
        memset(&bitmap, 0, sizeof(t_bitmap));
        bitmap.width  = 256;
        bitmap.height = 192;
        bitmap.depth  = 8;
        bitmap.pitch  = (bitmap.width * (bitmap.depth >> 3));
        bitmap.data   = (unsigned char *)&bitmap_data[0];

        init_smsplus();

        splash=(uint8 *)malloc(480*640*3);
        dcp_load(splash,p_smsplus);

        for (i=0; i<2048; i++) {
                game_desc[i] = (char *)malloc(256);
	}

        dir_root=(char *)malloc(256);

        arrow = malloc(2);
        arrow = "->";
        space = malloc(2);
        space = "  ";

        font_init();
        bkg_init("/rd/bkg.jpg");

        vmu_display(vmu_icon);

        ss_gamegear_w = 160.0f / 256.0f;
        ss_mastersystem_w = 1.0f;
        ss_gamegear = 144.0f / 256.0f;
        ss_mastersystem = 192.0f / 256.0f;

        return(0);
}

void trash_machine(void)
{
        int i;
        free(space);
        free(arrow);
        free(dir_root);
        free(splash);
        for (i=0; i<2048; i++) {
                free(game_desc[i]);
	}
        return;
}

/* startof sound.c */
#include "sndstream.h"

#define AUDIO_BUFFER_SIZE 10000
#define SMOOTH_SIZE 200
#define DC_FRAMES_PER_SECOND 60

int attenuation = 0;
unsigned char *audio_buffer = NULL;
unsigned char *audio_temp = NULL;

static int audio_stereo;
static int audio_pos = 0; // the position of the next buffer in the audio_buffer to be returned by kcallback

/* global sample tracking */
static int samples_per_frame;
static int samples_per_frame_remainder;
static int samples_left_over;
static int samples_this_frame;

// flag to set for callback to return NULL when stopped
static int stopped = 1;

// single linear transition from src to dst values
void audio_smooth_together(INT16 *audio_to_smooth, INT16 *audio_to_match)
{
 INT16 * dst_left;
 INT16 * dst_right;
 INT16 * src_left;
 INT16 * src_right;
int i;

 dst_left = audio_to_smooth;
 dst_right = audio_to_smooth + 1;

 src_left = audio_to_match;
 src_right = audio_to_match + 1;

 for (i = 0; i < SMOOTH_SIZE; i++)
 {
  *dst_left =  (((*src_left * (SMOOTH_SIZE - i)) / SMOOTH_SIZE) + ((*dst_left * (i)) / SMOOTH_SIZE))/2;
  *dst_right =  (((*src_right * (SMOOTH_SIZE - i)) / SMOOTH_SIZE) + ((*dst_right * (i)) / SMOOTH_SIZE))/2;

  dst_left += 2;
  dst_right += 2;
  src_left += 2;
  src_right += 2;
 }
}

// simple linear transition from value to dst
void audio_smooth_to_value(INT16 *audio_to_smooth, INT16 value_to_match)
{
 INT16 * dst_left;
 INT16 * dst_right;
int i;

 dst_left = audio_to_smooth;
 dst_right = audio_to_smooth + 1;

 for (i = 0; i < SMOOTH_SIZE; i++)
 {
  *dst_left =  (((value_to_match * (SMOOTH_SIZE - i)) / SMOOTH_SIZE) + ((*dst_left * (i)) / SMOOTH_SIZE))/2;
  *dst_right =  (((value_to_match * (SMOOTH_SIZE - i)) / SMOOTH_SIZE) + ((*dst_right * (i)) / SMOOTH_SIZE))/2;

  dst_left += 2;
  dst_right += 2;
 }
}

// way to much memory moving around for my taste but...
void* kos_audio_callback(int size)
{
 //int i;

 // return NULL if stopped this will cause the sndstream
 // code to silience the sound hardware on the next poll.
 if (stopped)
 {
  return NULL;
 }

// Jim's magic fairy dust is located here
// we don't have enough new data yet so let's manufature some data
// this is where a smaller buffer would be nice to make matching smoother
// but a smaller buffer means that this will occur more frequently
// so it really needs to do a good job
// even at full speed emulation things can get out of sync and we will
// need to manufacture data sometimes
if (size > audio_pos)
{
 // if it's not too bad let's do something fancy
 // otherwise just return the whole last buffer again cause it
 // will match what we will be playing next
 if (size > 2 * audio_pos + SMOOTH_SIZE)
 {
  // well, we are way behind so just repeat the whole last buffer

  // smooth the BACK to match the front here and avoid the seam
  audio_smooth_to_value(audio_temp, audio_temp[size]);

  return audio_temp;
 }
 else
 {
  // copy what we do have into the end of the buffer
  // cause it will match what will will be playing next
  memcpy(audio_temp + (size - audio_pos), audio_buffer, audio_pos);

  // copy what we do have into the beginning of the buffer
  // cause it matches what we have already played
  // but only enough to meet what we copied above
  // leaving only one small seam
  memcpy(audio_temp, audio_buffer, (size - audio_pos));

  // smooth the FRONT to match the back here and avoid the seam
  audio_smooth_together(audio_temp + (size - audio_pos), audio_buffer + (size - audio_pos));

  // we used up all our data so adjust the position
  // hopefully we will have enough next time
  audio_pos = 0;

  return audio_temp;
 }
}

 // copy current audio data into temp buffer to pass back
 memcpy(audio_temp, audio_buffer, size);

 // adjust the position in the audio buffer
 audio_pos -= size;

 // if it didn't ask for all the data slide back the extra
 // data we have to the front of the audio buffer so
 // we know where it is next time through
 if (audio_pos)
 {
  memcpy(audio_buffer, audio_buffer + size, audio_pos);
 }

 // return the new audio data
 return audio_temp;
}
int osd_start_audio_stream(int stereo)
{
        if (sample_rate == 0) return 0;

	// first time through allocate the buffers
	if (audio_buffer == 0)
	{
		audio_buffer = (char *)malloc(AUDIO_BUFFER_SIZE * 2);
		audio_temp = (char *)malloc(AUDIO_BUFFER_SIZE);
	}

	memset(audio_buffer, 0, AUDIO_BUFFER_SIZE * 2);
	memset(audio_temp, 0, AUDIO_BUFFER_SIZE);

	// initial position in the audio buffer
	audio_pos  = 0;
	audio_stereo = stereo;

	/* determine the number of samples per frame */
        samples_per_frame = sample_rate / DC_FRAMES_PER_SECOND;
        samples_per_frame_remainder = sample_rate % (int)DC_FRAMES_PER_SECOND;
	samples_left_over = samples_per_frame_remainder;
	samples_this_frame = samples_per_frame;

	printf("samples_per_frame: %d\n", samples_per_frame);
	
	// not stopped anymore
	stopped = 0;
	
	// start the audio stream, always stereo
        stream_start(sample_rate, 1);

	// ask for this many samples for the first frame
	return samples_this_frame;
}

void osd_stop_audio_stream(void)
{
        if (sample_rate == 0) return;
	
	if (audio_buffer != 0) 
	{
		// extra space for main buffer in case we get more than a buffer
		memset(audio_buffer, 0, AUDIO_BUFFER_SIZE * 2);
		// buffer that gets transfered to sndstream
		memset(audio_temp, 0, AUDIO_BUFFER_SIZE);
	}

	stopped = 1;
	
	// wait for silience to get transfered to both buffers before we shutdown
	stream_poll();
	
	// stop the stream
	stream_stop();
}

int osd_update_audio_stream(INT16 *buffer)
{
        if (sample_rate == 0) return 0;

	if (audio_stereo)
	{
		// copy the new data into the audio buffer at the current position
		memcpy(audio_buffer + audio_pos, buffer, samples_this_frame * 2);
		audio_pos += samples_this_frame * 2;
	} 
	else 
	{
		int i, j;
		INT16 *p;

		// OK now we have to manufacture stereo data from mono
		i = j = audio_pos / 2;

		p = (INT16 *)audio_buffer;

		for (i = 0; i < samples_this_frame; i++)
		{
			// every other byte
			p[j + (i * 2)]     = *buffer;
			p[j + (i * 2) + 1] = *buffer++;
		}
		
		// and now we have twice the data
		audio_pos += samples_this_frame * 4;
	}
	
	// we have enough data in the buffer so wait for it to be transfered 
	// via the kcallback() before asking for more
//	if (audio_pos >= AUDIO_BUFFER_SIZE) 
	{
		stream_poll();
	}
	
	// update samples to request for next frame
	samples_left_over = samples_left_over + samples_per_frame_remainder;
        samples_this_frame = samples_per_frame +  samples_left_over / DC_FRAMES_PER_SECOND;
        samples_left_over =  samples_left_over % DC_FRAMES_PER_SECOND;
	
	return samples_this_frame;
}

/* attenuation in dB */
void osd_set_mastervolume(int _attenuation)
{
	if (_attenuation > 0) _attenuation = 0;
	if (_attenuation < -32) _attenuation = -32;

	attenuation = _attenuation;
//	stream_volume(attenuation);
}

int osd_get_mastervolume(void)
{
	return attenuation;
}

void osd_sound_enable(int enable_it)
{
}

void osd_opl_control(int chip,int reg)
{
}

void osd_opl_write(int chip,int data)
{
}
/* endof sound.c */


//static uint32 txr_alloc_base;
//void ta_poly_hdr_col(poly_hdr_t *target, int translucent);
//void ta_txr_release_all();


/* Update Video */
void update_video(void) {
        int x, y, c;

        /* Width and height of viewport */
        int w = (cart.type ? 160 : 256);
        int h = (cart.type ? 144 : 192);

        /* Offset in display bitmap */
        int sx = (cart.type ? 48 : 0);
        int sy = (cart.type ? 24 : 0);

        for(y = 0; y < h; y++) {
                /* Point to current line of bitmap */
                char *p = &bitmap.data[((sy + y) * bitmap.width) + (sx)];

                for(x = 0; x < w; x++) {
                        c = (p[x] & PIXEL_MASK);

                        txrtmp[y*256+x] = RGB565(bitmap.pal.color[c][0],bitmap.pal.color[c][1],bitmap.pal.color[c][2]);
                }
        }
}

static void disc_display(polyplace_t *p) {
        vertex_ot_t     vert;
	poly_hdr_t	hdr;

        ta_poly_hdr_txr(&hdr, TA_OPAQUE, TA_RGB565, 256, 256, disc_txr, TA_NO_FILTER);
        ta_commit_poly_hdr(&hdr);

	vert.flags = TA_VERTEX_NORMAL;
        vert.x = p->x + 0.0f; vert.y = p->y + 480.0f; vert.z = p->z;
        vert.a = 1.0f; //vert.r = 0.0f; vert.g = 0.0f; vert.b = 0.0f;
        vert.r = vert.g = vert.b = 1.0f;
        vert.u = 0.0f; vert.v = ss_select; //vert.v = 1.0f;
        ta_commit_vertex(&vert, sizeof(vert));

	vert.flags = TA_VERTEX_NORMAL;
        vert.x = p->x + 0.0f; vert.y = p->y + 0.0f; vert.z = p->z;
        vert.a = 1.0f; //vert.r = 0.0f; vert.g = 0.0f; vert.b = 0.0f;
        vert.u = 0.0f; vert.v = 0.0f;
        ta_commit_vertex(&vert, sizeof(vert));

	vert.flags = TA_VERTEX_NORMAL;
        vert.x = p->x + 640.0f; vert.y = p->y + 480.0f; vert.z = p->z;
        vert.a = 1.0f; //vert.r = 0.0f; vert.g = 0.0f; vert.b = 0.0f;
        //vert.u = 1.0f; vert.v = ss_select; //vert.v = 1.0f;
        vert.u = ss_select_w; vert.v = ss_select; //vert.v = 1.0f;
        ta_commit_vertex(&vert, sizeof(vert));

	vert.flags = TA_VERTEX_EOL;
        vert.x = p->x + 640.0f; vert.y = p->y + 0.0f; vert.z = p->z;
        vert.a = 1.0f;// vert.r = vert.g = vert.b = 1.0f;//vert.r = 0.0f; vert.g = 0.0f; vert.b = 0.0f;
        //vert.u = 1.0f; vert.v = 0.0f;
        vert.u = ss_select_w; vert.v = 0.0f;
        ta_commit_vertex(&vert, sizeof(vert));
}

static void disc_blank() {
	poly_hdr_t	hdr;
        ta_poly_hdr_col(&hdr, TA_TRANSLUCENT);
        ta_commit_poly_hdr(&hdr);
}

void disclaimer() {

        ta_begin_render();
        disc_display(&polys);
        ta_commit_eol();
        disc_blank();
        ta_commit_eol();
        ta_finish_frame();

        ta_begin_render();
        disc_display(&polys);
        ta_commit_eol();
        disc_blank();
        ta_commit_eol();
        ta_finish_frame();

}


/* Show how many frames have been rendered */
void display_fcount() {
        return;
}

/* Updates the Controller's input */

int update_input() {
        cont_cond_t FirstCont;
        cont_cond_t SecondCont;

        FirstCont=getButtons(0);

        memset(&input, 0, sizeof(t_input));

        /* only  player 1 can exit, by pressing rtrig & ltrig */
        if(FirstCont.ltrig & FirstCont.rtrig)           exit_flag = 1;

        //if(FirstCont.rtrig) frame_skip=max_skip;
        //if(FirstCont.ltrig) frame_skip=min_skip;
        if((!(FirstCont.buttons & CONT_X)) && (!(FirstCont.buttons & CONT_Y))) { save_state(); return 0; }

        /* first controller */
        if(!(FirstCont.buttons  & CONT_START))          input.system |= (cart.type) ? INPUT_START : INPUT_PAUSE;
        if(!(FirstCont.buttons  & CONT_DPAD_UP))         input.pad[0] |= INPUT_UP;
        else
        if(!(FirstCont.buttons  & CONT_DPAD_DOWN))       input.pad[0] |= INPUT_DOWN;
        if(!(FirstCont.buttons  & CONT_DPAD_LEFT))       input.pad[0] |= INPUT_LEFT;
        else
        if(!(FirstCont.buttons  & CONT_DPAD_RIGHT))      input.pad[0] |= INPUT_RIGHT;
        if(!(FirstCont.buttons  & CONT_B))               input.pad[0] |= INPUT_BUTTON2;
        if(!(FirstCont.buttons  & CONT_A))               input.pad[0] |= INPUT_BUTTON1;

        /* second controller */
        SecondCont=getButtons(1);
        if(!(SecondCont.buttons & CONT_DPAD_UP))   input.pad[1] |= INPUT_UP;
        else
        if(!(SecondCont.buttons  & CONT_DPAD_DOWN))   input.pad[1] |= INPUT_DOWN;
        if(!(SecondCont.buttons  & CONT_DPAD_LEFT))   input.pad[1] |= INPUT_LEFT;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -