mirror of
https://github.com/RaySollium99/libpicofe.git
synced 2025-09-06 23:28:04 -04:00
remove PicoDrive-specific stuff, add readme
This commit is contained in:
parent
ca69c3e5a0
commit
f506842df2
73 changed files with 13 additions and 16178 deletions
|
@ -1,14 +0,0 @@
|
|||
// (c) Copyright 2006-2009 notaz, All rights reserved.
|
||||
// Free for non-commercial use.
|
||||
|
||||
// For commercial use, separate licencing terms must be obtained.
|
||||
|
||||
void bgr444_to_rgb32(void *to, void *from);
|
||||
void bgr444_to_rgb32_sh(void *to, void *from);
|
||||
|
||||
void vidcpy_m2(void *dest, void *src, int m32col, int with_32c_border);
|
||||
void vidcpy_m2_rot(void *dest, void *src, int m32col, int with_32c_border);
|
||||
void spend_cycles(int c); // utility
|
||||
|
||||
void rotated_blit8 (void *dst, void *linesx4, int y, int is_32col);
|
||||
void rotated_blit16(void *dst, void *linesx4, int y, int is_32col);
|
|
@ -1,337 +0,0 @@
|
|||
@ vim:filetype=armasm
|
||||
@ some color conversion and blitting routines
|
||||
|
||||
@ (c) Copyright 2006, 2007 notaz
|
||||
@ All Rights Reserved
|
||||
|
||||
@ vim:filetype=armasm
|
||||
|
||||
.text
|
||||
.align 4
|
||||
|
||||
@ Convert 0000bbb0 ggg0rrr0 0000bbb0 ggg0rrr0
|
||||
@ to 00000000 rrr00000 ggg00000 bbb00000 ...
|
||||
|
||||
@ lr = 0x00e000e0, out: r3=lower_pix, r2=higher_pix; trashes rin
|
||||
.macro convRGB32_2 rin sh=0
|
||||
and r2, lr, \rin, lsr #4 @ blue
|
||||
and r3, \rin, lr
|
||||
orr r2, r2, r3, lsl #8 @ g0b0g0b0
|
||||
|
||||
mov r3, r2, lsl #16 @ g0b00000
|
||||
and \rin,lr, \rin, ror #12 @ 00r000r0 (reversed)
|
||||
orr r3, r3, \rin, lsr #16 @ g0b000r0
|
||||
.if \sh == 1
|
||||
mov r3, r3, ror #17 @ shadow mode
|
||||
.elseif \sh == 2
|
||||
adds r3, r3, #0x40000000 @ green
|
||||
orrcs r3, r3, #0xe0000000
|
||||
mov r3, r3, ror #8
|
||||
adds r3, r3, #0x40000000
|
||||
orrcs r3, r3, #0xe0000000
|
||||
mov r3, r3, ror #16
|
||||
adds r3, r3, #0x40000000
|
||||
orrcs r3, r3, #0xe0000000
|
||||
mov r3, r3, ror #24
|
||||
.else
|
||||
mov r3, r3, ror #16 @ r3=low
|
||||
.endif
|
||||
|
||||
orr r3, r3, r3, lsr #3
|
||||
str r3, [r0], #4
|
||||
|
||||
mov r2, r2, lsr #16
|
||||
orr r2, r2, \rin, lsl #16
|
||||
.if \sh == 1
|
||||
mov r2, r2, lsr #1
|
||||
.elseif \sh == 2
|
||||
mov r2, r2, ror #8
|
||||
adds r2, r2, #0x40000000 @ blue
|
||||
orrcs r2, r2, #0xe0000000
|
||||
mov r2, r2, ror #8
|
||||
adds r2, r2, #0x40000000
|
||||
orrcs r2, r2, #0xe0000000
|
||||
mov r2, r2, ror #8
|
||||
adds r2, r2, #0x40000000
|
||||
orrcs r2, r2, #0xe0000000
|
||||
mov r2, r2, ror #8
|
||||
.endif
|
||||
|
||||
orr r2, r2, r2, lsr #3
|
||||
.if \sh == 1
|
||||
str r2, [r0, #0x40*2*4]
|
||||
.endif
|
||||
str r2, [r0], #4
|
||||
.endm
|
||||
|
||||
|
||||
.global bgr444_to_rgb32 @ void *to, void *from
|
||||
|
||||
bgr444_to_rgb32:
|
||||
stmfd sp!, {r4-r7,lr}
|
||||
|
||||
mov r12, #0x40>>3 @ repeats
|
||||
mov lr, #0x00e00000
|
||||
orr lr, lr, #0x00e0
|
||||
|
||||
.loopRGB32:
|
||||
subs r12, r12, #1
|
||||
|
||||
ldmia r1!, {r4-r7}
|
||||
convRGB32_2 r4
|
||||
convRGB32_2 r5
|
||||
convRGB32_2 r6
|
||||
convRGB32_2 r7
|
||||
bgt .loopRGB32
|
||||
|
||||
ldmfd sp!, {r4-r7,pc}
|
||||
|
||||
|
||||
.global bgr444_to_rgb32_sh @ void *to, void *from
|
||||
|
||||
bgr444_to_rgb32_sh:
|
||||
stmfd sp!, {r4-r7,lr}
|
||||
|
||||
mov r12, #0x40>>3 @ repeats
|
||||
add r0, r0, #0x40*4
|
||||
mov lr, #0x00e00000
|
||||
orr lr, lr, #0x00e0
|
||||
|
||||
.loopRGB32sh:
|
||||
subs r12, r12, #1
|
||||
|
||||
ldmia r1!, {r4-r7}
|
||||
convRGB32_2 r4, 1
|
||||
convRGB32_2 r5, 1
|
||||
convRGB32_2 r6, 1
|
||||
convRGB32_2 r7, 1
|
||||
bgt .loopRGB32sh
|
||||
|
||||
mov r12, #0x40>>3 @ repeats
|
||||
sub r1, r1, #0x40*2
|
||||
|
||||
.loopRGB32hi:
|
||||
ldmia r1!, {r4-r7}
|
||||
convRGB32_2 r4, 2
|
||||
convRGB32_2 r5, 2
|
||||
convRGB32_2 r6, 2
|
||||
convRGB32_2 r7, 2
|
||||
|
||||
subs r12, r12, #1
|
||||
bgt .loopRGB32hi
|
||||
|
||||
ldmfd sp!, {r4-r7,lr}
|
||||
bx lr
|
||||
|
||||
|
||||
@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
|
||||
|
||||
@ mode2 blitter
|
||||
.global vidcpy_m2 @ void *dest, void *src, int m32col, int with_32c_border
|
||||
vidcpy_m2:
|
||||
stmfd sp!, {r4-r6,lr}
|
||||
|
||||
mov r12, #224 @ lines
|
||||
add r0, r0, #320*8
|
||||
add r1, r1, #8
|
||||
mov lr, #0
|
||||
|
||||
tst r2, r2
|
||||
movne lr, #64
|
||||
tstne r3, r3
|
||||
addne r0, r0, #32
|
||||
|
||||
vidCpyM2_loop_out:
|
||||
mov r6, #10
|
||||
sub r6, r6, lr, lsr #5 @ -= 2 in 32col mode
|
||||
vidCpyM2_loop:
|
||||
subs r6, r6, #1
|
||||
ldmia r1!, {r2-r5}
|
||||
stmia r0!, {r2-r5}
|
||||
ldmia r1!, {r2-r5}
|
||||
stmia r0!, {r2-r5}
|
||||
bne vidCpyM2_loop
|
||||
|
||||
subs r12,r12,#1
|
||||
add r0, r0, lr
|
||||
add r1, r1, #8
|
||||
add r1, r1, lr
|
||||
bne vidCpyM2_loop_out
|
||||
|
||||
ldmfd sp!, {r4-r6,pc}
|
||||
|
||||
|
||||
.global vidcpy_m2_rot @ void *dest, void *src, int m32col, int with_32c_border
|
||||
vidcpy_m2_rot:
|
||||
stmfd sp!,{r4-r8,lr}
|
||||
add r1, r1, #8
|
||||
tst r2, r2
|
||||
subne r1, r1, #32 @ adjust
|
||||
|
||||
mov r4, r0
|
||||
mov r5, r1
|
||||
mov r6, r2
|
||||
mov r7, #8+4
|
||||
|
||||
vidcpy_m2_rot_loop:
|
||||
@ a bit lame but oh well..
|
||||
mov r0, r4
|
||||
mov r1, r5
|
||||
mov r2, r7
|
||||
mov r3, r6
|
||||
mov r8, #328
|
||||
adr lr, after_rot_blit8
|
||||
stmfd sp!,{r4-r8,lr}
|
||||
b rotated_blit8_2
|
||||
|
||||
after_rot_blit8:
|
||||
add r5, r5, #328*4
|
||||
add r7, r7, #4
|
||||
cmp r7, #224+8+4
|
||||
ldmgefd sp!,{r4-r8,pc}
|
||||
b vidcpy_m2_rot_loop
|
||||
|
||||
|
||||
.global rotated_blit8 @ void *dst, void *linesx4, u32 y, int is_32col
|
||||
rotated_blit8:
|
||||
stmfd sp!,{r4-r8,lr}
|
||||
mov r8, #320
|
||||
|
||||
rotated_blit8_2:
|
||||
add r0, r0, #(240*320)
|
||||
sub r0, r0, #(240+4) @ y starts from 4
|
||||
add r0, r0, r2
|
||||
|
||||
tst r3, r3
|
||||
subne r0, r0, #(240*32)
|
||||
addne r1, r1, #32
|
||||
movne lr, #256/4
|
||||
moveq lr, #320/4
|
||||
|
||||
rotated_blit_loop8:
|
||||
mov r6, r1
|
||||
ldr r2, [r6], r8
|
||||
ldr r3, [r6], r8
|
||||
ldr r4, [r6], r8
|
||||
ldr r5, [r6], r8
|
||||
|
||||
mov r6, r2, lsl #24
|
||||
mov r6, r6, lsr #8
|
||||
orr r6, r6, r3, lsl #24
|
||||
mov r6, r6, lsr #8
|
||||
orr r6, r6, r4, lsl #24
|
||||
mov r6, r6, lsr #8
|
||||
orr r6, r6, r5, lsl #24
|
||||
str r6, [r0], #-240
|
||||
|
||||
and r6, r3, #0xff00
|
||||
and r7, r2, #0xff00
|
||||
orr r6, r6, r7, lsr #8
|
||||
and r7, r4, #0xff00
|
||||
orr r6, r6, r7, lsl #8
|
||||
and r7, r5, #0xff00
|
||||
orr r6, r6, r7, lsl #16
|
||||
str r6, [r0], #-240
|
||||
|
||||
and r6, r4, #0xff0000
|
||||
and r7, r2, #0xff0000
|
||||
orr r6, r6, r7, lsr #16
|
||||
and r7, r3, #0xff0000
|
||||
orr r6, r6, r7, lsr #8
|
||||
and r7, r5, #0xff0000
|
||||
orr r6, r6, r7, lsl #8
|
||||
str r6, [r0], #-240
|
||||
|
||||
mov r6, r5, lsr #24
|
||||
mov r6, r6, lsl #8
|
||||
orr r6, r6, r4, lsr #24
|
||||
mov r6, r6, lsl #8
|
||||
orr r6, r6, r3, lsr #24
|
||||
mov r6, r6, lsl #8
|
||||
orr r6, r6, r2, lsr #24
|
||||
str r6, [r0], #-240
|
||||
|
||||
subs lr, lr, #1
|
||||
add r1, r1, #4
|
||||
bne rotated_blit_loop8
|
||||
|
||||
ldmfd sp!,{r4-r8,pc}
|
||||
|
||||
|
||||
@ input: r2-r5
|
||||
@ output: r7,r8
|
||||
@ trash: r6
|
||||
.macro rb_line_low
|
||||
mov r6, r2, lsl #16
|
||||
mov r7, r3, lsl #16
|
||||
orr r7, r7, r6, lsr #16
|
||||
mov r6, r4, lsl #16
|
||||
mov r8, r5, lsl #16
|
||||
orr r8, r8, r6, lsr #16
|
||||
.endm
|
||||
|
||||
.macro rb_line_hi
|
||||
mov r6, r2, lsr #16
|
||||
mov r7, r3, lsr #16
|
||||
orr r7, r6, r7, lsl #16
|
||||
mov r6, r4, lsr #16
|
||||
mov r8, r5, lsr #16
|
||||
orr r8, r6, r8, lsl #16
|
||||
.endm
|
||||
|
||||
.global rotated_blit16 @ void *dst, void *linesx4, u32 y, int is_32col
|
||||
rotated_blit16:
|
||||
stmfd sp!,{r4-r8,lr}
|
||||
|
||||
add r0, r0, #(240*320)*2
|
||||
sub r0, r0, #(240+4)*2 @ y starts from 4
|
||||
add r0, r0, r2, lsl #1
|
||||
|
||||
tst r3, r3
|
||||
subne r0, r0, #(240*32)*2
|
||||
addne r1, r1, #32*2
|
||||
movne lr, #256/4
|
||||
moveq lr, #320/4
|
||||
|
||||
rotated_blit_loop16:
|
||||
ldr r2, [r1, #320*0*2]
|
||||
ldr r3, [r1, #320*1*2]
|
||||
ldr r4, [r1, #320*2*2]
|
||||
ldr r5, [r1, #320*3*2]
|
||||
rb_line_low
|
||||
stmia r0, {r7,r8}
|
||||
sub r0, r0, #240*2
|
||||
rb_line_hi
|
||||
stmia r0, {r7,r8}
|
||||
sub r0, r0, #240*2
|
||||
|
||||
ldr r2, [r1, #320*0*2+4]
|
||||
ldr r3, [r1, #320*1*2+4]
|
||||
ldr r4, [r1, #320*2*2+4]
|
||||
ldr r5, [r1, #320*3*2+4]
|
||||
rb_line_low
|
||||
stmia r0, {r7,r8}
|
||||
sub r0, r0, #240*2
|
||||
rb_line_hi
|
||||
stmia r0, {r7,r8}
|
||||
sub r0, r0, #240*2
|
||||
|
||||
subs lr, lr, #1
|
||||
add r1, r1, #8
|
||||
bne rotated_blit_loop16
|
||||
|
||||
ldmfd sp!,{r4-r8,pc}
|
||||
|
||||
|
||||
.global spend_cycles @ c
|
||||
|
||||
spend_cycles:
|
||||
mov r0, r0, lsr #2 @ 4 cycles/iteration
|
||||
sub r0, r0, #2 @ entry/exit/init
|
||||
.sc_loop:
|
||||
subs r0, r0, #1
|
||||
bpl .sc_loop
|
||||
|
||||
bx lr
|
||||
|
|
@ -1,154 +0,0 @@
|
|||
ifneq ($(DEBUG),)
|
||||
CFLAGS += -ggdb
|
||||
endif
|
||||
ifeq "$(profile)" "1"
|
||||
CFLAGS += -fprofile-generate
|
||||
endif
|
||||
ifeq "$(profile)" "2"
|
||||
CFLAGS += -fprofile-use
|
||||
endif
|
||||
ifeq "$(pdb)" "1"
|
||||
DEFINES += PDB
|
||||
OBJS += cpu/debug.o
|
||||
ifeq "$(pdb_net)" "1"
|
||||
DEFINES += PDB_NET
|
||||
endif
|
||||
ifeq "$(readline)" "1"
|
||||
DEFINES += HAVE_READLINE
|
||||
LDFLAGS += -lreadline
|
||||
endif
|
||||
endif
|
||||
ifeq "$(pprof)" "1"
|
||||
DEFINES += PPROF
|
||||
OBJS += platform/linux/pprof.o
|
||||
endif
|
||||
|
||||
# === Pico core ===
|
||||
# Pico
|
||||
OBJS += pico/state.o pico/cart.o pico/memory.o pico/pico.o pico/sek.o pico/z80if.o \
|
||||
pico/videoport.o pico/draw2.o pico/draw.o pico/mode4.o \
|
||||
pico/misc.o pico/eeprom.o pico/patch.o pico/debug.o
|
||||
# SMS
|
||||
ifneq "$(no_sms)" "1"
|
||||
OBJS += pico/sms.o
|
||||
else
|
||||
DEFINES += NO_SMS
|
||||
endif
|
||||
# CD
|
||||
OBJS += pico/cd/pico.o pico/cd/memory.o pico/cd/sek.o pico/cd/LC89510.o \
|
||||
pico/cd/cd_sys.o pico/cd/cd_file.o pico/cd/cue.o pico/cd/gfx_cd.o \
|
||||
pico/cd/misc.o pico/cd/pcm.o pico/cd/buffering.o
|
||||
# 32X
|
||||
ifneq "$(no_32x)" "1"
|
||||
OBJS += pico/32x/32x.o pico/32x/memory.o pico/32x/draw.o pico/32x/pwm.o
|
||||
else
|
||||
DEFINES += NO_32X
|
||||
endif
|
||||
# Pico
|
||||
OBJS += pico/pico/pico.o pico/pico/memory.o pico/pico/xpcm.o
|
||||
# carthw
|
||||
OBJS += pico/carthw/carthw.o
|
||||
# SVP
|
||||
OBJS += pico/carthw/svp/svp.o pico/carthw/svp/memory.o \
|
||||
pico/carthw/svp/ssp16.o
|
||||
# sound
|
||||
OBJS += pico/sound/sound.o
|
||||
OBJS += pico/sound/sn76496.o pico/sound/ym2612.o
|
||||
|
||||
# === CPU cores ===
|
||||
# --- M68k ---
|
||||
ifeq "$(use_musashi)" "1"
|
||||
DEFINES += EMU_M68K
|
||||
OBJS += cpu/musashi/m68kops.o cpu/musashi/m68kcpu.o
|
||||
#OBJS += cpu/musashi/m68kdasm.o
|
||||
endif
|
||||
ifeq "$(use_cyclone)" "1"
|
||||
DEFINES += EMU_C68K
|
||||
OBJS += pico/m68kif_cyclone.o cpu/Cyclone/proj/Cyclone.o cpu/Cyclone/tools/idle.o
|
||||
endif
|
||||
ifeq "$(use_fame)" "1"
|
||||
DEFINES += EMU_F68K
|
||||
OBJS += cpu/fame/famec.o
|
||||
endif
|
||||
|
||||
# --- Z80 ---
|
||||
ifeq "$(use_drz80)" "1"
|
||||
DEFINES += _USE_DRZ80
|
||||
OBJS += cpu/DrZ80/drz80.o
|
||||
endif
|
||||
#
|
||||
ifeq "$(use_cz80)" "1"
|
||||
DEFINES += _USE_CZ80
|
||||
OBJS += cpu/cz80/cz80.o
|
||||
endif
|
||||
|
||||
# --- SH2 ---
|
||||
OBJS += cpu/drc/cmn.o
|
||||
ifneq "$(no_32x)" "1"
|
||||
OBJS += cpu/sh2/sh2.o
|
||||
#
|
||||
ifeq "$(use_sh2drc)" "1"
|
||||
DEFINES += DRC_SH2
|
||||
OBJS += cpu/sh2/compiler.o
|
||||
ifdef drc_debug
|
||||
DEFINES += DRC_DEBUG=$(drc_debug)
|
||||
OBJS += cpu/sh2/mame/sh2dasm.o
|
||||
OBJS += platform/linux/host_dasm.o
|
||||
LDFLAGS += -lbfd -lopcodes -liberty
|
||||
endif
|
||||
ifeq "$(drc_debug_interp)" "1"
|
||||
DEFINES += DRC_DEBUG_INTERP
|
||||
use_sh2mame = 1
|
||||
endif
|
||||
endif # use_sh2drc
|
||||
#
|
||||
ifeq "$(use_sh2mame)" "1"
|
||||
OBJS += cpu/sh2/mame/sh2pico.o
|
||||
endif
|
||||
endif # !no_32x
|
||||
|
||||
|
||||
DIRS += platform platform/common pico pico/cd pico/pico pico/32x pico/sound pico/carthw/svp \
|
||||
cpu cpu/musashi cpu/cz80 cpu/fame cpu/sh2/mame cpu/drc
|
||||
|
||||
|
||||
# common rules
|
||||
.c.o:
|
||||
@echo ">>>" $<
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
.s.o:
|
||||
@echo ">>>" $<
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
clean_prof:
|
||||
find ../.. -name '*.gcno' -delete
|
||||
find ../.. -name '*.gcda' -delete
|
||||
|
||||
mkdirs:
|
||||
mkdir -p $(DIRS)
|
||||
|
||||
../../tools/textfilter: ../../tools/textfilter.c
|
||||
make -C ../../tools/ textfilter
|
||||
|
||||
|
||||
# random deps
|
||||
pico/carthw/svp/compiler.o : ../../cpu/drc/emit_$(ARCH).c
|
||||
cpu/sh2/compiler.o : ../../cpu/drc/emit_$(ARCH).c
|
||||
cpu/sh2/mame/sh2pico.o : ../../cpu/sh2/mame/sh2.c
|
||||
pico/pico.o pico/cd/pico.o : ../../pico/pico_cmn.c ../../pico/pico_int.h
|
||||
pico/memory.o pico/cd/memory.o : ../../pico/pico_int.h ../../pico/memory.h
|
||||
|
||||
../../cpu/musashi/m68kops.c :
|
||||
@make -C ../../cpu/musashi
|
||||
|
||||
../../cpu/mz80/mz80.asm :
|
||||
@make -C ../../cpu/mz80/
|
||||
|
||||
cpu/fame/famec.o : ../../cpu/fame/famec.c ../../cpu/fame/famec_opcodes.h
|
||||
@echo ">>>" $<
|
||||
$(CC) $(CFLAGS) -Wno-unused -c $< -o $@
|
||||
|
||||
../../cpu/Cyclone/proj/Cyclone.s:
|
||||
@echo building Cyclone...
|
||||
@make -C ../../cpu/Cyclone/proj CONFIG_FILE=config_pico.h
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
# asm stuff
|
||||
ifeq "$(asm_render)" "1"
|
||||
DEFINES += _ASM_DRAW_C
|
||||
OBJS += pico/draw_arm.o pico/draw2_arm.o
|
||||
endif
|
||||
ifeq "$(asm_memory)" "1"
|
||||
DEFINES += _ASM_MEMORY_C
|
||||
OBJS += pico/memory_arm.o
|
||||
endif
|
||||
ifeq "$(asm_ym2612)" "1"
|
||||
DEFINES += _ASM_YM2612_C
|
||||
OBJS += pico/sound/ym2612_arm.o
|
||||
endif
|
||||
ifeq "$(asm_misc)" "1"
|
||||
DEFINES += _ASM_MISC_C
|
||||
OBJS += pico/misc_arm.o
|
||||
OBJS += pico/cd/misc_arm.o
|
||||
endif
|
||||
ifeq "$(asm_cdpico)" "1"
|
||||
DEFINES += _ASM_CD_PICO_C
|
||||
OBJS += pico/cd/pico_arm.o
|
||||
endif
|
||||
ifeq "$(asm_cdmemory)" "1"
|
||||
DEFINES += _ASM_CD_MEMORY_C
|
||||
OBJS += pico/cd/memory_arm.o
|
||||
endif
|
||||
ifeq "$(asm_32xdraw)" "1"
|
||||
DEFINES += _ASM_32X_DRAW
|
||||
OBJS += pico/32x/draw_arm.o
|
||||
endif
|
||||
|
||||
|
||||
DIRS += cpu/Cyclone cpu/Cyclone/proj cpu/Cyclone/tools cpu/DrZ80
|
||||
|
||||
|
||||
# build helix libs
|
||||
../common/helix/$(CROSS)helix-mp3.a:
|
||||
make -C ../common/helix CROSS=$(CROSS) clean all
|
||||
|
840
common/config.c
840
common/config.c
|
@ -1,840 +0,0 @@
|
|||
/*
|
||||
* Human-readable config file management for PicoDrive
|
||||
* (c) notaz, 2008
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef __EPOC32__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "config.h"
|
||||
#include "plat.h"
|
||||
#include "input.h"
|
||||
#include "lprintf.h"
|
||||
|
||||
static char *mystrip(char *str);
|
||||
|
||||
#ifndef _MSC_VER
|
||||
|
||||
#include "menu.h"
|
||||
#include "menu_pico.h"
|
||||
#include "emu.h"
|
||||
#include <pico/pico.h>
|
||||
|
||||
// always output DOS endlines
|
||||
#ifdef _WIN32
|
||||
#define NL "\n"
|
||||
#else
|
||||
#define NL "\r\n"
|
||||
#endif
|
||||
|
||||
static int seek_sect(FILE *f, const char *section)
|
||||
{
|
||||
char line[128], *tmp;
|
||||
int len;
|
||||
|
||||
len = strlen(section);
|
||||
// seek to the section needed
|
||||
while (!feof(f))
|
||||
{
|
||||
tmp = fgets(line, sizeof(line), f);
|
||||
if (tmp == NULL) break;
|
||||
|
||||
if (line[0] != '[') continue; // not section start
|
||||
if (strncmp(line + 1, section, len) == 0 && line[len+1] == ']')
|
||||
return 1; // found it
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void keys_write(FILE *fn, const char *bind_str, int dev_id, const int *binds, int no_defaults)
|
||||
{
|
||||
char act[48];
|
||||
int key_count = 0, k, i;
|
||||
const int *def_binds;
|
||||
|
||||
in_get_config(dev_id, IN_CFG_BIND_COUNT, &key_count);
|
||||
def_binds = in_get_dev_def_binds(dev_id);
|
||||
|
||||
for (k = 0; k < key_count; k++)
|
||||
{
|
||||
const char *name;
|
||||
int t, mask;
|
||||
act[0] = act[31] = 0;
|
||||
|
||||
for (t = 0; t < IN_BINDTYPE_COUNT; t++)
|
||||
if (binds[IN_BIND_OFFS(k, t)] != def_binds[IN_BIND_OFFS(k, t)])
|
||||
break;
|
||||
|
||||
if (no_defaults && t == IN_BINDTYPE_COUNT)
|
||||
continue; /* no change from defaults */
|
||||
|
||||
name = in_get_key_name(dev_id, k);
|
||||
|
||||
for (t = 0; t < IN_BINDTYPE_COUNT; t++)
|
||||
if (binds[IN_BIND_OFFS(k, t)] != 0 || def_binds[IN_BIND_OFFS(k, t)] == 0)
|
||||
break;
|
||||
|
||||
if (t == IN_BINDTYPE_COUNT) {
|
||||
/* key has default bind removed */
|
||||
fprintf(fn, "%s %s =" NL, bind_str, name);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; me_ctrl_actions[i].name != NULL; i++) {
|
||||
mask = me_ctrl_actions[i].mask;
|
||||
if (mask & binds[IN_BIND_OFFS(k, IN_BINDTYPE_PLAYER12)]) {
|
||||
strncpy(act, me_ctrl_actions[i].name, 31);
|
||||
fprintf(fn, "%s %s = player1 %s" NL, bind_str, name, mystrip(act));
|
||||
}
|
||||
mask = me_ctrl_actions[i].mask << 16;
|
||||
if (mask & binds[IN_BIND_OFFS(k, IN_BINDTYPE_PLAYER12)]) {
|
||||
strncpy(act, me_ctrl_actions[i].name, 31);
|
||||
fprintf(fn, "%s %s = player2 %s" NL, bind_str, name, mystrip(act));
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; emuctrl_actions[i].name != NULL; i++) {
|
||||
mask = emuctrl_actions[i].mask;
|
||||
if (mask & binds[IN_BIND_OFFS(k, IN_BINDTYPE_EMU)]) {
|
||||
strncpy(act, emuctrl_actions[i].name, 31);
|
||||
fprintf(fn, "%s %s = %s" NL, bind_str, name, mystrip(act));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX: this should go to menu structures instead */
|
||||
static int default_var(const menu_entry *me)
|
||||
{
|
||||
switch (me->id)
|
||||
{
|
||||
case MA_OPT2_ENABLE_YM2612:
|
||||
case MA_OPT2_ENABLE_SN76496:
|
||||
case MA_OPT2_ENABLE_Z80:
|
||||
case MA_OPT_6BUTTON_PAD:
|
||||
case MA_OPT_ACC_SPRITES:
|
||||
case MA_OPT_ARM940_SOUND:
|
||||
case MA_CDOPT_PCM:
|
||||
case MA_CDOPT_CDDA:
|
||||
case MA_CDOPT_SCALEROT_CHIP:
|
||||
case MA_CDOPT_BETTER_SYNC:
|
||||
case MA_CDOPT_SAVERAM:
|
||||
case MA_32XOPT_ENABLE_32X:
|
||||
case MA_32XOPT_PWM:
|
||||
case MA_OPT2_SVP_DYNAREC:
|
||||
case MA_OPT2_NO_SPRITE_LIM:
|
||||
case MA_OPT2_NO_IDLE_LOOPS:
|
||||
return defaultConfig.s_PicoOpt;
|
||||
|
||||
case MA_OPT_SRAM_STATES:
|
||||
case MA_OPT_SHOW_FPS:
|
||||
case MA_OPT_ENABLE_SOUND:
|
||||
case MA_OPT2_GZIP_STATES:
|
||||
case MA_OPT2_SQUIDGEHACK:
|
||||
case MA_OPT2_NO_LAST_ROM:
|
||||
case MA_OPT2_RAMTIMINGS:
|
||||
case MA_CDOPT_LEDS:
|
||||
case MA_OPT2_A_SN_GAMMA:
|
||||
case MA_OPT2_VSYNC:
|
||||
case MA_OPT_INTERLACED:
|
||||
case MA_OPT2_DBLBUFF:
|
||||
case MA_OPT2_STATUS_LINE:
|
||||
case MA_OPT2_NO_FRAME_LIMIT:
|
||||
case MA_OPT_TEARING_FIX:
|
||||
return defaultConfig.EmuOpt;
|
||||
|
||||
case MA_CTRL_TURBO_RATE: return defaultConfig.turbo_rate;
|
||||
case MA_OPT_SCALING: return defaultConfig.scaling;
|
||||
case MA_OPT_ROTATION: return defaultConfig.rotation;
|
||||
case MA_OPT2_GAMMA: return defaultConfig.gamma;
|
||||
case MA_OPT_FRAMESKIP: return defaultConfig.Frameskip;
|
||||
case MA_OPT_CONFIRM_STATES: return defaultConfig.confirm_save;
|
||||
case MA_OPT_CPU_CLOCKS: return defaultConfig.CPUclock;
|
||||
case MA_OPT_RENDERER: return defaultConfig.renderer;
|
||||
case MA_32XOPT_RENDERER: return defaultConfig.renderer32x;
|
||||
|
||||
case MA_OPT_SAVE_SLOT:
|
||||
return 0;
|
||||
|
||||
default:
|
||||
lprintf("missing default for %d\n", me->id);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int is_cust_val_default(const menu_entry *me)
|
||||
{
|
||||
switch (me->id)
|
||||
{
|
||||
case MA_OPT_REGION:
|
||||
return defaultConfig.s_PicoRegion == PicoRegionOverride &&
|
||||
defaultConfig.s_PicoAutoRgnOrder == PicoAutoRgnOrder;
|
||||
case MA_OPT_SOUND_QUALITY:
|
||||
return defaultConfig.s_PsndRate == PsndRate &&
|
||||
((defaultConfig.s_PicoOpt ^ PicoOpt) & POPT_EN_STEREO) == 0;
|
||||
case MA_CDOPT_READAHEAD:
|
||||
return defaultConfig.s_PicoCDBuffers == PicoCDBuffers;
|
||||
case MA_32XOPT_MSH2_CYCLES:
|
||||
return p32x_msh2_multiplier == MSH2_MULTI_DEFAULT;
|
||||
case MA_32XOPT_SSH2_CYCLES:
|
||||
return p32x_ssh2_multiplier == SSH2_MULTI_DEFAULT;
|
||||
default:break;
|
||||
}
|
||||
|
||||
lprintf("is_cust_val_default: unhandled id %i\n", me->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_writesect(const char *fname, const char *section)
|
||||
{
|
||||
FILE *fo = NULL, *fn = NULL; // old and new
|
||||
int no_defaults = 0; // avoid saving defaults
|
||||
menu_entry *me;
|
||||
int t, tlen, ret;
|
||||
char line[128], *tmp;
|
||||
|
||||
if (section != NULL)
|
||||
{
|
||||
no_defaults = 1;
|
||||
|
||||
fo = fopen(fname, "r");
|
||||
if (fo == NULL) {
|
||||
fn = fopen(fname, "w");
|
||||
goto write;
|
||||
}
|
||||
|
||||
ret = seek_sect(fo, section);
|
||||
if (!ret) {
|
||||
// sect not found, we can simply append
|
||||
fclose(fo); fo = NULL;
|
||||
fn = fopen(fname, "a");
|
||||
goto write;
|
||||
}
|
||||
|
||||
// use 2 files..
|
||||
fclose(fo);
|
||||
rename(fname, "tmp.cfg");
|
||||
fo = fopen("tmp.cfg", "r");
|
||||
fn = fopen(fname, "w");
|
||||
if (fo == NULL || fn == NULL) goto write;
|
||||
|
||||
// copy everything until sect
|
||||
tlen = strlen(section);
|
||||
while (!feof(fo))
|
||||
{
|
||||
tmp = fgets(line, sizeof(line), fo);
|
||||
if (tmp == NULL) break;
|
||||
|
||||
if (line[0] == '[' && strncmp(line + 1, section, tlen) == 0 && line[tlen+1] == ']')
|
||||
break;
|
||||
fputs(line, fn);
|
||||
}
|
||||
|
||||
// now skip to next sect
|
||||
while (!feof(fo))
|
||||
{
|
||||
tmp = fgets(line, sizeof(line), fo);
|
||||
if (tmp == NULL) break;
|
||||
if (line[0] == '[') {
|
||||
fseek(fo, -strlen(line), SEEK_CUR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (feof(fo))
|
||||
{
|
||||
fclose(fo); fo = NULL;
|
||||
remove("tmp.cfg");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fn = fopen(fname, "w");
|
||||
}
|
||||
|
||||
write:
|
||||
if (fn == NULL) {
|
||||
if (fo) fclose(fo);
|
||||
return -1;
|
||||
}
|
||||
if (section != NULL)
|
||||
fprintf(fn, "[%s]" NL, section);
|
||||
|
||||
for (me = me_list_get_first(); me != NULL; me = me_list_get_next())
|
||||
{
|
||||
int dummy;
|
||||
if (!me->need_to_save)
|
||||
continue;
|
||||
if (me->name == NULL || me->name[0] == 0)
|
||||
continue;
|
||||
|
||||
if (me->beh == MB_OPT_ONOFF || me->beh == MB_OPT_CUSTONOFF) {
|
||||
if (!no_defaults || ((*(int *)me->var ^ default_var(me)) & me->mask))
|
||||
fprintf(fn, "%s = %i" NL, me->name, (*(int *)me->var & me->mask) ? 1 : 0);
|
||||
}
|
||||
else if (me->beh == MB_OPT_RANGE || me->beh == MB_OPT_CUSTRANGE) {
|
||||
if (!no_defaults || (*(int *)me->var ^ default_var(me)))
|
||||
fprintf(fn, "%s = %i" NL, me->name, *(int *)me->var);
|
||||
}
|
||||
else if (me->beh == MB_OPT_ENUM && me->data != NULL) {
|
||||
const char **names = (const char **)me->data;
|
||||
for (t = 0; names[t] != NULL; t++)
|
||||
if (*(int *)me->var == t && (!no_defaults || (*(int *)me->var ^ default_var(me)))) {
|
||||
strncpy(line, names[t], sizeof(line));
|
||||
goto write_line;
|
||||
}
|
||||
}
|
||||
else if (me->generate_name != NULL) {
|
||||
if (!no_defaults || !is_cust_val_default(me)) {
|
||||
strncpy(line, me->generate_name(0, &dummy), sizeof(line));
|
||||
goto write_line;
|
||||
}
|
||||
}
|
||||
else
|
||||
lprintf("config: unhandled write: %i\n", me->id);
|
||||
continue;
|
||||
|
||||
write_line:
|
||||
line[sizeof(line) - 1] = 0;
|
||||
mystrip(line);
|
||||
fprintf(fn, "%s = %s" NL, me->name, line);
|
||||
}
|
||||
|
||||
/* input: save device names */
|
||||
for (t = 0; t < IN_MAX_DEVS; t++)
|
||||
{
|
||||
const int *binds = in_get_dev_binds(t);
|
||||
const char *name = in_get_dev_name(t, 0, 0);
|
||||
if (binds == NULL || name == NULL)
|
||||
continue;
|
||||
|
||||
fprintf(fn, "input%d = %s" NL, t, name);
|
||||
}
|
||||
|
||||
/* input: save binds */
|
||||
for (t = 0; t < IN_MAX_DEVS; t++)
|
||||
{
|
||||
const int *binds = in_get_dev_binds(t);
|
||||
const char *name = in_get_dev_name(t, 0, 0);
|
||||
char strbind[16];
|
||||
int count = 0;
|
||||
|
||||
if (binds == NULL || name == NULL)
|
||||
continue;
|
||||
|
||||
sprintf(strbind, "bind%d", t);
|
||||
if (t == 0) strbind[4] = 0;
|
||||
|
||||
in_get_config(t, IN_CFG_BIND_COUNT, &count);
|
||||
keys_write(fn, strbind, t, binds, no_defaults);
|
||||
}
|
||||
|
||||
#ifndef PSP
|
||||
if (section == NULL)
|
||||
fprintf(fn, "Sound Volume = %i" NL, currentConfig.volume);
|
||||
#endif
|
||||
|
||||
fprintf(fn, NL);
|
||||
|
||||
if (fo != NULL)
|
||||
{
|
||||
// copy whatever is left
|
||||
while (!feof(fo))
|
||||
{
|
||||
tmp = fgets(line, sizeof(line), fo);
|
||||
if (tmp == NULL) break;
|
||||
|
||||
fputs(line, fn);
|
||||
}
|
||||
fclose(fo);
|
||||
remove("tmp.cfg");
|
||||
}
|
||||
|
||||
fclose(fn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int config_writelrom(const char *fname)
|
||||
{
|
||||
char line[128], *tmp, *optr = NULL;
|
||||
char *old_data = NULL;
|
||||
int size;
|
||||
FILE *f;
|
||||
|
||||
if (strlen(rom_fname_loaded) == 0) return -1;
|
||||
|
||||
f = fopen(fname, "r");
|
||||
if (f != NULL)
|
||||
{
|
||||
fseek(f, 0, SEEK_END);
|
||||
size = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
old_data = malloc(size + size/8);
|
||||
if (old_data != NULL)
|
||||
{
|
||||
optr = old_data;
|
||||
while (!feof(f))
|
||||
{
|
||||
tmp = fgets(line, sizeof(line), f);
|
||||
if (tmp == NULL) break;
|
||||
mystrip(line);
|
||||
if (strncasecmp(line, "LastUsedROM", 11) == 0)
|
||||
continue;
|
||||
sprintf(optr, "%s", line);
|
||||
optr += strlen(optr);
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
f = fopen(fname, "w");
|
||||
if (f == NULL) return -1;
|
||||
|
||||
if (old_data != NULL) {
|
||||
fwrite(old_data, 1, optr - old_data, f);
|
||||
free(old_data);
|
||||
}
|
||||
fprintf(f, "LastUsedROM = %s" NL, rom_fname_loaded);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------*/
|
||||
|
||||
int config_readlrom(const char *fname)
|
||||
{
|
||||
char line[128], *tmp;
|
||||
int i, len, ret = -1;
|
||||
FILE *f;
|
||||
|
||||
f = fopen(fname, "r");
|
||||
if (f == NULL) return -1;
|
||||
|
||||
// seek to the section needed
|
||||
while (!feof(f))
|
||||
{
|
||||
tmp = fgets(line, sizeof(line), f);
|
||||
if (tmp == NULL) break;
|
||||
|
||||
if (strncasecmp(line, "LastUsedROM", 11) != 0) continue;
|
||||
len = strlen(line);
|
||||
for (i = 0; i < len; i++)
|
||||
if (line[i] == '#' || line[i] == '\r' || line[i] == '\n') { line[i] = 0; break; }
|
||||
tmp = strchr(line, '=');
|
||||
if (tmp == NULL) break;
|
||||
tmp++;
|
||||
mystrip(tmp);
|
||||
|
||||
len = sizeof(rom_fname_loaded);
|
||||
strncpy(rom_fname_loaded, tmp, len);
|
||||
rom_fname_loaded[len-1] = 0;
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
fclose(f);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int custom_read(menu_entry *me, const char *var, const char *val)
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
switch (me->id)
|
||||
{
|
||||
case MA_OPT_FRAMESKIP:
|
||||
if (strcasecmp(var, "Frameskip") != 0) return 0;
|
||||
if (strcasecmp(val, "Auto") == 0)
|
||||
currentConfig.Frameskip = -1;
|
||||
else currentConfig.Frameskip = atoi(val);
|
||||
return 1;
|
||||
|
||||
case MA_OPT_SOUND_QUALITY:
|
||||
if (strcasecmp(var, "Sound Quality") != 0) return 0;
|
||||
PsndRate = strtoul(val, &tmp, 10);
|
||||
if (PsndRate < 8000 || PsndRate > 44100)
|
||||
PsndRate = 22050;
|
||||
if (*tmp == 'H' || *tmp == 'h') tmp++;
|
||||
if (*tmp == 'Z' || *tmp == 'z') tmp++;
|
||||
while (*tmp == ' ') tmp++;
|
||||
if (strcasecmp(tmp, "stereo") == 0) {
|
||||
PicoOpt |= POPT_EN_STEREO;
|
||||
} else if (strcasecmp(tmp, "mono") == 0) {
|
||||
PicoOpt &= ~POPT_EN_STEREO;
|
||||
} else
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
case MA_OPT_REGION:
|
||||
if (strcasecmp(var, "Region") != 0) return 0;
|
||||
if (strncasecmp(val, "Auto: ", 6) == 0)
|
||||
{
|
||||
const char *p = val + 5, *end = val + strlen(val);
|
||||
int i;
|
||||
PicoRegionOverride = PicoAutoRgnOrder = 0;
|
||||
for (i = 0; p < end && i < 3; i++)
|
||||
{
|
||||
while (*p == ' ') p++;
|
||||
if (p[0] == 'J' && p[1] == 'P') {
|
||||
PicoAutoRgnOrder |= 1 << (i*4);
|
||||
} else if (p[0] == 'U' && p[1] == 'S') {
|
||||
PicoAutoRgnOrder |= 4 << (i*4);
|
||||
} else if (p[0] == 'E' && p[1] == 'U') {
|
||||
PicoAutoRgnOrder |= 8 << (i*4);
|
||||
}
|
||||
while (*p != ' ' && *p != 0) p++;
|
||||
if (*p == 0) break;
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(val, "Auto") == 0) {
|
||||
PicoRegionOverride = 0;
|
||||
} else if (strcasecmp(val, "Japan NTSC") == 0) {
|
||||
PicoRegionOverride = 1;
|
||||
} else if (strcasecmp(val, "Japan PAL") == 0) {
|
||||
PicoRegionOverride = 2;
|
||||
} else if (strcasecmp(val, "USA") == 0) {
|
||||
PicoRegionOverride = 4;
|
||||
} else if (strcasecmp(val, "Europe") == 0) {
|
||||
PicoRegionOverride = 8;
|
||||
} else
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
case MA_OPT2_GAMMA:
|
||||
if (strcasecmp(var, "Gamma correction") != 0) return 0;
|
||||
currentConfig.gamma = (int) (atof(val) * 100.0);
|
||||
return 1;
|
||||
|
||||
case MA_CDOPT_READAHEAD:
|
||||
if (strcasecmp(var, "ReadAhead buffer") != 0) return 0;
|
||||
PicoCDBuffers = atoi(val) / 2;
|
||||
return 1;
|
||||
|
||||
case MA_32XOPT_MSH2_CYCLES:
|
||||
case MA_32XOPT_SSH2_CYCLES: {
|
||||
int *mul = (me->id == MA_32XOPT_MSH2_CYCLES) ? &p32x_msh2_multiplier : &p32x_ssh2_multiplier;
|
||||
*mul = ((unsigned int)atoi(val) << SH2_MULTI_SHIFT) / 7670;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* PSP */
|
||||
case MA_OPT3_SCALE:
|
||||
if (strcasecmp(var, "Scale factor") != 0) return 0;
|
||||
currentConfig.scale = atof(val);
|
||||
return 1;
|
||||
case MA_OPT3_HSCALE32:
|
||||
if (strcasecmp(var, "Hor. scale (for low res. games)") != 0) return 0;
|
||||
currentConfig.hscale32 = atof(val);
|
||||
return 1;
|
||||
case MA_OPT3_HSCALE40:
|
||||
if (strcasecmp(var, "Hor. scale (for hi res. games)") != 0) return 0;
|
||||
currentConfig.hscale40 = atof(val);
|
||||
return 1;
|
||||
case MA_OPT3_VSYNC:
|
||||
// XXX: use enum
|
||||
if (strcasecmp(var, "Wait for vsync") != 0) return 0;
|
||||
if (strcasecmp(val, "never") == 0) {
|
||||
currentConfig.EmuOpt &= ~0x12000;
|
||||
} else if (strcasecmp(val, "sometimes") == 0) {
|
||||
currentConfig.EmuOpt |= 0x12000;
|
||||
} else if (strcasecmp(val, "always") == 0) {
|
||||
currentConfig.EmuOpt &= ~0x12000;
|
||||
currentConfig.EmuOpt |= 0x02000;
|
||||
} else
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
default:
|
||||
lprintf("unhandled custom_read %i: %s\n", me->id, var);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static unsigned int keys_encountered = 0;
|
||||
|
||||
static int parse_bind_val(const char *val, int *type)
|
||||
{
|
||||
int i;
|
||||
|
||||
*type = IN_BINDTYPE_NONE;
|
||||
if (val[0] == 0)
|
||||
return 0;
|
||||
|
||||
if (strncasecmp(val, "player", 6) == 0)
|
||||
{
|
||||
int player, shift = 0;
|
||||
player = atoi(val + 6) - 1;
|
||||
|
||||
if (player > 1)
|
||||
return -1;
|
||||
if (player == 1)
|
||||
shift = 16;
|
||||
|
||||
*type = IN_BINDTYPE_PLAYER12;
|
||||
for (i = 0; me_ctrl_actions[i].name != NULL; i++) {
|
||||
if (strncasecmp(me_ctrl_actions[i].name, val + 8, strlen(val + 8)) == 0)
|
||||
return me_ctrl_actions[i].mask << shift;
|
||||
}
|
||||
}
|
||||
for (i = 0; emuctrl_actions[i].name != NULL; i++) {
|
||||
if (strncasecmp(emuctrl_actions[i].name, val, strlen(val)) == 0) {
|
||||
*type = IN_BINDTYPE_EMU;
|
||||
return emuctrl_actions[i].mask;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void keys_parse(const char *key, const char *val, int dev_id)
|
||||
{
|
||||
int acts, type;
|
||||
|
||||
acts = parse_bind_val(val, &type);
|
||||
if (acts == -1) {
|
||||
lprintf("config: unhandled action \"%s\"\n", val);
|
||||
return;
|
||||
}
|
||||
|
||||
in_config_bind_key(dev_id, key, acts, type);
|
||||
}
|
||||
|
||||
static int get_numvar_num(const char *var)
|
||||
{
|
||||
char *p = NULL;
|
||||
int num;
|
||||
|
||||
if (var[0] == ' ')
|
||||
return 0;
|
||||
|
||||
num = strtoul(var, &p, 10);
|
||||
if (*p == 0 || *p == ' ')
|
||||
return num;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* map dev number in confing to input dev number */
|
||||
static unsigned char input_dev_map[IN_MAX_DEVS];
|
||||
|
||||
static void parse(const char *var, const char *val)
|
||||
{
|
||||
menu_entry *me;
|
||||
int tmp;
|
||||
|
||||
if (strcasecmp(var, "LastUsedROM") == 0)
|
||||
return; /* handled elsewhere */
|
||||
|
||||
if (strcasecmp(var, "Sound Volume") == 0) {
|
||||
currentConfig.volume = atoi(val);
|
||||
return;
|
||||
}
|
||||
|
||||
/* input: device name */
|
||||
if (strncasecmp(var, "input", 5) == 0) {
|
||||
int num = get_numvar_num(var + 5);
|
||||
if (num >= 0 && num < IN_MAX_DEVS)
|
||||
input_dev_map[num] = in_config_parse_dev(val);
|
||||
else
|
||||
lprintf("config: failed to parse: %s\n", var);
|
||||
return;
|
||||
}
|
||||
|
||||
// key binds
|
||||
if (strncasecmp(var, "bind", 4) == 0) {
|
||||
const char *p = var + 4;
|
||||
int num = get_numvar_num(p);
|
||||
if (num < 0 || num >= IN_MAX_DEVS) {
|
||||
lprintf("config: failed to parse: %s\n", var);
|
||||
return;
|
||||
}
|
||||
|
||||
num = input_dev_map[num];
|
||||
if (num < 0 || num >= IN_MAX_DEVS) {
|
||||
lprintf("config: invalid device id: %s\n", var);
|
||||
return;
|
||||
}
|
||||
|
||||
while (*p && *p != ' ') p++;
|
||||
while (*p && *p == ' ') p++;
|
||||
keys_parse(p, val, num);
|
||||
return;
|
||||
}
|
||||
|
||||
for (me = me_list_get_first(); me != NULL; me = me_list_get_next())
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (!me->need_to_save)
|
||||
continue;
|
||||
if (me->name == NULL || strcasecmp(var, me->name) != 0)
|
||||
continue;
|
||||
|
||||
if (me->beh == MB_OPT_ONOFF) {
|
||||
tmp = strtol(val, &p, 0);
|
||||
if (*p != 0)
|
||||
goto bad_val;
|
||||
if (tmp) *(int *)me->var |= me->mask;
|
||||
else *(int *)me->var &= ~me->mask;
|
||||
return;
|
||||
}
|
||||
else if (me->beh == MB_OPT_RANGE) {
|
||||
tmp = strtol(val, &p, 0);
|
||||
if (*p != 0)
|
||||
goto bad_val;
|
||||
if (tmp < me->min) tmp = me->min;
|
||||
if (tmp > me->max) tmp = me->max;
|
||||
*(int *)me->var = tmp;
|
||||
return;
|
||||
}
|
||||
else if (me->beh == MB_OPT_ENUM) {
|
||||
const char **names, *p1;
|
||||
int i;
|
||||
|
||||
names = (const char **)me->data;
|
||||
if (names == NULL)
|
||||
goto bad_val;
|
||||
for (i = 0; names[i] != NULL; i++) {
|
||||
for (p1 = names[i]; *p1 == ' '; p1++)
|
||||
;
|
||||
if (strcasecmp(p1, val) == 0) {
|
||||
*(int *)me->var = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
goto bad_val;
|
||||
}
|
||||
else if (custom_read(me, var, val))
|
||||
return;
|
||||
}
|
||||
|
||||
lprintf("config_readsect: unhandled var: \"%s\"\n", var);
|
||||
return;
|
||||
|
||||
bad_val:
|
||||
lprintf("config_readsect: unhandled val for \"%s\": %s\n", var, val);
|
||||
}
|
||||
|
||||
|
||||
int config_havesect(const char *fname, const char *section)
|
||||
{
|
||||
FILE *f;
|
||||
int ret;
|
||||
|
||||
f = fopen(fname, "r");
|
||||
if (f == NULL) return 0;
|
||||
|
||||
ret = seek_sect(f, section);
|
||||
fclose(f);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int config_readsect(const char *fname, const char *section)
|
||||
{
|
||||
char line[128], *var, *val;
|
||||
FILE *f;
|
||||
int ret;
|
||||
|
||||
f = fopen(fname, "r");
|
||||
if (f == NULL) return -1;
|
||||
|
||||
if (section != NULL)
|
||||
{
|
||||
ret = seek_sect(f, section);
|
||||
if (!ret) {
|
||||
lprintf("config_readsect: %s: missing section [%s]\n", fname, section);
|
||||
fclose(f);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
keys_encountered = 0;
|
||||
memset(input_dev_map, 0xff, sizeof(input_dev_map));
|
||||
|
||||
while (!feof(f))
|
||||
{
|
||||
ret = config_get_var_val(f, line, sizeof(line), &var, &val);
|
||||
if (ret == 0) break;
|
||||
if (ret == -1) continue;
|
||||
|
||||
parse(var, val);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // _MSC_VER
|
||||
|
||||
static char *mystrip(char *str)
|
||||
{
|
||||
int i, len;
|
||||
|
||||
len = strlen(str);
|
||||
for (i = 0; i < len; i++)
|
||||
if (str[i] != ' ') break;
|
||||
if (i > 0) memmove(str, str + i, len - i + 1);
|
||||
|
||||
len = strlen(str);
|
||||
for (i = len - 1; i >= 0; i--)
|
||||
if (str[i] != ' ') break;
|
||||
str[i+1] = 0;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/* returns:
|
||||
* 0 - EOF, end
|
||||
* 1 - parsed ok
|
||||
* -1 - failed to parse line
|
||||
*/
|
||||
int config_get_var_val(void *file, char *line, int lsize, char **rvar, char **rval)
|
||||
{
|
||||
char *var, *val, *tmp;
|
||||
FILE *f = file;
|
||||
int len, i;
|
||||
|
||||
tmp = fgets(line, lsize, f);
|
||||
if (tmp == NULL) return 0;
|
||||
|
||||
if (line[0] == '[') return 0; // other section
|
||||
|
||||
// strip comments, linefeed, spaces..
|
||||
len = strlen(line);
|
||||
for (i = 0; i < len; i++)
|
||||
if (line[i] == '#' || line[i] == '\r' || line[i] == '\n') { line[i] = 0; break; }
|
||||
mystrip(line);
|
||||
len = strlen(line);
|
||||
if (len <= 0) return -1;;
|
||||
|
||||
// get var and val
|
||||
for (i = 0; i < len; i++)
|
||||
if (line[i] == '=') break;
|
||||
if (i >= len || strchr(&line[i+1], '=') != NULL) {
|
||||
lprintf("config_readsect: can't parse: %s\n", line);
|
||||
return -1;
|
||||
}
|
||||
line[i] = 0;
|
||||
var = line;
|
||||
val = &line[i+1];
|
||||
mystrip(var);
|
||||
mystrip(val);
|
||||
|
||||
#ifndef _MSC_VER
|
||||
if (strlen(var) == 0 || (strlen(val) == 0 && strncasecmp(var, "bind", 4) != 0)) {
|
||||
lprintf("config_readsect: something's empty: \"%s\" = \"%s\"\n", var, val);
|
||||
return -1;;
|
||||
}
|
||||
#endif
|
||||
|
||||
*rvar = var;
|
||||
*rval = val;
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int config_writesect(const char *fname, const char *section);
|
||||
int config_writelrom(const char *fname);
|
||||
int config_readsect(const char *fname, const char *section);
|
||||
int config_readlrom(const char *fname);
|
||||
int config_havesect(const char *fname, const char *section);
|
||||
int config_get_var_val(void *file, char *line, int lsize, char **rvar, char **rval);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
1636
common/emu.c
1636
common/emu.c
File diff suppressed because it is too large
Load diff
155
common/emu.h
155
common/emu.h
|
@ -1,155 +0,0 @@
|
|||
// (c) Copyright 2006-2007 notaz, All rights reserved.
|
||||
// Free for non-commercial use.
|
||||
|
||||
// For commercial use, separate licencing terms must be obtained.
|
||||
|
||||
#include "port_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define array_size(x) (sizeof(x) / sizeof(x[0]))
|
||||
|
||||
extern void *g_screen_ptr;
|
||||
|
||||
#if SCREEN_SIZE_FIXED
|
||||
#define g_screen_width SCREEN_WIDTH
|
||||
#define g_screen_height SCREEN_HEIGHT
|
||||
#else
|
||||
extern int g_screen_width;
|
||||
extern int g_screen_height;
|
||||
#endif
|
||||
|
||||
|
||||
#define EOPT_EN_SRAM (1<<0)
|
||||
#define EOPT_SHOW_FPS (1<<1)
|
||||
#define EOPT_EN_SOUND (1<<2)
|
||||
#define EOPT_GZIP_SAVES (1<<3)
|
||||
#define EOPT_MMUHACK (1<<4)
|
||||
#define EOPT_NO_AUTOSVCFG (1<<5)
|
||||
#define EOPT_16BPP (1<<7) // depreceted for .renderer
|
||||
#define EOPT_RAM_TIMINGS (1<<8)
|
||||
#define EOPT_EN_CD_LEDS (1<<10)
|
||||
#define EOPT_A_SN_GAMMA (1<<12)
|
||||
#define EOPT_VSYNC (1<<13)
|
||||
#define EOPT_GIZ_SCANLN (1<<14)
|
||||
#define EOPT_GIZ_DBLBUF (1<<15)
|
||||
#define EOPT_VSYNC_MODE (1<<16)
|
||||
#define EOPT_SHOW_RTC (1<<17)
|
||||
#define EOPT_NO_FRMLIMIT (1<<18)
|
||||
#define EOPT_WIZ_TEAR_FIX (1<<19)
|
||||
#define EOPT_EXT_FRMLIMIT (1<<20) // no internal frame limiter (limited by snd, etc)
|
||||
|
||||
enum {
|
||||
EOPT_SCALE_NONE = 0,
|
||||
EOPT_SCALE_SW,
|
||||
EOPT_SCALE_HW,
|
||||
};
|
||||
|
||||
enum {
|
||||
EOPT_CONFIRM_NONE = 0,
|
||||
EOPT_CONFIRM_SAVE = 1,
|
||||
EOPT_CONFIRM_LOAD = 2,
|
||||
EOPT_CONFIRM_BOTH = 3,
|
||||
};
|
||||
|
||||
typedef struct _currentConfig_t {
|
||||
int EmuOpt;
|
||||
int s_PicoOpt;
|
||||
int s_PsndRate;
|
||||
int s_PicoRegion;
|
||||
int s_PicoAutoRgnOrder;
|
||||
int s_PicoCDBuffers;
|
||||
int Frameskip;
|
||||
int confirm_save;
|
||||
int CPUclock;
|
||||
int volume;
|
||||
int gamma;
|
||||
int scaling; // gp2x: EOPT_SCALE_*; psp: bilinear filtering
|
||||
int vscaling;
|
||||
int rotation; // for UIQ
|
||||
float scale; // psp: screen scale
|
||||
float hscale32, hscale40; // psp: horizontal scale
|
||||
int gamma2; // psp: black level
|
||||
int turbo_rate;
|
||||
int renderer;
|
||||
int renderer32x;
|
||||
int filter; // pandora
|
||||
int analog_deadzone;
|
||||
} currentConfig_t;
|
||||
|
||||
extern currentConfig_t currentConfig, defaultConfig;
|
||||
extern char *PicoConfigFile;
|
||||
extern int rom_loaded;
|
||||
extern int state_slot;
|
||||
extern int config_slot, config_slot_current;
|
||||
extern unsigned char *movie_data;
|
||||
extern int reset_timing;
|
||||
|
||||
#define PICO_PEN_ADJUST_X 4
|
||||
#define PICO_PEN_ADJUST_Y 2
|
||||
extern int pico_pen_x, pico_pen_y;
|
||||
extern int pico_inp_mode;
|
||||
|
||||
extern char rom_fname_reload[512]; // ROM to try loading on next PGS_ReloadRom
|
||||
extern char rom_fname_loaded[512]; // currently loaded ROM filename
|
||||
|
||||
// engine states
|
||||
extern int engineState;
|
||||
enum TPicoGameState {
|
||||
PGS_Paused = 1,
|
||||
PGS_Running,
|
||||
PGS_Quit,
|
||||
PGS_KeyConfig,
|
||||
PGS_ReloadRom,
|
||||
PGS_Menu,
|
||||
PGS_TrayMenu,
|
||||
PGS_RestartRun,
|
||||
PGS_Suspending, /* PSP */
|
||||
PGS_SuspendWake, /* PSP */
|
||||
};
|
||||
|
||||
// media types
|
||||
enum {
|
||||
PM_BAD = 0,
|
||||
PM_MD_CART, /* also 32x */
|
||||
PM_MARK3,
|
||||
PM_CD,
|
||||
};
|
||||
|
||||
void emu_init(void);
|
||||
void emu_finish(void);
|
||||
void emu_loop(void);
|
||||
|
||||
int emu_reload_rom(char *rom_fname);
|
||||
int emu_swap_cd(const char *fname);
|
||||
int emu_save_load_game(int load, int sram);
|
||||
void emu_reset_game(void);
|
||||
|
||||
void emu_prep_defconfig(void);
|
||||
void emu_set_defconfig(void);
|
||||
int emu_read_config(const char *rom_fname, int no_defaults);
|
||||
int emu_write_config(int game);
|
||||
|
||||
char *emu_get_save_fname(int load, int is_sram, int slot);
|
||||
int emu_check_save_file(int slot, int *time);
|
||||
|
||||
void emu_text_out8 (int x, int y, const char *text);
|
||||
void emu_text_out16(int x, int y, const char *text);
|
||||
void emu_text_out8_rot (int x, int y, const char *text);
|
||||
void emu_text_out16_rot(int x, int y, const char *text);
|
||||
|
||||
void emu_make_path(char *buff, const char *end, int size);
|
||||
void emu_update_input(void);
|
||||
void emu_get_game_name(char *str150);
|
||||
void emu_set_fastforward(int set_on);
|
||||
void emu_status_msg(const char *format, ...);
|
||||
|
||||
/* used by some (but not all) platforms */
|
||||
void emu_cmn_forced_frame(int no_scale, int do_emu);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
148
common/main.c
148
common/main.c
|
@ -1,148 +0,0 @@
|
|||
// (c) Copyright 2006-2009 notaz, All rights reserved.
|
||||
// Free for non-commercial use.
|
||||
|
||||
// For commercial use, separate licencing terms must be obtained.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include "menu.h"
|
||||
#include "emu.h"
|
||||
#include "config.h"
|
||||
#include "input.h"
|
||||
#include "plat.h"
|
||||
#include <cpu/debug.h>
|
||||
#include <version.h>
|
||||
|
||||
|
||||
extern char *PicoConfigFile;
|
||||
static int load_state_slot = -1;
|
||||
char **g_argv;
|
||||
|
||||
void parse_cmd_line(int argc, char *argv[])
|
||||
{
|
||||
int x, unrecognized = 0;
|
||||
|
||||
for (x = 1; x < argc; x++)
|
||||
{
|
||||
if (argv[x][0] == '-')
|
||||
{
|
||||
if (strcasecmp(argv[x], "-config") == 0) {
|
||||
if (x+1 < argc) { ++x; PicoConfigFile = argv[x]; }
|
||||
}
|
||||
else if (strcasecmp(argv[x], "-loadstate") == 0) {
|
||||
if (x+1 < argc) { ++x; load_state_slot = atoi(argv[x]); }
|
||||
}
|
||||
else if (strcasecmp(argv[x], "-pdb") == 0) {
|
||||
if (x+1 < argc) { ++x; pdb_command(argv[x]); }
|
||||
}
|
||||
else if (strcasecmp(argv[x], "-pdb_connect") == 0) {
|
||||
if (x+2 < argc) { pdb_net_connect(argv[x+1], argv[x+2]); x += 2; }
|
||||
}
|
||||
else {
|
||||
unrecognized = 1;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* External Frontend: ROM Name */
|
||||
FILE *f;
|
||||
strncpy(rom_fname_reload, argv[x], sizeof(rom_fname_reload));
|
||||
rom_fname_reload[sizeof(rom_fname_reload) - 1] = 0;
|
||||
f = fopen(rom_fname_reload, "rb");
|
||||
if (f) fclose(f);
|
||||
else unrecognized = 1;
|
||||
engineState = PGS_ReloadRom;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (unrecognized) {
|
||||
printf("\n\n\nPicoDrive v" VERSION " (c) notaz, 2006-2009\n");
|
||||
printf("usage: %s [options] [romfile]\n", argv[0]);
|
||||
printf("options:\n"
|
||||
" -config <file> use specified config file instead of default 'config.cfg'\n"
|
||||
" -loadstate <num> if ROM is specified, try loading slot <num>\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
g_argv = argv;
|
||||
|
||||
plat_early_init();
|
||||
|
||||
in_init();
|
||||
in_probe();
|
||||
|
||||
plat_init();
|
||||
|
||||
emu_prep_defconfig(); // depends on input
|
||||
emu_read_config(NULL, 0);
|
||||
|
||||
emu_init();
|
||||
menu_init();
|
||||
|
||||
engineState = PGS_Menu;
|
||||
|
||||
if (argc > 1)
|
||||
parse_cmd_line(argc, argv);
|
||||
|
||||
if (engineState == PGS_ReloadRom)
|
||||
{
|
||||
if (emu_reload_rom(rom_fname_reload)) {
|
||||
engineState = PGS_Running;
|
||||
if (load_state_slot >= 0) {
|
||||
state_slot = load_state_slot;
|
||||
emu_save_load_game(1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
switch (engineState)
|
||||
{
|
||||
case PGS_Menu:
|
||||
menu_loop();
|
||||
break;
|
||||
|
||||
case PGS_TrayMenu:
|
||||
menu_loop_tray();
|
||||
break;
|
||||
|
||||
case PGS_ReloadRom:
|
||||
if (emu_reload_rom(rom_fname_reload))
|
||||
engineState = PGS_Running;
|
||||
else {
|
||||
printf("PGS_ReloadRom == 0\n");
|
||||
engineState = PGS_Menu;
|
||||
}
|
||||
break;
|
||||
|
||||
case PGS_RestartRun:
|
||||
engineState = PGS_Running;
|
||||
/* vvv fallthrough */
|
||||
|
||||
case PGS_Running:
|
||||
emu_loop();
|
||||
break;
|
||||
|
||||
case PGS_Quit:
|
||||
goto endloop;
|
||||
|
||||
default:
|
||||
printf("engine got into unknown state (%i), exitting\n", engineState);
|
||||
goto endloop;
|
||||
}
|
||||
}
|
||||
|
||||
endloop:
|
||||
|
||||
emu_finish();
|
||||
plat_finish();
|
||||
|
||||
return 0;
|
||||
}
|
1080
common/menu_pico.c
1080
common/menu_pico.c
File diff suppressed because it is too large
Load diff
|
@ -1,94 +0,0 @@
|
|||
typedef enum
|
||||
{
|
||||
MA_NONE = 1,
|
||||
MA_MAIN_RESUME_GAME,
|
||||
MA_MAIN_SAVE_STATE,
|
||||
MA_MAIN_LOAD_STATE,
|
||||
MA_MAIN_RESET_GAME,
|
||||
MA_MAIN_LOAD_ROM,
|
||||
MA_MAIN_CONTROLS,
|
||||
MA_MAIN_CREDITS,
|
||||
MA_MAIN_PATCHES,
|
||||
MA_MAIN_EXIT,
|
||||
MA_OPT_RENDERER,
|
||||
MA_OPT_SCALING,
|
||||
MA_OPT_VSCALING,
|
||||
MA_OPT_ACC_SPRITES,
|
||||
MA_OPT_SHOW_FPS,
|
||||
MA_OPT_FRAMESKIP,
|
||||
MA_OPT_ENABLE_SOUND,
|
||||
MA_OPT_SOUND_QUALITY,
|
||||
MA_OPT_ARM940_SOUND,
|
||||
MA_OPT_6BUTTON_PAD,
|
||||
MA_OPT_REGION,
|
||||
MA_OPT_SRAM_STATES,
|
||||
MA_OPT_CONFIRM_STATES,
|
||||
MA_OPT_SAVE_SLOT,
|
||||
MA_OPT_CPU_CLOCKS,
|
||||
MA_OPT_SCD_OPTS,
|
||||
MA_OPT_ADV_OPTS,
|
||||
MA_OPT_DISP_OPTS, /* psp */
|
||||
MA_OPT_SAVECFG,
|
||||
MA_OPT_SAVECFG_GAME,
|
||||
MA_OPT_LOADCFG,
|
||||
MA_OPT_INTERLACED, /* giz */
|
||||
MA_OPT_ROTATION, /* uiq */
|
||||
MA_OPT_TEARING_FIX, /* wiz */
|
||||
MA_OPT2_GAMMA,
|
||||
MA_OPT2_A_SN_GAMMA,
|
||||
MA_OPT2_DBLBUFF, /* giz */
|
||||
MA_OPT2_VSYNC,
|
||||
MA_OPT2_ENABLE_Z80,
|
||||
MA_OPT2_ENABLE_YM2612,
|
||||
MA_OPT2_ENABLE_SN76496,
|
||||
MA_OPT2_GZIP_STATES,
|
||||
MA_OPT2_NO_LAST_ROM,
|
||||
MA_OPT2_RAMTIMINGS, /* gp2x */
|
||||
MA_OPT2_SQUIDGEHACK, /* gp2x */
|
||||
MA_OPT2_STATUS_LINE, /* psp */
|
||||
MA_OPT2_NO_FRAME_LIMIT, /* psp */
|
||||
MA_OPT2_SVP_DYNAREC,
|
||||
MA_OPT2_NO_SPRITE_LIM,
|
||||
MA_OPT2_NO_IDLE_LOOPS,
|
||||
MA_OPT2_DONE,
|
||||
MA_OPT3_SCALE, /* psp (all OPT3) */
|
||||
MA_OPT3_HSCALE32,
|
||||
MA_OPT3_HSCALE40,
|
||||
MA_OPT3_PRES_NOSCALE,
|
||||
MA_OPT3_PRES_SCALE43,
|
||||
MA_OPT3_PRES_FULLSCR,
|
||||
MA_OPT3_FILTERING,
|
||||
MA_OPT3_VSYNC,
|
||||
MA_OPT3_GAMMAA,
|
||||
MA_OPT3_BLACKLVL,
|
||||
MA_OPT3_LAYER_X,
|
||||
MA_OPT3_LAYER_Y,
|
||||
MA_OPT3_LAYER_W,
|
||||
MA_OPT3_LAYER_H,
|
||||
MA_OPT3_DONE,
|
||||
MA_CDOPT_TESTBIOS_USA,
|
||||
MA_CDOPT_TESTBIOS_EUR,
|
||||
MA_CDOPT_TESTBIOS_JAP,
|
||||
MA_CDOPT_LEDS,
|
||||
MA_CDOPT_CDDA,
|
||||
MA_CDOPT_PCM,
|
||||
MA_CDOPT_READAHEAD,
|
||||
MA_CDOPT_SAVERAM,
|
||||
MA_CDOPT_SCALEROT_CHIP,
|
||||
MA_CDOPT_BETTER_SYNC,
|
||||
MA_CDOPT_DONE,
|
||||
MA_32XOPT_ENABLE_32X,
|
||||
MA_32XOPT_RENDERER,
|
||||
MA_32XOPT_PWM,
|
||||
MA_32XOPT_MSH2_CYCLES,
|
||||
MA_32XOPT_SSH2_CYCLES,
|
||||
MA_CTRL_PLAYER1,
|
||||
MA_CTRL_PLAYER2,
|
||||
MA_CTRL_EMU,
|
||||
MA_CTRL_TURBO_RATE,
|
||||
MA_CTRL_DEADZONE,
|
||||
MA_CTRL_DEV_FIRST,
|
||||
MA_CTRL_DEV_NEXT,
|
||||
MA_CTRL_DONE,
|
||||
} menu_id;
|
||||
|
29
common/mp3.c
29
common/mp3.c
|
@ -1,29 +0,0 @@
|
|||
#include "mp3.h"
|
||||
|
||||
int mp3_find_sync_word(const unsigned char *buf, int size)
|
||||
{
|
||||
const unsigned char *p, *pe;
|
||||
|
||||
/* find byte-aligned syncword - need 12 (MPEG 1,2) or 11 (MPEG 2.5) matching bits */
|
||||
for (p = buf, pe = buf + size - 3; p <= pe; p++)
|
||||
{
|
||||
int pn;
|
||||
if (p[0] != 0xff)
|
||||
continue;
|
||||
pn = p[1];
|
||||
if ((pn & 0xf8) != 0xf8 || // currently must be MPEG1
|
||||
(pn & 6) == 0) { // invalid layer
|
||||
p++; continue;
|
||||
}
|
||||
pn = p[2];
|
||||
if ((pn & 0xf0) < 0x20 || (pn & 0xf0) == 0xf0 || // bitrates
|
||||
(pn & 0x0c) != 0) { // not 44kHz
|
||||
continue;
|
||||
}
|
||||
|
||||
return p - buf;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
|
||||
int mp3_find_sync_word(const unsigned char *buf, int size);
|
||||
|
||||
#ifdef __GP2X__
|
||||
void mp3_update_local(int *buffer, int length, int stereo);
|
||||
void mp3_start_play_local(void *f, int pos);
|
||||
#endif
|
||||
|
|
@ -1,220 +0,0 @@
|
|||
// Some mp3 related code for Sega/Mega CD.
|
||||
// Uses the Helix Fixed-point MP3 decoder
|
||||
|
||||
// (c) Copyright 2007, Grazvydas "notaz" Ignotas
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <pico/pico_int.h>
|
||||
#include <pico/sound/mix.h>
|
||||
#include "helix/pub/mp3dec.h"
|
||||
#include "mp3.h"
|
||||
#include "lprintf.h"
|
||||
|
||||
static HMP3Decoder mp3dec = 0;
|
||||
static FILE *mp3_current_file = NULL;
|
||||
static int mp3_file_len = 0, mp3_file_pos = 0;
|
||||
static int mp3_buffer_offs = 0;
|
||||
static unsigned char mp3_input_buffer[2*1024];
|
||||
|
||||
#ifdef __GP2X__
|
||||
#define mp3_update mp3_update_local
|
||||
#define mp3_start_play mp3_start_play_local
|
||||
#endif
|
||||
|
||||
static int try_get_header(unsigned char *buff, MP3FrameInfo *fi)
|
||||
{
|
||||
int ret, offs1, offs = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
offs1 = mp3_find_sync_word(buff + offs, 2048 - offs);
|
||||
if (offs1 < 0) return -2;
|
||||
offs += offs1;
|
||||
if (2048 - offs < 4) return -3;
|
||||
|
||||
// printf("trying header %08x\n", *(int *)(buff + offs));
|
||||
|
||||
ret = MP3GetNextFrameInfo(mp3dec, fi, buff + offs);
|
||||
if (ret == 0 && fi->bitrate != 0) break;
|
||||
offs++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mp3_get_bitrate(void *f_, int len)
|
||||
{
|
||||
unsigned char buff[2048];
|
||||
MP3FrameInfo fi;
|
||||
FILE *f = f_;
|
||||
int ret;
|
||||
|
||||
memset(buff, 0, sizeof(buff));
|
||||
|
||||
if (mp3dec)
|
||||
MP3FreeDecoder(mp3dec);
|
||||
mp3dec = MP3InitDecoder();
|
||||
|
||||
fseek(f, 0, SEEK_SET);
|
||||
ret = fread(buff, 1, sizeof(buff), f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
if (ret <= 0)
|
||||
return -1;
|
||||
|
||||
ret = try_get_header(buff, &fi);
|
||||
if (ret != 0 || fi.bitrate == 0) {
|
||||
// try to read somewhere around the middle
|
||||
fseek(f, len>>1, SEEK_SET);
|
||||
fread(buff, 1, 2048, f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
ret = try_get_header(buff, &fi);
|
||||
}
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
// printf("bitrate: %i\n", fi.bitrate / 1000);
|
||||
|
||||
return fi.bitrate / 1000;
|
||||
}
|
||||
|
||||
static int mp3_decode(void)
|
||||
{
|
||||
unsigned char *readPtr;
|
||||
int bytesLeft;
|
||||
int offset; // mp3 frame offset from readPtr
|
||||
int had_err;
|
||||
int err = 0;
|
||||
|
||||
do
|
||||
{
|
||||
if (mp3_file_pos >= mp3_file_len)
|
||||
return 1; /* EOF, nothing to do */
|
||||
|
||||
fseek(mp3_current_file, mp3_file_pos, SEEK_SET);
|
||||
bytesLeft = fread(mp3_input_buffer, 1, sizeof(mp3_input_buffer), mp3_current_file);
|
||||
|
||||
offset = mp3_find_sync_word(mp3_input_buffer, bytesLeft);
|
||||
if (offset < 0) {
|
||||
lprintf("find_sync_word (%i/%i) err %i\n", mp3_file_pos, mp3_file_len, offset);
|
||||
mp3_file_pos = mp3_file_len;
|
||||
return 1; // EOF
|
||||
}
|
||||
readPtr = mp3_input_buffer + offset;
|
||||
bytesLeft -= offset;
|
||||
|
||||
had_err = err;
|
||||
err = MP3Decode(mp3dec, &readPtr, &bytesLeft, cdda_out_buffer, 0);
|
||||
if (err) {
|
||||
if (err == ERR_MP3_MAINDATA_UNDERFLOW && !had_err) {
|
||||
// just need another frame
|
||||
mp3_file_pos += readPtr - mp3_input_buffer;
|
||||
continue;
|
||||
}
|
||||
if (err == ERR_MP3_INDATA_UNDERFLOW && !had_err) {
|
||||
if (offset == 0)
|
||||
// something's really wrong here, frame had to fit
|
||||
mp3_file_pos = mp3_file_len;
|
||||
else
|
||||
mp3_file_pos += offset;
|
||||
continue;
|
||||
}
|
||||
if (-12 <= err && err <= -6) {
|
||||
// ERR_MP3_INVALID_FRAMEHEADER, ERR_MP3_INVALID_*
|
||||
// just try to skip the offending frame..
|
||||
mp3_file_pos += offset + 1;
|
||||
continue;
|
||||
}
|
||||
lprintf("MP3Decode err (%i/%i) %i\n", mp3_file_pos, mp3_file_len, err);
|
||||
mp3_file_pos = mp3_file_len;
|
||||
return 1;
|
||||
}
|
||||
mp3_file_pos += readPtr - mp3_input_buffer;
|
||||
}
|
||||
while (0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mp3_start_play(void *f_, int pos)
|
||||
{
|
||||
FILE *f = f_;
|
||||
|
||||
mp3_file_len = mp3_file_pos = 0;
|
||||
mp3_current_file = NULL;
|
||||
mp3_buffer_offs = 0;
|
||||
|
||||
if (!(PicoOpt & POPT_EN_MCD_CDDA) || f == NULL) // cdda disabled or no file?
|
||||
return;
|
||||
|
||||
// must re-init decoder for new track
|
||||
if (mp3dec)
|
||||
MP3FreeDecoder(mp3dec);
|
||||
mp3dec = MP3InitDecoder();
|
||||
|
||||
mp3_current_file = f;
|
||||
fseek(f, 0, SEEK_END);
|
||||
mp3_file_len = ftell(f);
|
||||
|
||||
// search for first sync word, skipping stuff like ID3 tags
|
||||
while (mp3_file_pos < 128*1024) {
|
||||
int offs, bytes;
|
||||
|
||||
fseek(f, mp3_file_pos, SEEK_SET);
|
||||
bytes = fread(mp3_input_buffer, 1, sizeof(mp3_input_buffer), f);
|
||||
if (bytes < 4)
|
||||
break;
|
||||
offs = mp3_find_sync_word(mp3_input_buffer, bytes);
|
||||
if (offs >= 0) {
|
||||
mp3_file_pos += offs;
|
||||
break;
|
||||
}
|
||||
mp3_file_pos += bytes - 2;
|
||||
}
|
||||
|
||||
// seek..
|
||||
if (pos) {
|
||||
unsigned long long pos64 = mp3_file_len - mp3_file_pos;
|
||||
pos64 *= pos;
|
||||
mp3_file_pos += pos64 >> 10;
|
||||
}
|
||||
|
||||
mp3_decode();
|
||||
}
|
||||
|
||||
void mp3_update(int *buffer, int length, int stereo)
|
||||
{
|
||||
int length_mp3, shr = 0;
|
||||
void (*mix_samples)(int *dest_buf, short *mp3_buf, int count) = mix_16h_to_32;
|
||||
|
||||
if (mp3_current_file == NULL || mp3_file_pos >= mp3_file_len)
|
||||
return; /* no file / EOF */
|
||||
|
||||
length_mp3 = length;
|
||||
if (PsndRate <= 11025 + 100) {
|
||||
mix_samples = mix_16h_to_32_s2;
|
||||
length_mp3 <<= 2; shr = 2;
|
||||
}
|
||||
else if (PsndRate <= 22050 + 100) {
|
||||
mix_samples = mix_16h_to_32_s1;
|
||||
length_mp3 <<= 1; shr = 1;
|
||||
}
|
||||
|
||||
if (1152 - mp3_buffer_offs >= length_mp3) {
|
||||
mix_samples(buffer, cdda_out_buffer + mp3_buffer_offs*2, length<<1);
|
||||
|
||||
mp3_buffer_offs += length_mp3;
|
||||
} else {
|
||||
int ret, left = 1152 - mp3_buffer_offs;
|
||||
|
||||
mix_samples(buffer, cdda_out_buffer + mp3_buffer_offs*2, (left>>shr)<<1);
|
||||
ret = mp3_decode();
|
||||
if (ret == 0) {
|
||||
mp3_buffer_offs = length_mp3 - left;
|
||||
mix_samples(buffer + ((left>>shr)<<1), cdda_out_buffer, (mp3_buffer_offs>>shr)<<1);
|
||||
} else
|
||||
mp3_buffer_offs = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
platform/common/menu.o : revision.h
|
||||
|
||||
revision.h: FORCE
|
||||
ifndef NOREVISION
|
||||
@echo "#define REVISION \"`svn info -r HEAD | grep Revision | cut -c 11-`\"" > /tmp/r.tmp
|
||||
else
|
||||
@echo "#define REVISION \"0\"" > /tmp/r.tmp
|
||||
endif
|
||||
@diff -q $@ /tmp/r.tmp > /dev/null 2>&1 || mv -f /tmp/r.tmp $@
|
||||
|
||||
FORCE:
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue