mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 07:17:45 -04:00
GP2X: low volume and fast forward
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@310 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
parent
53668ca0f8
commit
4a32f01f55
9 changed files with 186 additions and 40 deletions
|
@ -131,6 +131,7 @@ extern void (*PicoPrepareCram)(); // prepares PicoCramHigh for renderer to us
|
|||
// sound.c
|
||||
extern int PsndRate,PsndLen;
|
||||
extern short *PsndOut;
|
||||
extern void (*PsndMix_32_to_16l)(short *dest, int *src, int count);
|
||||
void PsndRerate(int preserve_state);
|
||||
|
||||
// Utils.c
|
||||
|
|
|
@ -6,3 +6,5 @@ void mix_16h_to_32_s2(int *dest, short *src, int count);
|
|||
void mix_32_to_16l_stereo(short *dest, int *src, int count);
|
||||
void mix_32_to_16_mono(short *dest, int *src, int count);
|
||||
|
||||
extern int mix_32_to_16l_level;
|
||||
void mix_32_to_16l_stereo_lvl(short *dest, int *src, int count);
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
@ (c) Copyright 2007, Grazvydas "notaz" Ignotas
|
||||
|
||||
|
||||
.text
|
||||
.align 4
|
||||
|
||||
@ this assumes src is word aligned
|
||||
.global mix_16h_to_32 @ int *dest, short *src, int count
|
||||
|
||||
|
@ -293,3 +296,72 @@ m32_16_mo_no_unal2:
|
|||
ldmfd sp!, {r4-r8,lr}
|
||||
bx lr
|
||||
|
||||
|
||||
|
||||
.data
|
||||
.align 4
|
||||
|
||||
.global mix_32_to_16l_level
|
||||
mix_32_to_16l_level:
|
||||
.word 0
|
||||
|
||||
.text
|
||||
.align 4
|
||||
|
||||
@ same as mix_32_to_16l_stereo, but with additional shift
|
||||
.global mix_32_to_16l_stereo_lvl @ short *dest, int *src, int count
|
||||
|
||||
mix_32_to_16l_stereo_lvl:
|
||||
stmfd sp!, {r4-r9,lr}
|
||||
|
||||
ldr r9, =mix_32_to_16l_level
|
||||
mov lr, #1
|
||||
ldr r9, [r9]
|
||||
|
||||
mov r2, r2, lsl #1
|
||||
subs r2, r2, #4
|
||||
bmi m32_16l_st_l_end
|
||||
|
||||
m32_16l_st_l_loop:
|
||||
ldmia r0, {r8,r12}
|
||||
ldmia r1!, {r4-r7}
|
||||
mov r8, r8, lsl #16
|
||||
mov r12,r12,lsl #16
|
||||
add r4, r4, r8, asr #16
|
||||
add r5, r5, r8, asr #16
|
||||
add r6, r6, r12,asr #16
|
||||
add r7, r7, r12,asr #16
|
||||
mov r4, r4, asr r9
|
||||
mov r5, r5, asr r9
|
||||
mov r6, r6, asr r9
|
||||
mov r7, r7, asr r9
|
||||
Limitsh r4
|
||||
Limitsh r5
|
||||
Limitsh r6
|
||||
Limitsh r7
|
||||
subs r2, r2, #4
|
||||
orr r4, r5, r4, lsr #16
|
||||
orr r5, r7, r6, lsr #16
|
||||
stmia r0!, {r4,r5}
|
||||
bpl m32_16l_st_l_loop
|
||||
|
||||
m32_16l_st_l_end:
|
||||
@ check for remaining bytes to convert
|
||||
tst r2, #2
|
||||
beq m32_16l_st_l_no_unal2
|
||||
ldrsh r6, [r0]
|
||||
ldmia r1!,{r4,r5}
|
||||
add r4, r4, r6
|
||||
add r5, r5, r6
|
||||
mov r4, r4, asr r9
|
||||
mov r5, r5, asr r9
|
||||
Limitsh r4
|
||||
Limitsh r5
|
||||
orr r4, r5, r4, lsr #16
|
||||
str r4, [r0], #4
|
||||
|
||||
m32_16l_st_l_no_unal2:
|
||||
ldmfd sp!, {r4-r9,lr}
|
||||
bx lr
|
||||
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include "../cd/pcm.h"
|
||||
#include "mix.h"
|
||||
|
||||
void (*PsndMix_32_to_16l)(short *dest, int *src, int count) = mix_32_to_16l_stereo;
|
||||
|
||||
// master int buffer to mix to
|
||||
static int PsndBuffer[2*44100/50];
|
||||
|
||||
|
@ -151,6 +153,9 @@ void PsndRerate(int preserve_state)
|
|||
memset32(PsndBuffer, 0, sizeof(PsndBuffer)/4);
|
||||
if (PsndOut)
|
||||
PsndClear();
|
||||
|
||||
// set mixer
|
||||
PsndMix_32_to_16l = (PicoOpt & 8) ? mix_32_to_16l_stereo : mix_32_to_16_mono;
|
||||
}
|
||||
|
||||
|
||||
|
@ -260,9 +265,7 @@ PICO_INTERNAL int PsndRender(int offset, int length)
|
|||
mp3_update(buf32, length, stereo);
|
||||
|
||||
// convert + limit to normal 16bit output
|
||||
if (stereo)
|
||||
mix_32_to_16l_stereo(PsndOut+offset, buf32, length);
|
||||
else mix_32_to_16_mono (PsndOut+offset, buf32, length);
|
||||
PsndMix_32_to_16l(PsndOut+offset, buf32, length);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
|
|
@ -641,7 +641,11 @@ Changelog
|
|||
* Fixed a sram bug in memhandlers (fixes Shining in the Darkness saves).
|
||||
* PSP: fixed another bug in memhanlers, which crashed the emu for some games
|
||||
(like NBA Jam and NHL 9x).
|
||||
* Added suspend/resume handling for Sega CD games.
|
||||
+ PSP: added suspend/resume handling for Sega CD games.
|
||||
+ GP2X: added additional low volume levels for my late-night gaming sessions
|
||||
(in stereo mode only).
|
||||
+ GP2X: added "fast forward" action in key config. Not recommended to use for
|
||||
Sega CD, may case problems there.
|
||||
* Some other small tweaks I forgot about.
|
||||
|
||||
1.35a
|
||||
|
@ -649,7 +653,7 @@ Changelog
|
|||
* PSP: fixed incorrect CZ80 memory map setup, which caused Z80 crashes and
|
||||
graphics corruption in EU Mega CD model1 BIOS menus.
|
||||
+ PSP: added additional "set to 4:3 scaled" display option for convenience.
|
||||
+ Added an option to disable frame limitter (works only with non-auto frameskip).
|
||||
+ PSP: Added an option to disable frame limitter (works only with non-auto frameskip).
|
||||
|
||||
1.35
|
||||
+ PSP port added. Lots of new code for it. Integrated modified FAME/C, CZ80 cores.
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
@ vim:filetype=armasm
|
||||
@ some color conversion and blitting routines
|
||||
|
||||
@ (c) Copyright 2006, notaz
|
||||
@ (c) Copyright 2006, 2007 notaz
|
||||
@ All Rights Reserved
|
||||
|
||||
@ vim:filetype=armasm
|
||||
|
||||
.text
|
||||
.align 4
|
||||
|
||||
@ Convert 0000bbb0 ggg0rrr0 0000bbb0 ggg0rrr0
|
||||
@ to 00000000 rrr00000 ggg00000 bbb00000 ...
|
||||
|
||||
|
@ -217,3 +220,4 @@ flushcache:
|
|||
swi #0x9f0002
|
||||
mov pc, lr
|
||||
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include <Pico/PicoInt.h>
|
||||
#include <Pico/Patch.h>
|
||||
#include <Pico/sound/mix.h>
|
||||
#include <zlib/zlib.h>
|
||||
|
||||
//#define PFRAMES
|
||||
|
@ -432,9 +433,69 @@ static void emu_msg_tray_open(void)
|
|||
gettimeofday(¬iceMsgTime, 0);
|
||||
}
|
||||
|
||||
static void update_volume(int has_changed, int is_up)
|
||||
{
|
||||
static int prev_frame = 0, wait_frames = 0;
|
||||
int vol = currentConfig.volume;
|
||||
|
||||
if (has_changed)
|
||||
{
|
||||
if (vol < 5 && (PicoOpt&8) && prev_frame == Pico.m.frame_count - 1 && wait_frames < 12)
|
||||
wait_frames++;
|
||||
else {
|
||||
if (is_up) {
|
||||
if (vol < 99) vol++;
|
||||
} else {
|
||||
if (vol > 0) vol--;
|
||||
}
|
||||
wait_frames = 0;
|
||||
gp2x_sound_volume(vol, vol);
|
||||
currentConfig.volume = vol;
|
||||
}
|
||||
sprintf(noticeMsg, "VOL: %02i", vol);
|
||||
gettimeofday(¬iceMsgTime, 0);
|
||||
prev_frame = Pico.m.frame_count;
|
||||
}
|
||||
|
||||
// set the right mixer func
|
||||
if (!(PicoOpt&8)) return; // just use defaults for mono
|
||||
if (vol >= 5)
|
||||
PsndMix_32_to_16l = mix_32_to_16l_stereo;
|
||||
else {
|
||||
mix_32_to_16l_level = 5 - vol;
|
||||
PsndMix_32_to_16l = mix_32_to_16l_stereo_lvl;
|
||||
}
|
||||
}
|
||||
|
||||
static void change_fast_forward(int set_on)
|
||||
{
|
||||
static void *set_PsndOut = NULL;
|
||||
static int set_Frameskip, set_EmuOpt, is_on = 0;
|
||||
|
||||
if (set_on && !is_on) {
|
||||
set_PsndOut = PsndOut;
|
||||
set_Frameskip = currentConfig.Frameskip;
|
||||
set_EmuOpt = currentConfig.EmuOpt;
|
||||
PsndOut = NULL;
|
||||
currentConfig.Frameskip = 8;
|
||||
currentConfig.EmuOpt &= ~4;
|
||||
is_on = 1;
|
||||
}
|
||||
else if (!set_on && is_on) {
|
||||
PsndOut = set_PsndOut;
|
||||
currentConfig.Frameskip = set_Frameskip;
|
||||
currentConfig.EmuOpt = set_EmuOpt;
|
||||
PsndRerate(1);
|
||||
update_volume(0, 0);
|
||||
reset_timing = 1;
|
||||
is_on = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void RunEvents(unsigned int which)
|
||||
{
|
||||
if(which & 0x1800) { // save or load (but not both)
|
||||
if (which & 0x1800) // save or load (but not both)
|
||||
{
|
||||
int do_it = 1;
|
||||
if ( emu_checkSaveFile(state_slot) &&
|
||||
(( (which & 0x1000) && (currentConfig.EmuOpt & 0x800)) || // load
|
||||
|
@ -456,7 +517,8 @@ static void RunEvents(unsigned int which)
|
|||
|
||||
reset_timing = 1;
|
||||
}
|
||||
if(which & 0x0400) { // switch renderer
|
||||
if (which & 0x0400) // switch renderer
|
||||
{
|
||||
if ( PicoOpt&0x10) { PicoOpt&=~0x10; currentConfig.EmuOpt |= 0x80; }
|
||||
else if (!(currentConfig.EmuOpt&0x80)) PicoOpt|= 0x10;
|
||||
else currentConfig.EmuOpt &= ~0x80;
|
||||
|
@ -473,7 +535,8 @@ static void RunEvents(unsigned int which)
|
|||
|
||||
gettimeofday(¬iceMsgTime, 0);
|
||||
}
|
||||
if(which & 0x0300) {
|
||||
if (which & 0x0300)
|
||||
{
|
||||
if(which&0x0200) {
|
||||
state_slot -= 1;
|
||||
if(state_slot < 0) state_slot = 9;
|
||||
|
@ -552,18 +615,11 @@ static void updateKeys(void)
|
|||
events = (allActions[0] | allActions[1]) >> 16;
|
||||
|
||||
// volume is treated in special way and triggered every frame
|
||||
if(events & 0x6000) {
|
||||
int vol = currentConfig.volume;
|
||||
if (events & 0x2000) {
|
||||
if (vol < 99) vol++;
|
||||
} else {
|
||||
if (vol > 0) vol--;
|
||||
}
|
||||
gp2x_sound_volume(vol, vol);
|
||||
sprintf(noticeMsg, "VOL: %02i", vol);
|
||||
gettimeofday(¬iceMsgTime, 0);
|
||||
currentConfig.volume = vol;
|
||||
}
|
||||
if (events & 0x6000)
|
||||
update_volume(1, events & 0x2000);
|
||||
|
||||
if ((events ^ prevEvents) & 0x40)
|
||||
change_fast_forward(events & 0x40);
|
||||
|
||||
events &= ~prevEvents;
|
||||
if (events) RunEvents(events);
|
||||
|
@ -685,15 +741,11 @@ void emu_Loop(void)
|
|||
reset_timing = 1;
|
||||
|
||||
// prepare sound stuff
|
||||
if(currentConfig.EmuOpt & 4) {
|
||||
if (currentConfig.EmuOpt & 4)
|
||||
{
|
||||
int snd_excess_add;
|
||||
if (PsndRate != PsndRate_old || (PicoOpt&0x20b) != (PicoOpt_old&0x20b) || Pico.m.pal != pal_old ||
|
||||
((PicoOpt&0x200) && crashed_940)) {
|
||||
/* if 940 is turned off, we need it to be put back to sleep */
|
||||
if (!(PicoOpt&0x200) && ((PicoOpt^PicoOpt_old)&0x200)) {
|
||||
Reset940(1, 2);
|
||||
Pause940(1);
|
||||
}
|
||||
PsndRerate(Pico.m.frame_count ? 1 : 0);
|
||||
}
|
||||
snd_excess_add = ((PsndRate - PsndLen*target_fps)<<16) / target_fps;
|
||||
|
@ -702,13 +754,14 @@ void emu_Loop(void)
|
|||
gp2x_start_sound(PsndRate, 16, (PicoOpt&8)>>3);
|
||||
gp2x_sound_volume(currentConfig.volume, currentConfig.volume);
|
||||
PicoWriteSound = updateSound;
|
||||
update_volume(0, 0);
|
||||
memset(sndBuffer, 0, sizeof(sndBuffer));
|
||||
PsndOut = sndBuffer;
|
||||
PsndRate_old = PsndRate;
|
||||
PicoOpt_old = PicoOpt;
|
||||
pal_old = Pico.m.pal;
|
||||
} else {
|
||||
PsndOut = 0;
|
||||
PsndOut = NULL;
|
||||
}
|
||||
|
||||
// prepare CD buffer
|
||||
|
@ -740,7 +793,8 @@ void emu_Loop(void)
|
|||
}
|
||||
|
||||
// show notice message?
|
||||
if(noticeMsgTime.tv_sec) {
|
||||
if (noticeMsgTime.tv_sec)
|
||||
{
|
||||
static int noticeMsgSum;
|
||||
if((tval.tv_sec*1000000+tval.tv_usec) - (noticeMsgTime.tv_sec*1000000+noticeMsgTime.tv_usec) > 2000000) { // > 2.0 sec
|
||||
noticeMsgTime.tv_sec = noticeMsgTime.tv_usec = 0;
|
||||
|
@ -755,7 +809,8 @@ void emu_Loop(void)
|
|||
|
||||
// check for mode changes
|
||||
modes = ((Pico.video.reg[12]&1)<<2)|(Pico.video.reg[1]&8);
|
||||
if (modes != oldmodes) {
|
||||
if (modes != oldmodes)
|
||||
{
|
||||
int scalex = 320;
|
||||
osd_fps_x = OSD_FPS_X;
|
||||
if (modes & 4) {
|
||||
|
@ -777,7 +832,8 @@ void emu_Loop(void)
|
|||
}
|
||||
|
||||
// second changed?
|
||||
if(thissec != tval.tv_sec) {
|
||||
if (thissec != tval.tv_sec)
|
||||
{
|
||||
#ifdef BENCHMARK
|
||||
static int bench = 0, bench_fps = 0, bench_fps_s = 0, bfp = 0, bf[4];
|
||||
if (++bench == 10) {
|
||||
|
@ -791,6 +847,7 @@ void emu_Loop(void)
|
|||
#else
|
||||
if (currentConfig.EmuOpt & 2)
|
||||
sprintf(fpsbuff, "%02i/%02i", frames_shown, frames_done);
|
||||
if (fpsbuff[5] == 0) { fpsbuff[5] = fpsbuff[6] = ' '; fpsbuff[7] = 0; }
|
||||
#endif
|
||||
thissec = tval.tv_sec;
|
||||
|
||||
|
@ -818,7 +875,7 @@ void emu_Loop(void)
|
|||
for(i = 0; i < currentConfig.Frameskip; i++) {
|
||||
updateKeys();
|
||||
SkipFrame(1); frames_done++;
|
||||
if (PsndOut) { // do framelimitting if sound is enabled
|
||||
if (PsndOut && !reset_timing) { // do framelimitting if sound is enabled
|
||||
gettimeofday(&tval, 0);
|
||||
if(thissec != tval.tv_sec) tval.tv_usec+=1000000;
|
||||
if(tval.tv_usec < lim_time) { // we are too fast
|
||||
|
@ -911,7 +968,7 @@ if (Pico.m.frame_count == 31563) {
|
|||
{
|
||||
// sleep or vsync if we are still too fast
|
||||
// usleep sleeps for ~20ms minimum, so it is not a solution here
|
||||
if(tval.tv_usec < lim_time)
|
||||
if (!reset_timing && tval.tv_usec < lim_time)
|
||||
{
|
||||
// we are too fast
|
||||
if (vsync_offset) {
|
||||
|
@ -929,6 +986,7 @@ if (Pico.m.frame_count == 31563) {
|
|||
frames_done++; frames_shown++;
|
||||
}
|
||||
|
||||
change_fast_forward(0);
|
||||
|
||||
if (PicoMCD & 1) PicoCDBufferFree();
|
||||
|
||||
|
|
|
@ -232,8 +232,8 @@ void gp2x_start_sound(int rate, int bits, int stereo)
|
|||
if (sounddev == -1)
|
||||
printf("open(\"/dev/dsp\") failed with %i\n", errno);
|
||||
|
||||
ioctl(sounddev, SNDCTL_DSP_SPEED, &rate);
|
||||
ioctl(sounddev, SNDCTL_DSP_SETFMT, &bits);
|
||||
ioctl(sounddev, SNDCTL_DSP_SPEED, &rate);
|
||||
ioctl(sounddev, SNDCTL_DSP_STEREO, &stereo);
|
||||
// calculate buffer size
|
||||
buffers = 16;
|
||||
|
@ -242,11 +242,12 @@ void gp2x_start_sound(int rate, int bits, int stereo)
|
|||
while ((bsize>>=1)) frag++;
|
||||
frag |= buffers<<16; // 16 buffers
|
||||
ioctl(sounddev, SNDCTL_DSP_SETFRAGMENT, &frag);
|
||||
usleep(192*1024);
|
||||
|
||||
printf("gp2x_set_sound: %i/%ibit/%s, %i buffers of %i bytes\n",
|
||||
rate, bits, stereo?"stereo":"mono", frag>>16, 1<<(frag&0xffff));
|
||||
|
||||
s_oldrate = rate; s_oldbits = bits; s_oldstereo = stereo;
|
||||
usleep(100000);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -838,6 +838,7 @@ static bind_action_t emuctrl_actions[] =
|
|||
{ "Switch Renderer", 1<<26 },
|
||||
{ "Volume Down ", 1<<30 },
|
||||
{ "Volume Up ", 1<<29 },
|
||||
{ "Fast forward ", 1<<22 },
|
||||
{ "Enter Menu ", 1<<23 },
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue