mirror of
https://github.com/coderkei/akmenu-next.git
synced 2025-06-18 17:05:48 -04:00
Make it build on latest devkitARM
- UTF8-ify where possible - Remove custom linkerscript - Update Makefiles - devkitPro/nds-examples@6afa09b205 - Comment out akloader binaries - This will be reworked soon™️ - Eradicate sdidentify - AKRPG specific - Eradicate libelm - Eradicate save64m - Eradicate file operations - Eradicate libio* - Eradicate crtsmall - Fix paths for new root drive naming in latest libfat - dsrom: fix type cast issue in homebrew check - MAX_FILENAME_LENGTH -> PATH_MAX - adapt directory listing operations to new dkP way - timer: unstaticify _factor - Remove all flashcart-specific bits - fix type of cPopMenu::itemBelowPoint - gbaloader: use updated vramSetPrimaryBanks function - Move arm9-specific headers to arm9
This commit is contained in:
parent
6fe395b92f
commit
a7dd6151a4
114
Makefile
114
Makefile
@ -2,113 +2,57 @@
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(DEVKITARM)),)
|
||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM)
|
||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
||||
endif
|
||||
|
||||
export TARGET := $(shell basename $(CURDIR))
|
||||
export TOPDIR := $(CURDIR)
|
||||
|
||||
# GMAE_ICON is the image used to create the game icon, leave blank to use default rule
|
||||
GAME_ICON :=
|
||||
|
||||
# specify a directory which contains the nitro filesystem
|
||||
# this is relative to the Makefile
|
||||
NITRO_FILES :=
|
||||
|
||||
# These set the information text in the nds file
|
||||
GAME_TITLE := acekard
|
||||
GAME_SUBTITLE1 := Real Play Gear
|
||||
GAME_SUBTITLE2 := www.acekard.com
|
||||
|
||||
include $(DEVKITARM)/ds_rules
|
||||
|
||||
export TARGET := $(shell basename $(CURDIR))
|
||||
export TOPDIR := $(CURDIR)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# path to tools - this can be deleted if you set the path in windows
|
||||
#---------------------------------------------------------------------------------
|
||||
export PATH := $(DEVKITARM)/bin:$(PATH)
|
||||
|
||||
.PHONY: all rpg r4 ak2i r4idsn clean
|
||||
.PHONY: arm7/rpg/$(TARGET).arm7 arm9/rpg/$(TARGET).arm9
|
||||
.PHONY: arm7/r4/$(TARGET).arm7 arm9/r4/$(TARGET).arm9
|
||||
.PHONY: arm7/ak2i/$(TARGET).arm7 arm9/ak2i/$(TARGET).arm9
|
||||
.PHONY: arm7/r4idsn/$(TARGET).arm7 arm9/r4idsn/$(TARGET).arm9
|
||||
.PHONY: checkarm7 checkarm9 clean
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
all: rpg r4
|
||||
all: checkarm7 checkarm9 $(TARGET).nds
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# rpg target
|
||||
#---------------------------------------------------------------------------------
|
||||
rpg: $(TARGET).nds
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# r4 target
|
||||
#---------------------------------------------------------------------------------
|
||||
r4: _DS_MENU.DAT
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# ak2i target
|
||||
#---------------------------------------------------------------------------------
|
||||
ak2i: ak2i/$(TARGET).nds
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# r4idsn target
|
||||
#---------------------------------------------------------------------------------
|
||||
r4idsn: _DSMENU.DAT
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
$(TARGET).nds : arm7/rpg/$(TARGET).arm7 arm9/rpg/$(TARGET).arm9
|
||||
ndstool -c $(TARGET).nds -7 arm7/rpg/$(TARGET).arm7 -9 arm9/rpg/$(TARGET).arm9 -e9 0x02000450 -e7 0x02380000 -b $(TARGET).bmp "acekard;Real Play Gear;www.acekard.com"
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
arm7/rpg/$(TARGET).arm7:
|
||||
checkarm7:
|
||||
$(MAKE) -C arm7
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
arm9/rpg/$(TARGET).arm9:
|
||||
checkarm9:
|
||||
$(MAKE) -C arm9
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
_DS_MENU.DAT : $(TARGET)_r4.nds
|
||||
r4denc $(TARGET)_r4.nds _DS_MENU.DAT
|
||||
$(TARGET).nds : $(NITRO_FILES) arm7/$(TARGET).elf arm9/$(TARGET).elf
|
||||
ndstool -c $(TARGET).nds -7 arm7/$(TARGET).elf -9 arm9/$(TARGET).elf \
|
||||
-b $(GAME_ICON) "$(GAME_TITLE);$(GAME_SUBTITLE1);$(GAME_SUBTITLE2)" \
|
||||
$(_ADDFILES)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
$(TARGET)_r4.nds : arm7/r4/$(TARGET).arm7 arm9/r4/$(TARGET).arm9
|
||||
ndstool -c $(TARGET)_r4.nds -7 arm7/r4/$(TARGET).arm7 -9 arm9/r4/$(TARGET).arm9 -e9 0x02000450 -e7 0x02380000 -b $(TARGET).bmp "wood r4"
|
||||
arm7/$(TARGET).elf:
|
||||
$(MAKE) -C arm7
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
arm7/r4/$(TARGET).arm7:
|
||||
$(MAKE) -C arm7 STORAGE=r4
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
arm9/r4/$(TARGET).arm9:
|
||||
$(MAKE) -C arm9 STORAGE=r4
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
ak2i/$(TARGET).nds : arm7/ak2i/$(TARGET).arm7 arm9/ak2i/$(TARGET).arm9
|
||||
mkdir -p ak2i
|
||||
ndstool -c ak2i/$(TARGET).nds -7 arm7/ak2i/$(TARGET).arm7 -9 arm9/ak2i/$(TARGET).arm9 -e9 0x02000450 -e7 0x02380000 -b $(TARGET).bmp "wood ak2i"
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
_DSMENU.DAT : arm7/r4idsn/$(TARGET).arm7 arm9/r4idsn/$(TARGET).arm9
|
||||
ndstool -c _DSMENU.DAT -7 arm7/r4idsn/$(TARGET).arm7 -9 arm9/r4idsn/$(TARGET).arm9 -e9 0x02000000 -e7 0x02380000 -b $(TARGET).bmp "wood r4idsn"
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
arm7/ak2i/$(TARGET).arm7:
|
||||
$(MAKE) -C arm7 STORAGE=ak2i
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
arm9/ak2i/$(TARGET).arm9:
|
||||
$(MAKE) -C arm9 STORAGE=ak2i
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
arm7/r4idsn/$(TARGET).arm7:
|
||||
$(MAKE) -C arm7 STORAGE=r4idsn
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
arm9/r4idsn/$(TARGET).arm9:
|
||||
$(MAKE) -C arm9 STORAGE=r4idsn
|
||||
arm9/$(TARGET).elf:
|
||||
$(MAKE) -C arm9
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
$(MAKE) -C arm9 clean
|
||||
$(MAKE) -C arm7 clean
|
||||
$(MAKE) -C arm9 STORAGE=r4 clean
|
||||
$(MAKE) -C arm7 STORAGE=r4 clean
|
||||
$(MAKE) -C arm9 STORAGE=ak2i clean
|
||||
$(MAKE) -C arm7 STORAGE=ak2i clean
|
||||
$(MAKE) -C arm9 STORAGE=r4idsn clean
|
||||
$(MAKE) -C arm7 STORAGE=r4idsn clean
|
||||
rm -f $(TARGET).nds _DS_MENU.DAT $(TARGET)_r4.nds _DSMENU.DAT
|
||||
rm -rf ak2i
|
||||
rm -f $(TARGET).nds
|
||||
|
@ -14,92 +14,86 @@ include $(DEVKITARM)/ds_rules
|
||||
# DATA is a list of directories containing binary files
|
||||
# all directories are relative to this makefile
|
||||
#---------------------------------------------------------------------------------
|
||||
STORAGE ?= rpg
|
||||
BUILD := $(STORAGE)/build
|
||||
SOURCES := source
|
||||
INCLUDES := include $(BUILD)
|
||||
DATA :=
|
||||
CRT := crt/ds_arm7_crt1.o
|
||||
BUILD := build
|
||||
SOURCES := source
|
||||
INCLUDES := include build ../share $(SOURCES)
|
||||
DATA :=
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -mthumb-interwork
|
||||
ARCH := -mthumb-interwork
|
||||
|
||||
CFLAGS := -g -Wall -Os\
|
||||
-mcpu=arm7tdmi -mtune=arm7tdmi -fomit-frame-pointer\
|
||||
-ffast-math \
|
||||
$(ARCH)
|
||||
CFLAGS := -g -Wall -O3\
|
||||
$(ARCH) $(INCLUDE) -DARM7
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=ds_arm7.specs -g $(ARCH) -Wl,--nmagic -Wl,-Map,$(notdir $*).map
|
||||
|
||||
CFLAGS += $(INCLUDE) -DARM7 -fno-dwarf2-cfi-asm
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -fno-rtti
|
||||
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=../../specs/ds_arm7.specs -g $(ARCH) -mno-fpu -Wl,-Map,$(notdir $*).map
|
||||
|
||||
LIBS := -lunds7
|
||||
LIBS := -ldswifi7 -lmm7 -lnds7
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(LIBUNDS)
|
||||
|
||||
LIBDIRS := $(LIBNDS)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
# rules for different file extensions
|
||||
#---------------------------------------------------------------------------------
|
||||
ifneq ($(notdir $(BUILD)),$(notdir $(CURDIR)))
|
||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export ARM7BIN := $(CURDIR)/$(STORAGE)/$(TARGET).arm7
|
||||
export ARM7ELF := $(CURDIR)/$(STORAGE)/$(TARGET).arm7.elf
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
export ARM7ELF := $(CURDIR)/$(TARGET).elf
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir))
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir))\
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
export OFILES := $(addsuffix .o,$(BINFILES)) \
|
||||
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD)
|
||||
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(CPPFILES)),)
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CC)
|
||||
export LD := $(CC)
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CXX)
|
||||
export LD := $(CXX)
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
||||
|
||||
export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
|
||||
export OFILES := $(OFILES_BIN) $(OFILES_SOURCES)
|
||||
|
||||
export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-iquote $(CURDIR)/$(dir))\
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include)\
|
||||
-I$(CURDIR)/$(BUILD)
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||
|
||||
.PHONY: $(BUILD) clean
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
$(BUILD):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@[ -d $@/crt ] || mkdir -p $@/crt
|
||||
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -fr $(STORAGE) *.elf
|
||||
@rm -fr $(BUILD) $(TARGET).elf
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
@ -110,28 +104,19 @@ DEPENDS := $(OFILES:.o=.d)
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
$(ARM7BIN) : $(ARM7ELF)
|
||||
@$(OBJCOPY) -O binary $< $@
|
||||
@echo built ... $(notdir $@)
|
||||
|
||||
|
||||
$(ARM7ELF) : $(OFILES) $(CRT)
|
||||
$(ARM7ELF) : $(OFILES)
|
||||
@echo linking $(notdir $@)
|
||||
@$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# you need a rule like this for each extension you use as binary data
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o : %.bin
|
||||
%.bin.o %_bin.h : %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
$(CRT) : $(CRT:.o=.s)
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
||||
#---------------------------------------------------------------------------------------
|
||||
|
@ -1,104 +0,0 @@
|
||||
@---------------------------------------------------------------------------------
|
||||
.arch armv4t
|
||||
.cpu arm7tdmi
|
||||
.section ".init"
|
||||
.global _start
|
||||
@---------------------------------------------------------------------------------
|
||||
.align 4
|
||||
.arm
|
||||
@---------------------------------------------------------------------------------
|
||||
_start:
|
||||
@---------------------------------------------------------------------------------
|
||||
mov r0, #0x04000000 @ IME = 0;
|
||||
mov r1, #0
|
||||
str r1, [r0, #0x208]
|
||||
|
||||
mov r0, #0x12 @ Switch to IRQ Mode
|
||||
msr cpsr, r0
|
||||
ldr sp, =__sp_irq @ Set IRQ stack
|
||||
|
||||
mov r0, #0x13 @ Switch to SVC Mode
|
||||
msr cpsr, r0
|
||||
ldr sp, =__sp_svc @ Set SVC stack
|
||||
|
||||
mov r0, #0x1F @ Switch to System Mode
|
||||
msr cpsr, r0
|
||||
ldr sp, =__sp_usr @ Set user stack
|
||||
|
||||
ldr r1, =__iwram_lma
|
||||
ldr r2, =__iwram_start
|
||||
ldr r4, =__iwram_end
|
||||
bl CopyMemCheck
|
||||
|
||||
ldr r0, =__bss_start @ Clear BSS section to 0x00
|
||||
ldr r1, =__bss_end
|
||||
sub r1, r1, r0
|
||||
bl ClearMem
|
||||
|
||||
ldr r3, =__libc_init_array @ global constructors
|
||||
bl _blx_r3_stub
|
||||
|
||||
mov r0, #0 @ int argc
|
||||
mov r1, #0 @ char *argv[]
|
||||
ldr r3, =main
|
||||
ldr lr,=__libnds_exit
|
||||
bx r3
|
||||
|
||||
|
||||
@---------------------------------------------------------------------------------
|
||||
_blx_r3_stub:
|
||||
@---------------------------------------------------------------------------------
|
||||
bx r3
|
||||
|
||||
@---------------------------------------------------------------------------------
|
||||
@ Clear memory to 0x00 if length != 0
|
||||
@ r0 = Start Address
|
||||
@ r1 = Length
|
||||
@---------------------------------------------------------------------------------
|
||||
ClearMem:
|
||||
@---------------------------------------------------------------------------------
|
||||
mov r2, #3 @ Round down to nearest word boundary
|
||||
add r1, r1, r2 @ Shouldn't be needed
|
||||
bics r1, r1, r2 @ Clear 2 LSB (and set Z)
|
||||
bxeq lr @ Quit if copy size is 0
|
||||
|
||||
mov r2, #0
|
||||
ClrLoop:
|
||||
stmia r0!, {r2}
|
||||
subs r1, r1, #4
|
||||
bne ClrLoop
|
||||
bx lr
|
||||
|
||||
@---------------------------------------------------------------------------------
|
||||
@ Copy memory if length != 0
|
||||
@ r1 = Source Address
|
||||
@ r2 = Dest Address
|
||||
@ r4 = Dest Address + Length
|
||||
@---------------------------------------------------------------------------------
|
||||
CopyMemCheck:
|
||||
@---------------------------------------------------------------------------------
|
||||
sub r3, r4, r2 @ Is there any data to copy?
|
||||
@---------------------------------------------------------------------------------
|
||||
@ Copy memory
|
||||
@ r1 = Source Address
|
||||
@ r2 = Dest Address
|
||||
@ r3 = Length
|
||||
@---------------------------------------------------------------------------------
|
||||
CopyMem:
|
||||
@---------------------------------------------------------------------------------
|
||||
mov r0, #3 @ These commands are used in cases where
|
||||
add r3, r3, r0 @ the length is not a multiple of 4,
|
||||
bics r3, r3, r0 @ even though it should be.
|
||||
bxeq lr @ Length is zero, so exit
|
||||
CIDLoop:
|
||||
ldmia r1!, {r0}
|
||||
stmia r2!, {r0}
|
||||
subs r3, r3, #4
|
||||
bne CIDLoop
|
||||
bx lr
|
||||
|
||||
@---------------------------------------------------------------------------------
|
||||
.align
|
||||
.pool
|
||||
.end
|
||||
@---------------------------------------------------------------------------------
|
@ -1,198 +0,0 @@
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_start)
|
||||
|
||||
MEMORY {
|
||||
|
||||
rom : ORIGIN = 0x08000000, LENGTH = 32M
|
||||
iwram : ORIGIN = 0x03800000, LENGTH = 64K
|
||||
awram : ORIGIN = 0x02380000, LENGTH = 128K
|
||||
}
|
||||
|
||||
__iwram_start = ORIGIN(iwram);
|
||||
__iwram_top = ORIGIN(iwram)+ LENGTH(iwram);
|
||||
__awram_start = ORIGIN(awram);
|
||||
__awram_top = ORIGIN(awram)+ LENGTH(awram);
|
||||
__sp_irq = __iwram_top - 0x100;
|
||||
__sp_svc = __sp_irq - 0x100;
|
||||
__sp_usr = __sp_svc - 0x100;
|
||||
|
||||
__irq_flags = 0x04000000 - 8;
|
||||
__irq_flagsaux = 0x04000000 - 0x40;
|
||||
__irq_vector = 0x04000000 - 4;
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.init :
|
||||
{
|
||||
__text_start = . ;
|
||||
KEEP (*(.init))
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >awram = 0xff
|
||||
|
||||
__iwram_lma = . ;
|
||||
|
||||
.plt : { *(.plt) } >iwram AT>awram = 0xff
|
||||
|
||||
.text : /* ALIGN (4): */
|
||||
{
|
||||
*(.text .stub .text.* .gnu.linkonce.t.*)
|
||||
KEEP (*(.text.*personality*))
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
*(.glue_7t) *(.glue_7) *(.vfp11_veneer)
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >iwram = 0xff
|
||||
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(.fini))
|
||||
} >iwram =0xff
|
||||
|
||||
__text_end = . ;
|
||||
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata)
|
||||
*all.rodata*(*)
|
||||
*(.roda)
|
||||
*(.rodata.*)
|
||||
*(.gnu.linkonce.r*)
|
||||
SORT(CONSTRUCTORS)
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >iwram = 0xff
|
||||
|
||||
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >iwram
|
||||
__exidx_start = .;
|
||||
.ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >iwram
|
||||
__exidx_end = .;
|
||||
|
||||
/* Ensure the __preinit_array_start label is properly aligned. We
|
||||
could instead move the label definition inside the section, but
|
||||
the linker would then create the section even if it turns out to
|
||||
be empty, which isn't pretty. */
|
||||
. = ALIGN(32 / 8);
|
||||
PROVIDE (__preinit_array_start = .);
|
||||
.preinit_array : { KEEP (*(.preinit_array)) } >iwram = 0xff
|
||||
PROVIDE (__preinit_array_end = .);
|
||||
PROVIDE (__init_array_start = .);
|
||||
.init_array : { KEEP (*(.init_array)) } >iwram = 0xff
|
||||
PROVIDE (__init_array_end = .);
|
||||
PROVIDE (__fini_array_start = .);
|
||||
.fini_array : { KEEP (*(.fini_array)) } >iwram = 0xff
|
||||
PROVIDE (__fini_array_end = .);
|
||||
|
||||
.ctors :
|
||||
{
|
||||
/* gcc uses crtbegin.o to find the start of the constructors, so
|
||||
we make sure it is first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not actually link against
|
||||
crtbegin.o; the linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it doesn't matter which
|
||||
directory crtbegin.o is in. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >iwram = 0xff
|
||||
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >iwram = 0xff
|
||||
|
||||
.eh_frame :
|
||||
{
|
||||
KEEP (*(.eh_frame))
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >iwram = 0xff
|
||||
|
||||
.gcc_except_table :
|
||||
{
|
||||
*(.gcc_except_table)
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >iwram = 0xff
|
||||
.jcr : { KEEP (*(.jcr)) } >iwram = 0
|
||||
.got : { *(.got.plt) *(.got) } >iwram = 0
|
||||
|
||||
|
||||
.iwram ALIGN(4) :
|
||||
{
|
||||
*(.iwram)
|
||||
*iwram.*(.text)
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >iwram = 0xff
|
||||
|
||||
|
||||
.data ALIGN(4) : {
|
||||
__data_start = ABSOLUTE(.);
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d*)
|
||||
CONSTRUCTORS
|
||||
. = ALIGN(4);
|
||||
__data_end = ABSOLUTE(.) ;
|
||||
__iwram_end = ABSOLUTE(.);
|
||||
} >iwram = 0xff
|
||||
|
||||
|
||||
|
||||
.bss ALIGN(4) :
|
||||
{
|
||||
__bss_start = ABSOLUTE(.);
|
||||
__bss_start__ = ABSOLUTE(.);
|
||||
*(.dynbss)
|
||||
*(.gnu.linkonce.b*)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >iwram
|
||||
|
||||
__bss_end = . ;
|
||||
__bss_end__ = . ;
|
||||
|
||||
_end = . ;
|
||||
__end__ = . ;
|
||||
PROVIDE (end = _end);
|
||||
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
.stack 0x80000 : { _stack = .; *(.stack) }
|
||||
/* These must appear regardless of . */
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
%rename link old_link
|
||||
|
||||
*link:
|
||||
%(old_link) -T ../../specs/ds_arm7.ld%s
|
||||
|
||||
*startfile:
|
||||
crt/ds_arm7_crt1%O%s crti%O%s crtbegin%O%s
|
||||
|
121
arm9/Makefile
121
arm9/Makefile
@ -11,140 +11,127 @@ include $(DEVKITARM)/ds_rules
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# INCLUDES is a list of directories containing extra header files
|
||||
# DATA is a list of directories containing binary files
|
||||
# DATA is a list of directories containing binary files embedded using bin2o
|
||||
# GRAPHICS is a list of directories containing image files to be converted with grit
|
||||
# all directories are relative to this makefile
|
||||
#---------------------------------------------------------------------------------
|
||||
STORAGE ?= rpg
|
||||
BUILD := $(STORAGE)/build
|
||||
SOURCES := source source/ui ../share source/font
|
||||
INCLUDES := source source/ui ../share source/font $(BUILD)
|
||||
DATA := data data/$(STORAGE)
|
||||
BUILD := build
|
||||
SOURCES := source source/ui source/font
|
||||
INCLUDES := include ../share $(SOURCES)
|
||||
DATA := data
|
||||
GRAPHICS :=
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -mthumb -mthumb-interwork
|
||||
#
|
||||
ARCH := -marm -mthumb-interwork -march=armv5te -mtune=arm946e-s
|
||||
|
||||
# note: arm9tdmi isn't the correct CPU arch, but anything newer and LD
|
||||
# *insists* it has a FPU or VFP, and it won't take no for an answer!
|
||||
CFLAGS := -g -Wall -Os\
|
||||
-march=armv5te -mtune=arm946e-s -fomit-frame-pointer\
|
||||
-ffast-math \
|
||||
$(ARCH)
|
||||
|
||||
CFLAGS += $(INCLUDE) -DARM9 -fno-dwarf2-cfi-asm -D_STORAGE_$(STORAGE)
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
|
||||
#--ansi
|
||||
|
||||
ASFLAGS := -g $(ARCH) -march=armv5te -mtune=arm946e-s -D_STORAGE_$(STORAGE)
|
||||
LDFLAGS = -specs=../../specs/ds_arm9.specs -g $(ARCH) -mno-fpu -Wl,-Map,$(notdir $*.map)
|
||||
CFLAGS := -g -Wall -O3\
|
||||
$(ARCH) $(INCLUDE) -DARM9
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# any extra libraries we wish to link with the project
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBS := -lelm -lio$(STORAGE) -lunds9
|
||||
LIBS := -lfat -lnds9
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(LIBELM) $(LIBUNDS)
|
||||
ifeq ($(STORAGE),rpg)
|
||||
LIBDIRS += $(LIBIORPG)
|
||||
endif
|
||||
ifeq ($(STORAGE),r4)
|
||||
LIBDIRS += $(LIBIOR4)
|
||||
endif
|
||||
ifeq ($(STORAGE),ak2i)
|
||||
LIBDIRS += $(LIBIOAK2I)
|
||||
endif
|
||||
ifeq ($(STORAGE),r4idsn)
|
||||
LIBDIRS += $(LIBIOR4IDSN)
|
||||
endif
|
||||
LIBDIRS := $(LIBNDS) $(PORTLIBS)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
# rules for different file extensions
|
||||
#---------------------------------------------------------------------------------
|
||||
ifneq ($(notdir $(BUILD)),$(notdir $(CURDIR)))
|
||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export ARM9BIN := $(CURDIR)/$(STORAGE)/$(TARGET).arm9
|
||||
export ARM9ELF := $(CURDIR)/$(STORAGE)/$(TARGET).arm9.elf
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
export ARM9ELF := $(CURDIR)/$(TARGET).elf
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir))\
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))\
|
||||
$(foreach dir,$(GRAPHICS),$(CURDIR)/$(dir))
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
PNGFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(CPPFILES)),)
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CC)
|
||||
export LD := $(CC)
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CXX)
|
||||
export LD := $(CXX)
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OFILES := $(addsuffix .o,$(BINFILES)) \
|
||||
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD)
|
||||
export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||
export OFILES := $(PNGFILES:.png=.o) $(OFILES_BIN) $(OFILES_SOURCES)
|
||||
|
||||
export HFILES := $(PNGFILES:.png=.h) $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-iquote $(CURDIR)/$(dir))\
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include)\
|
||||
-I$(CURDIR)/$(BUILD)
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||
|
||||
.PHONY: $(BUILD) clean
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
$(BUILD):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -fr $(STORAGE) *.elf *.nds* *.bin
|
||||
@rm -fr $(BUILD) $(TARGET).elf
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
$(ARM9BIN) : $(ARM9ELF)
|
||||
@$(OBJCOPY) -O binary $< $@
|
||||
@echo built ... $(notdir $@)
|
||||
|
||||
$(ARM9ELF) : $(OFILES)
|
||||
$(ARM9ELF) : $(OFILES)
|
||||
@echo linking $(notdir $@)
|
||||
@$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# you need a rule like this for each extension you use as binary data
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o : %.bin
|
||||
%.bin.o %_bin.h : %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# This rule creates assembly source files using grit
|
||||
# grit takes an image file and a .grit describing how the file is to be processed
|
||||
# add additional rules like this for each image extension
|
||||
# you use in the graphics folders
|
||||
#---------------------------------------------------------------------------------
|
||||
%.s %.h: %.png %.grit
|
||||
#---------------------------------------------------------------------------------
|
||||
grit $< -fts -o$*
|
||||
|
||||
-include $(DEPENDS)
|
||||
-include $(DEPSDIR)/*.d
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
||||
#---------------------------------------------------------------------------------------
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
#include "bigclock.h"
|
||||
#include "../../share/stringtool.h"
|
||||
#include "stringtool.h"
|
||||
#include "systemfilenames.h"
|
||||
#include "windowmanager.h"
|
||||
#include "inifile.h"
|
||||
|
@ -18,7 +18,7 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//<2F>
|
||||
//<2F>
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
@ -34,7 +34,7 @@ cBMP15::cBMP15( u32 width, u32 height ) : _width(0), _height(0), _pitch(0), _buf
|
||||
_width = width;
|
||||
_height = height;
|
||||
_pitch = (width + (width & 1)) << 1;
|
||||
//u32 pitch = (((width*16)+31)>>5)<<2; // 通用算法?
|
||||
//u32 pitch = (((width*16)+31)>>5)<<2; // 通用算法?
|
||||
}
|
||||
|
||||
cBMP15::~cBMP15()
|
||||
@ -46,12 +46,12 @@ cBMP15 createBMP15( u32 width, u32 height )
|
||||
{
|
||||
cBMP15 bmp( width, height );
|
||||
|
||||
u32 pitch = bmp.pitch(); // 15bit bmp pitch 算法
|
||||
u32 pitch = bmp.pitch(); // 15bit bmp pitch 算法
|
||||
//dbg_printf( "pitch: %d bytes\n", pitch );
|
||||
//dbg_printf( "buffer %08x\n", bmp.buffer() );
|
||||
|
||||
u32 bufferSize = height * pitch;
|
||||
if( bufferSize & 3 ) // 如果 bufferSize 不是按4字节对齐,就把他调整到对齐
|
||||
if( bufferSize & 3 ) // 如果 bufferSize 不是按4字节对齐,就把他调整到对齐
|
||||
bufferSize += 4 - (bufferSize & 3);
|
||||
bmp._buffer = new u32[bufferSize>>2];
|
||||
return bmp;
|
||||
@ -85,7 +85,7 @@ cBMP15 createBMP15FromFile( const std::string & filename )
|
||||
return cBMP15();
|
||||
}
|
||||
|
||||
// 读取文件长度
|
||||
// 读取文件长度
|
||||
fseek( f, 0, SEEK_END );
|
||||
int fileSize = ftell( f );
|
||||
|
||||
@ -103,7 +103,7 @@ cBMP15 createBMP15FromFile( const std::string & filename )
|
||||
return cBMP15();
|
||||
}
|
||||
|
||||
// 找出bmp高和宽
|
||||
// 找出bmp高和宽
|
||||
u32 width = 0;
|
||||
u32 height = 0;
|
||||
fseek( f, 0x12, SEEK_SET );
|
||||
|
@ -60,7 +60,7 @@ protected:
|
||||
|
||||
u32 _pitch;
|
||||
|
||||
u32 * _buffer; // 按 32 位地址对齐,可以在 bitblt 的时候加快速度
|
||||
u32 * _buffer; // 按 32 位地址对齐,可以在 bitblt 的时候加快速度
|
||||
};
|
||||
|
||||
cBMP15 createBMP15( u32 width, u32 height );
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "windowmanager.h"
|
||||
#include "inifile.h"
|
||||
#include "globalsettings.h"
|
||||
#include "../../share/stringtool.h"
|
||||
#include "stringtool.h"
|
||||
#include "../../share/memtool.h"
|
||||
|
||||
using namespace akui;
|
||||
|
@ -23,9 +23,9 @@
|
||||
#include "windowmanager.h"
|
||||
#include "language.h"
|
||||
#include "msgbox.h"
|
||||
#include "../../share/gamecode.h"
|
||||
#include "gamecode.h"
|
||||
#include <sys/stat.h>
|
||||
#include <elm.h>
|
||||
#include <fat.h>
|
||||
|
||||
using namespace akui;
|
||||
|
||||
@ -272,7 +272,6 @@ static void updateDB(u8 value,u32 offset,FILE* db)
|
||||
|
||||
void cCheatWnd::onGenerate(void)
|
||||
{
|
||||
NandFast();
|
||||
FILE* db=fopen(SFN_CHEATS,"r+b");
|
||||
if(db)
|
||||
{
|
||||
@ -284,7 +283,6 @@ void cCheatWnd::onGenerate(void)
|
||||
}
|
||||
fclose(db);
|
||||
}
|
||||
NandFlush();
|
||||
cForm::onOK();
|
||||
}
|
||||
|
||||
|
@ -1,121 +0,0 @@
|
||||
/*
|
||||
crtsmall.cpp
|
||||
Copyright (C) 2009 yellow wood goblin
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <new>
|
||||
#include <nds.h>
|
||||
|
||||
const std::nothrow_t std::nothrow={};
|
||||
|
||||
static void Halt(void) __attribute__((__noreturn__));
|
||||
|
||||
static void Halt(void)
|
||||
{
|
||||
while(true) swiWaitForVBlank();
|
||||
}
|
||||
|
||||
void* operator new(std::size_t size)
|
||||
{
|
||||
void* result=malloc(size);
|
||||
if(!result) Halt();
|
||||
return result;
|
||||
}
|
||||
|
||||
void* operator new(std::size_t size,const std::nothrow_t&)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void* operator new[](std::size_t size)
|
||||
{
|
||||
return ::operator new(size);
|
||||
}
|
||||
|
||||
void* operator new[](std::size_t size,const std::nothrow_t&)
|
||||
{
|
||||
return ::operator new(size,std::nothrow);
|
||||
}
|
||||
|
||||
void operator delete(void* block)
|
||||
{
|
||||
free(block);
|
||||
}
|
||||
|
||||
void operator delete[] (void *ptr)
|
||||
{
|
||||
::operator delete(ptr);
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
void __throw_bad_alloc(void)
|
||||
{
|
||||
Halt();
|
||||
}
|
||||
void __throw_length_error(const char*)
|
||||
{
|
||||
Halt();
|
||||
}
|
||||
void __throw_out_of_range(const char*)
|
||||
{
|
||||
Halt();
|
||||
}
|
||||
void __throw_logic_error(const char*)
|
||||
{
|
||||
Halt();
|
||||
}
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void __gxx_personality_v0(void)
|
||||
{
|
||||
Halt();
|
||||
}
|
||||
void __cxa_end_catch(void)
|
||||
{
|
||||
Halt();
|
||||
}
|
||||
void __cxa_begin_catch(void)
|
||||
{
|
||||
Halt();
|
||||
}
|
||||
void __cxa_rethrow(void)
|
||||
{
|
||||
Halt();
|
||||
}
|
||||
void __cxa_end_cleanup(void)
|
||||
{
|
||||
Halt();
|
||||
}
|
||||
void __cxa_pure_virtual(void)
|
||||
{
|
||||
Halt();
|
||||
}
|
||||
void __aeabi_unwind_cpp_pr0(void)
|
||||
{
|
||||
Halt();
|
||||
}
|
||||
void __aeabi_unwind_cpp_pr1(void)
|
||||
{
|
||||
Halt();
|
||||
}
|
||||
void __aeabi_unwind_cpp_pr2(void)
|
||||
{
|
||||
Halt();
|
||||
}
|
||||
}
|
@ -24,7 +24,7 @@
|
||||
#include <nds.h>
|
||||
#include <time.h>
|
||||
#include "singleton.h"
|
||||
#include "../../share/stringtool.h"
|
||||
#include "stringtool.h"
|
||||
|
||||
class cDateTime
|
||||
{
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "inifile.h"
|
||||
#include "systemfilenames.h"
|
||||
#include "../../share/memtool.h"
|
||||
#include "../../share/timetool.h"
|
||||
#include "timetool.h"
|
||||
#include "globalsettings.h"
|
||||
|
||||
using namespace akui;
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include "unknown_nds_banner_bin.h"
|
||||
#include "gbarom_banner_bin.h"
|
||||
#include "icon_bg_bin.h"
|
||||
#include "../../share/gamecode.h"
|
||||
#include "gamecode.h"
|
||||
#include "fileicons.h"
|
||||
|
||||
DSRomInfo & DSRomInfo::operator =( const DSRomInfo & src )
|
||||
@ -47,14 +47,14 @@ bool DSRomInfo::loadDSRomInfo( const std::string & filename, bool loadBanner )
|
||||
_isDSRom = EFalse;
|
||||
_isHomebrew = EFalse;
|
||||
FILE * f = fopen( filename.c_str(), "rb" );
|
||||
if( NULL == f )// <EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>ʧ<EFBFBD><EFBFBD>
|
||||
if( NULL == f )// 锟斤拷锟侥硷拷失锟斤拷
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
tNDSHeader header;
|
||||
if( 512 != fread( &header, 1, 512, f ) ) // <EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>ͷʧ<EFBFBD><EFBFBD>
|
||||
if( 512 != fread( &header, 1, 512, f ) ) // 锟斤拷锟侥硷拷头失锟斤拷
|
||||
{
|
||||
dbg_printf( "read rom header fail\n" );
|
||||
memcpy( &_banner, unknown_nds_banner_bin, sizeof(_banner) );
|
||||
@ -64,7 +64,7 @@ bool DSRomInfo::loadDSRomInfo( const std::string & filename, bool loadBanner )
|
||||
|
||||
///////// ROM Header /////////
|
||||
u16 crc = swiCRC16( 0xFFFF, &header, 0x15E );
|
||||
if( crc != header.headerCRC16 ) // <EFBFBD>ļ<EFBFBD>ͷ CRC <20><><EFBFBD><EFBFBD><F3A3ACB2><EFBFBD>nds<64><73>Ϸ
|
||||
if( crc != header.headerCRC16 ) // 锟侥硷拷头 CRC 锟斤拷锟襟,诧拷锟斤拷nds锟斤拷戏
|
||||
{
|
||||
dbg_printf( "%s rom header crc error\n", filename.c_str() );
|
||||
memcpy( &_banner, unknown_nds_banner_bin, sizeof(_banner) );
|
||||
@ -72,7 +72,7 @@ bool DSRomInfo::loadDSRomInfo( const std::string & filename, bool loadBanner )
|
||||
return true;
|
||||
} else {
|
||||
_isDSRom = ETrue;
|
||||
if( header.arm7destination >= 0x037F8000 || 0x23232323 == gamecode(header.gameCode) ) {//23->'#'
|
||||
if( (u32)(header.arm7destination) >= 0x037F8000 || 0x23232323 == gamecode(header.gameCode) ) {//23->'#'
|
||||
_isHomebrew = ETrue;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include "datetime.h"
|
||||
#include "progresswnd.h"
|
||||
#include "fontfactory.h"
|
||||
#include <elm.h>
|
||||
#include <fat.h>
|
||||
|
||||
using namespace akui;
|
||||
|
||||
@ -214,9 +214,8 @@ void cExpWnd::onRAM()
|
||||
|
||||
void cExpWnd::onSRAM()
|
||||
{
|
||||
std::string saveName="fat0:/sram-"+datetime().getTimeStampString()+".sav";
|
||||
std::string saveName="fat:/sram-"+datetime().getTimeStampString()+".sav";
|
||||
const u32 size=4096*128,page=4096,pages=128;
|
||||
NandFast();
|
||||
FILE* saveFile=fopen(saveName.c_str(),"wb");
|
||||
if(saveFile)
|
||||
{
|
||||
@ -241,7 +240,6 @@ void cExpWnd::onSRAM()
|
||||
}
|
||||
fclose(saveFile);
|
||||
}
|
||||
NandFlush();
|
||||
cForm::onOK();
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include "icons.h"
|
||||
#include "globalsettings.h"
|
||||
#include <sys/dir.h>
|
||||
#include <elm.h>
|
||||
#include <fat.h>
|
||||
|
||||
cFileIconItem::cFileIconItem(const std::string& aFolderName,const std::string& aFileName):_loaded(false),_foldername(aFolderName),_filename(aFileName)
|
||||
{
|
||||
@ -67,28 +67,25 @@ cFileIcons::cFileIcons()
|
||||
|
||||
void cFileIcons::LoadFolder(cIconPaths& aPaths,const std::string& aFolder)
|
||||
{
|
||||
DIR_ITER* dir=diropen(aFolder.c_str());
|
||||
if(NULL!=dir)
|
||||
{
|
||||
struct stat st;
|
||||
char longFilename[MAX_FILENAME_LENGTH];
|
||||
while(dirnext(dir,longFilename,&st)==0)
|
||||
{
|
||||
if((st.st_mode&S_IFDIR)==0)
|
||||
{
|
||||
size_t len=strlen(longFilename);
|
||||
DIR *dir=opendir(aFolder.c_str());
|
||||
struct dirent *entry;
|
||||
|
||||
if (NULL!=dir){
|
||||
while ((entry=readdir(dir))!=NULL) {
|
||||
if(entry->d_type != DT_DIR) {
|
||||
size_t len=strlen(entry->d_name);
|
||||
if(len>4)
|
||||
{
|
||||
char* extName=longFilename+len-4;
|
||||
char* extName=entry->d_name+len-4;
|
||||
if(strcasecmp(extName,".bmp")==0)
|
||||
{
|
||||
*extName=0;
|
||||
aPaths.insert(cFileIconItem(aFolder,longFilename));
|
||||
aPaths.insert(cFileIconItem(aFolder,entry->d_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dirclose(dir);
|
||||
closedir(dir);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,516 +0,0 @@
|
||||
/*
|
||||
files.cpp
|
||||
Copyright (C) 2007 Acekard, www.acekard.com
|
||||
Copyright (C) 2007-2009 somebody
|
||||
Copyright (C) 2009 yellow wood goblin
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <nds.h>
|
||||
#include <string>
|
||||
#include "files.h"
|
||||
//#include "dbgtool.h"
|
||||
#include <elm.h>
|
||||
#include <sys/iosupport.h>
|
||||
#include "msgbox.h"
|
||||
#include "progresswnd.h"
|
||||
#include <errno.h>
|
||||
#include <cstdio>
|
||||
#include <unistd.h>
|
||||
#include "language.h"
|
||||
#include "datetime.h"
|
||||
#include "dsrom.h"
|
||||
#include "favorites.h"
|
||||
|
||||
#define USE_OPEN
|
||||
#ifdef USE_OPEN
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
using namespace akui;
|
||||
|
||||
static SRC_FILE_MODE _srcFileMode = SFM_COPY;
|
||||
static std::string _srcFilename = "";
|
||||
|
||||
bool loadFile( void * buffer, const std::string & filename, size_t offset, size_t & readCount )
|
||||
{
|
||||
if( "" == filename )
|
||||
return false;
|
||||
|
||||
if( NULL == buffer ) {
|
||||
dbg_printf("invalid buffer pointer\n");
|
||||
struct stat st;
|
||||
stat( filename.c_str(), &st );
|
||||
readCount = st.st_size;
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE * f = fopen( filename.c_str(), "rb" );
|
||||
if( NULL == f ) {
|
||||
dbg_printf("file does not exist\n");
|
||||
readCount = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek( f, 0, SEEK_END );
|
||||
int fileSize = ftell( f );
|
||||
|
||||
if( -1 == fileSize ) {
|
||||
fclose( f );
|
||||
readCount = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek( f, offset, SEEK_SET );
|
||||
size_t readed = fread( buffer, 1, fileSize, f );
|
||||
fclose( f );
|
||||
|
||||
readCount = readed;
|
||||
if( readed != (size_t)fileSize-offset ) {
|
||||
dbg_printf("fread fail: %d/%d\n", readed, fileSize );
|
||||
readCount = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int getFileSize( const std::string & filename )
|
||||
{
|
||||
if( "" == filename )
|
||||
return -1;
|
||||
|
||||
struct stat st;
|
||||
if( -1 == stat( filename.c_str(), &st ) ) {
|
||||
return -1;
|
||||
}
|
||||
return st.st_size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------//
|
||||
bool stopCopying = false;
|
||||
bool copyingFile = false;
|
||||
|
||||
bool copyFile( const std::string & srcFilename, const std::string & destFilename, bool silently, size_t copyLength )
|
||||
{
|
||||
dbg_printf("copy %s to %s\n", srcFilename.c_str(), destFilename.c_str() );
|
||||
struct stat srcSt;
|
||||
if( 0 != stat( srcFilename.c_str(), &srcSt ) ) {
|
||||
messageBox( NULL, LANG("copy file error","title"), LANG("copy file error","text"), MB_OK );
|
||||
return false;
|
||||
}
|
||||
|
||||
u64 total = 0;
|
||||
u64 used = 0;
|
||||
u64 freeSpace = 0;
|
||||
|
||||
std::string destDiskName = destFilename.substr( 0, 6 );
|
||||
if( destDiskName != "fat0:/" && destDiskName != "fat1:/" )
|
||||
return false;
|
||||
|
||||
if( !getDiskSpaceInfo( destDiskName, total, used, freeSpace ) ) {
|
||||
messageBox( NULL, LANG("no free space","title"), LANG("no free space","text"), MB_OK );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( 0 == copyLength || copyLength > (size_t)srcSt.st_size )
|
||||
copyLength = srcSt.st_size;
|
||||
|
||||
if( freeSpace < copyLength ) {
|
||||
messageBox( NULL, LANG("no free space","title"), LANG("no free space","text"), MB_OK );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !silently ) {
|
||||
struct stat destSt;
|
||||
if( 0 == stat( destFilename.c_str(), &destSt ) ) {
|
||||
if( !( destSt.st_mode & S_IFDIR ) ) {
|
||||
u32 ret = messageBox( NULL, LANG("copy file exists","title"),
|
||||
LANG("copy file exists","text"), MB_YES | MB_NO );
|
||||
if( ret != ID_YES )
|
||||
return false;
|
||||
} else {
|
||||
messageBox( NULL, LANG("copy dest is directory","title"),
|
||||
LANG("copy dest is directory","text"), MB_CANCEL );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 copyBufferSize=gs().CopyBufferSize();
|
||||
u8* copyBuffer=new(std::nothrow)u8[copyBufferSize];
|
||||
if(copyBuffer==NULL)
|
||||
{
|
||||
messageBox(NULL,LANG("ram allocation","title"),LANG("ram allocation","memory allocation error"),MB_OK);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string tempText = LANG("progress window", "processing copy");
|
||||
std::string copyTip = formatString( tempText.c_str(), (char)0x02 );
|
||||
progressWnd().setTipText( copyTip );
|
||||
progressWnd().show();
|
||||
progressWnd().setPercent( 0 );
|
||||
stopCopying = false;
|
||||
copyingFile = true;
|
||||
|
||||
NandFast();
|
||||
#ifdef USE_OPEN
|
||||
int wf=open(destFilename.c_str(),O_WRONLY|O_CREAT|O_TRUNC);
|
||||
int rf=open(srcFilename.c_str(),O_RDONLY);
|
||||
#else
|
||||
FILE * wf = fopen( destFilename.c_str(), "wb" );
|
||||
FILE * rf = fopen( srcFilename.c_str(), "rb" );
|
||||
#endif
|
||||
u8 percent = 0;
|
||||
|
||||
dbg_printf("start: %s", datetime().getTimeString().c_str() );
|
||||
|
||||
u32 writeCount = copyLength / copyBufferSize;
|
||||
if( copyLength % copyBufferSize )
|
||||
writeCount++;
|
||||
dbg_printf("write count %d\n", writeCount );
|
||||
|
||||
u32 remain = copyLength;
|
||||
|
||||
for( size_t i = 0; i < writeCount; ++i ) {
|
||||
if( stopCopying ) {
|
||||
copyingFile = false;
|
||||
u32 ret = messageBox( &progressWnd(), LANG("stop copying file","title"),
|
||||
LANG("stop copying file","text"), MB_YES | MB_NO );
|
||||
|
||||
if( ID_YES == ret ) {
|
||||
#ifdef USE_OPEN
|
||||
close(rf);
|
||||
close(wf);
|
||||
#else
|
||||
fclose( rf );
|
||||
fclose( wf );
|
||||
#endif
|
||||
NandFlush();
|
||||
progressWnd().hide();
|
||||
copyingFile = false;
|
||||
delete[] copyBuffer;
|
||||
return false;
|
||||
}
|
||||
copyingFile = true;
|
||||
stopCopying = false;
|
||||
}
|
||||
|
||||
u32 toRead = remain > copyBufferSize ? copyBufferSize : remain;
|
||||
#ifdef USE_OPEN
|
||||
ssize_t readed=read(rf,copyBuffer,toRead);
|
||||
ssize_t written=write(wf,copyBuffer,readed);
|
||||
#else
|
||||
u32 readed = fread( copyBuffer, 1, toRead, rf );
|
||||
u32 written = fwrite( copyBuffer, 1, (int)readed, wf );
|
||||
#endif
|
||||
if( written != readed ) {
|
||||
dbg_printf("err %d\n", errno );
|
||||
dbg_printf("COPY FILE ERROR! %d/%d\n", readed, written );
|
||||
// todo: judge error types in errno
|
||||
#ifdef USE_OPEN
|
||||
close(rf);
|
||||
close(wf);
|
||||
#else
|
||||
fclose( rf );
|
||||
fclose( wf );
|
||||
#endif
|
||||
NandFlush();
|
||||
progressWnd().hide();
|
||||
copyingFile = false;
|
||||
delete[] copyBuffer;
|
||||
messageBox( NULL, LANG("no free space","title"), LANG("no free space","text"), MB_OK );
|
||||
return false;
|
||||
}
|
||||
remain -= written;
|
||||
percent = i * 100 / writeCount;
|
||||
progressWnd().setPercent( percent );
|
||||
}
|
||||
#ifdef USE_OPEN
|
||||
close(rf);
|
||||
close(wf);
|
||||
#else
|
||||
fclose( rf );
|
||||
fclose( wf );
|
||||
#endif
|
||||
NandFlush();
|
||||
progressWnd().hide();
|
||||
copyingFile = false;
|
||||
delete[] copyBuffer;
|
||||
|
||||
dbg_printf("finish: %s", datetime().getTimeString().c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool renameFile( const std::string & oldName, const std::string & newName )
|
||||
{
|
||||
if( "" == oldName || "" == newName )
|
||||
return false;
|
||||
|
||||
struct stat destSt;
|
||||
if( 0 == stat( newName.c_str(), &destSt ) ) {
|
||||
if( !( destSt.st_mode & S_IFDIR ) ) {
|
||||
u32 ret = messageBox( NULL, LANG("copy file exists","title"),
|
||||
LANG("copy file exists","text"), MB_YES | MB_NO );
|
||||
if( ret != ID_YES )
|
||||
return false;
|
||||
} else {
|
||||
messageBox( NULL, LANG("move dest is directory","title"),
|
||||
LANG("move dest is directory","text"), MB_CANCEL );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if( 0 != rename( oldName.c_str(), newName.c_str() ) ) {
|
||||
if( EEXIST == errno || EXDEV == errno ) {
|
||||
bool success = copyFile( oldName, newName, true );
|
||||
if( success ) {
|
||||
unlink( oldName.c_str() );
|
||||
return true;
|
||||
} else {
|
||||
unlink( newName.c_str() );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool deleteFile( const std::string & filename )
|
||||
{
|
||||
if( "" == filename )
|
||||
return false;
|
||||
|
||||
struct stat destSt;
|
||||
if( 0 != stat( filename.c_str(), &destSt ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string confirmText = LANG("confirm delete file","text");
|
||||
std::string showname,realname;
|
||||
if( '/' == filename[filename.size()-1] )
|
||||
showname = filename.substr( 0, filename.size() - 1 );
|
||||
else
|
||||
showname = filename;
|
||||
realname = showname;
|
||||
|
||||
size_t slashPos = showname.find_last_of( '/' );
|
||||
if( showname.npos != slashPos )
|
||||
showname = showname.substr( slashPos + 1 );
|
||||
|
||||
confirmText = formatString( confirmText.c_str(), showname.c_str() );
|
||||
u32 result = messageBox( NULL, LANG("confirm delete file","title"), confirmText.c_str(), MB_YES | MB_NO );
|
||||
if( result != ID_YES ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int ret = unlink( realname.c_str() );
|
||||
if( 0 != ret ) {
|
||||
if( EACCES == errno ) {
|
||||
messageBox( NULL, LANG("do not delete directory","title"), LANG("do not delete directory","text"), MB_OK );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
cFavorites::RemoveFromFavorites(filename);
|
||||
return true;
|
||||
}
|
||||
|
||||
void setSrcFile( const std::string & filename, SRC_FILE_MODE mode )
|
||||
{
|
||||
_srcFilename = filename;
|
||||
_srcFileMode = mode;
|
||||
}
|
||||
|
||||
const std::string& getSrcFile(void)
|
||||
{
|
||||
return _srcFilename;
|
||||
}
|
||||
|
||||
bool copyOrMoveFile( const std::string & destDir )
|
||||
{
|
||||
if( "" == _srcFilename )
|
||||
return false;
|
||||
|
||||
const char * pPath = _srcFilename.c_str();
|
||||
const char * pName = NULL;
|
||||
while( pPath < _srcFilename.c_str() + _srcFilename.size() )
|
||||
{
|
||||
if( '/' == *pPath++ )
|
||||
pName = pPath;
|
||||
}
|
||||
|
||||
if( 0 == *pName )
|
||||
return false;
|
||||
|
||||
std::string destPath = destDir + pName;
|
||||
if( destPath == _srcFilename )
|
||||
return false;
|
||||
|
||||
if( SFM_COPY == _srcFileMode )
|
||||
{
|
||||
u32 copyLength = 0;
|
||||
|
||||
if( gs().romTrim ) {
|
||||
std::string extName;
|
||||
size_t lastDotPos = _srcFilename.find_last_of( '.' );
|
||||
if( _srcFilename.npos != lastDotPos )
|
||||
extName = _srcFilename.substr( lastDotPos );
|
||||
else
|
||||
extName = "";
|
||||
for( size_t i = 0; i < extName.size(); ++i )
|
||||
extName[i] = tolower( extName[i] );
|
||||
|
||||
if( ".nds" == extName ) {
|
||||
DSRomInfo info;
|
||||
info.MayBeDSRom(_srcFilename);
|
||||
if( info.isDSRom() && !info.isHomebrew() ) {
|
||||
FILE * f = fopen( _srcFilename.c_str(), "rb" );
|
||||
fseek( f, 0x80, SEEK_SET );
|
||||
fread( ©Length, 1, 4, f );
|
||||
fclose(f);
|
||||
copyLength += 0x88; // to keep RSA signature
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool copyOK = copyFile( _srcFilename, destPath, false, copyLength );
|
||||
if( copyOK ) {
|
||||
_srcFilename = "";
|
||||
}
|
||||
return copyOK;
|
||||
}
|
||||
|
||||
if( SFM_CUT == _srcFileMode )
|
||||
{
|
||||
bool moveOK = renameFile( _srcFilename, destPath );
|
||||
if( moveOK ) {
|
||||
cFavorites::UpdateFavorites(_srcFilename,destPath);
|
||||
_srcFilename = "";
|
||||
}
|
||||
return moveOK;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool getDirSize( const std::string & path, bool includeSubdirs, u64 * dirSize )
|
||||
{
|
||||
if( "" == path )
|
||||
return false;
|
||||
|
||||
u64 size = 0;
|
||||
|
||||
std::string dirPath = path;
|
||||
if( dirPath[dirPath.size()-1] != '/' )
|
||||
dirPath += "/";
|
||||
if( dirPath.size() > MAX_FILENAME_LENGTH )
|
||||
return false;
|
||||
|
||||
DIR_ITER * dir = NULL;
|
||||
dir = diropen(dirPath.c_str());
|
||||
if (dir == NULL) {
|
||||
//dbg_printf("getDirSize couldn't open dir %s", path.c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
size = 0;
|
||||
char filename[MAX_FILENAME_LENGTH];
|
||||
|
||||
struct stat stat_buf;
|
||||
while (dirnext(dir, filename, &stat_buf) == 0) {
|
||||
|
||||
if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//dbg_printf("getDirSize dir entry '%s'", path.c_str());
|
||||
if (!(stat_buf.st_mode & S_IFDIR)) {
|
||||
//dbg_printf("getDirSize add size %d for '%s'", (int)stat_buf.st_size, path.c_str());
|
||||
size += (u64)stat_buf.st_size;
|
||||
} else if (includeSubdirs) {
|
||||
/* calculate the size recursively */
|
||||
u64 subDirSize = 0;
|
||||
bool succ = getDirSize( dirPath + filename, includeSubdirs, &subDirSize );
|
||||
/* ignore failure in subdirs */
|
||||
if( succ ) {
|
||||
size += subDirSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dirclose(dir);
|
||||
*dirSize = size;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool getDiskFromString(const std::string& diskName,u32& disk)
|
||||
{
|
||||
if(tolower(diskName[0])=='f'&&tolower(diskName[1])=='a'&&tolower(diskName[2])=='t'&&(diskName[3]=='0'||diskName[3]=='1')&&diskName[4]==':')
|
||||
{
|
||||
disk=diskName[3]-'0';
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool getDiskTotalSpace(u32 disk,u64& diskSpace)
|
||||
{
|
||||
u32 clusters,clusterSize;
|
||||
if(ELM_ClusterSizeFromDisk(disk,&clusterSize)&&ELM_ClustersFromDisk(disk,&clusters))
|
||||
{
|
||||
diskSpace=(u64)clusters*(u64)clusterSize;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool getDiskFreeSpace(u32 disk,u64& freeSpace)
|
||||
{
|
||||
u32 clusters,clusterSize;
|
||||
if(ELM_ClusterSizeFromDisk(disk,&clusterSize)&&ELM_FreeClustersFromDisk(disk,&clusters))
|
||||
{
|
||||
freeSpace=(u64)clusters*(u64)clusterSize;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool getDiskSpaceInfo(const std::string& diskName,u64& total,u64& used,u64& freeSpace)
|
||||
{
|
||||
if(""==diskName) return false;
|
||||
u32 disk;
|
||||
if(!getDiskFromString(diskName,disk))
|
||||
{
|
||||
cwl();
|
||||
return false;
|
||||
}
|
||||
if(!getDiskTotalSpace(disk,total))
|
||||
{
|
||||
cwl();
|
||||
return false;
|
||||
}
|
||||
if(!getDiskFreeSpace(disk,freeSpace))
|
||||
{
|
||||
cwl();
|
||||
return false;
|
||||
}
|
||||
cwl();
|
||||
used=total-freeSpace;
|
||||
return true;
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
files.h
|
||||
Copyright (C) 2007 Acekard, www.acekard.com
|
||||
Copyright (C) 2007-2009 somebody
|
||||
Copyright (C) 2009 yellow wood goblin
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _FILES_H_
|
||||
#define _FILES_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
bool loadFile( void * buffer, const std::string & filename, size_t offset, size_t & readCount );
|
||||
|
||||
// 返回文件大小,-1表示文件不存在
|
||||
int getFileSize( const std::string & filename );
|
||||
|
||||
extern bool stopCopying;
|
||||
extern bool copyingFile;
|
||||
bool copyFile( const std::string & srcFilename, const std::string & destFilename, bool silently, size_t copyLength = 0 );
|
||||
|
||||
bool renameFile( const std::string & oldName, const std::string & newName );
|
||||
|
||||
bool deleteFile( const std::string & filename );
|
||||
|
||||
enum SRC_FILE_MODE
|
||||
{
|
||||
SFM_COPY = 0,
|
||||
SFM_CUT = 1
|
||||
};
|
||||
|
||||
void setSrcFile( const std::string & filename, SRC_FILE_MODE mode );
|
||||
|
||||
const std::string& getSrcFile(void);
|
||||
|
||||
bool copyOrMoveFile( const std::string & destDir );
|
||||
|
||||
bool getDirSize( const std::string & path, bool includeSubdirs, u64 * dirSize );
|
||||
|
||||
bool getDiskSpaceInfo( const std::string & diskName, u64 & total, u64 & used, u64 & freeSpace );
|
||||
|
||||
#endif//_FILES_H_
|
@ -21,7 +21,6 @@
|
||||
#include <nds.h>
|
||||
#include <string.h>
|
||||
#include "font.h"
|
||||
#include "files.h"
|
||||
#include "dbgtool.h"
|
||||
#include "systemfilenames.h"
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <nds.h>
|
||||
|
||||
|
||||
#include <singleton.h>
|
||||
#include "singleton.h"
|
||||
|
||||
#include "font.h"
|
||||
class cFontFactory
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include "sram.h"
|
||||
#include "gbapatcher.h"
|
||||
#include "gbaloader.h"
|
||||
#include <elm.h>
|
||||
#include <fat.h>
|
||||
|
||||
#define LEN 0x100000
|
||||
#define LEN_NOR 0x8000
|
||||
@ -225,7 +225,6 @@ bool CGbaLoader::CheckPSRAM(u32 aSize)
|
||||
void CGbaLoader::StartGBA(void)
|
||||
{
|
||||
LoadBorder();
|
||||
ELM_Unmount();
|
||||
BootGBA();
|
||||
while(true) swiWaitForVBlank();
|
||||
}
|
||||
@ -241,7 +240,7 @@ void CGbaLoader::LoadBorder(void)
|
||||
{
|
||||
videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
|
||||
videoSetModeSub(MODE_5_2D | DISPLAY_BG3_ACTIVE);
|
||||
vramSetMainBanks(VRAM_A_MAIN_BG_0x06000000, VRAM_B_MAIN_BG_0x06020000, VRAM_C_SUB_BG_0x06200000, VRAM_D_LCD);
|
||||
vramSetPrimaryBanks(VRAM_A_MAIN_BG_0x06000000, VRAM_B_MAIN_BG_0x06020000, VRAM_C_SUB_BG_0x06200000, VRAM_D_LCD);
|
||||
|
||||
// for the main screen
|
||||
REG_BG3CNT = BG_BMP16_256x256 | BG_BMP_BASE(0) | BG_WRAP_OFF;
|
||||
@ -358,7 +357,7 @@ bool CGbaLoader::LoadNor(void)
|
||||
cSram::CreateDefaultFile(iFileName.c_str(),saveSize);
|
||||
/*
|
||||
FILE *log;
|
||||
log=fopen("fat0:/test.bin","wb");
|
||||
log=fopen("fat:/test.bin","wb");
|
||||
fwrite((void*)0x08000000,iSize,1,log);
|
||||
fclose(log);
|
||||
// */
|
||||
|
@ -20,6 +20,9 @@
|
||||
#ifndef __GBALOADER_H__
|
||||
#define __GBALOADER_H__
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
#include <string>
|
||||
|
||||
class CGbaLoader
|
||||
{
|
||||
private:
|
||||
|
@ -155,16 +155,16 @@ void cGdi::activeFbMain(void)
|
||||
vramSetBankA( VRAM_A_MAIN_SPRITE_0x06400000 );
|
||||
|
||||
REG_BG2CNT = BG_BMP16_256x256 | BG_BMP_BASE(0) | BG_PRIORITY_1;
|
||||
REG_BG2PA = 1 << 8; // 2 =放大倍数
|
||||
REG_BG2PD = 1 << 8; // 2 =放大倍数
|
||||
REG_BG2PA = 1 << 8; // 2 =放大倍数
|
||||
REG_BG2PD = 1 << 8; // 2 =放大倍数
|
||||
REG_BG2PB = 0;
|
||||
REG_BG2PC = 0;
|
||||
REG_BG2Y = 0;
|
||||
REG_BG2X = 0;
|
||||
|
||||
REG_BG3CNT = BG_BMP16_256x256 | BG_BMP_BASE(8) | BG_PRIORITY_2;
|
||||
REG_BG3PA = 1 << 8; // 2 =放大倍数
|
||||
REG_BG3PD = 1 << 8; // 2 =放大倍数
|
||||
REG_BG3PA = 1 << 8; // 2 =放大倍数
|
||||
REG_BG3PD = 1 << 8; // 2 =放大倍数
|
||||
REG_BG3PB = 0;
|
||||
REG_BG3PC = 0;
|
||||
REG_BG3Y = 0;
|
||||
@ -200,14 +200,14 @@ void cGdi::activeFbSub(void)
|
||||
MyInitConsole(_bufferSub3+0x2000,_bufferSub3);
|
||||
#endif
|
||||
|
||||
// 分配显存存, 128k
|
||||
// 分配显存存, 128k
|
||||
vramSetBankC( VRAM_C_SUB_BG_0x06200000 ); // 128k
|
||||
|
||||
// 初始化为文字模式
|
||||
// 初始化为文字模式
|
||||
_subEngineMode = SEM_GRAPHICS;
|
||||
//_subEngineMode = SEM_TEXT;
|
||||
|
||||
// BMP bg 的参数设置,从 VRAM地址 0x06200000 开始,优先级3
|
||||
// BMP bg 的参数设置,从 VRAM地址 0x06200000 开始,优先级3
|
||||
REG_BG2CNT_SUB = BG_BMP16_256x256 | BG_BMP_BASE(0) | BG_PRIORITY_1;
|
||||
REG_BG2PA_SUB = 1<<8;
|
||||
REG_BG2PD_SUB = 1<<8;
|
||||
@ -225,18 +225,18 @@ void cGdi::activeFbSub(void)
|
||||
fillMemory( _bufferSub1, 0x18000, 0xffffffff );
|
||||
|
||||
// text BG
|
||||
// text bg 的字模占用 32(字节/字模) * 256(个ascii字) = 8192 字节显存,
|
||||
// 文字显示占用 32 x 32 * 2 = 2048 字节显存
|
||||
// 字模从 block 8 开始 = 0x06200000 + 8 * 0x4000 = 0x06220000
|
||||
// 文字信息从 block 72 开始 = 0x06200000 + 72 * 0x800 = 0x06224000
|
||||
// 优先级 2
|
||||
// text bg 的字模占用 32(字节/字模) * 256(个ascii字) = 8192 字节显存,
|
||||
// 文字显示占用 32 x 32 * 2 = 2048 字节显存
|
||||
// 字模从 block 8 开始 = 0x06200000 + 8 * 0x4000 = 0x06220000
|
||||
// 文字信息从 block 72 开始 = 0x06200000 + 72 * 0x800 = 0x06224000
|
||||
// 优先级 2
|
||||
#ifdef DEBUG
|
||||
BG_PALETTE_SUB[255] = RGB15(31,31,31); //by default font will be rendered with color 255
|
||||
REG_BG0CNT_SUB = BG_TILE_BASE(0) | BG_MAP_BASE(8) | BG_PRIORITY_2;
|
||||
#endif
|
||||
|
||||
swiWaitForVBlank(); //remove tearing at top screen
|
||||
// 模式5,开两层BG,一层BMP,一层文字(用于调试),bmp层现在默认关闭
|
||||
// 模式5,开两层BG,一层BMP,一层文字(用于调试),bmp层现在默认关闭
|
||||
videoSetModeSub( MODE_5_2D | DISPLAY_BG2_ACTIVE );// | DISPLAY_BG2_ACTIVE );
|
||||
}
|
||||
|
||||
@ -483,8 +483,8 @@ void cGdi::bitBlt( const void * src, s16 destX, s16 destY, u16 destW, u16 destH,
|
||||
}
|
||||
}
|
||||
|
||||
// maskBlt 要destW是偶数,速度可以快一倍
|
||||
// 不是偶数也可以,但要求在内存中 src 的 pitch 凑成偶数
|
||||
// maskBlt 要destW是偶数,速度可以快一倍
|
||||
// 不是偶数也可以,但要求在内存中 src 的 pitch 凑成偶数
|
||||
void cGdi::maskBlt( const void * src, s16 destX, s16 destY, u16 destW, u16 destH, GRAPHICS_ENGINE engine )
|
||||
{
|
||||
//dbg_printf("x %d y %d w %d h %d\n", destX, destY, destW, destH );
|
||||
@ -618,7 +618,7 @@ void cGdi::textOutRect( s16 x, s16 y, u16 w, u16 h, const char * text, GRAPHICS_
|
||||
|
||||
void cGdi::present( GRAPHICS_ENGINE engine )
|
||||
{
|
||||
if( GE_MAIN == engine ) { // 翻转主引擎
|
||||
if( GE_MAIN == engine ) { // 翻转主引擎
|
||||
//u16 * temp = _bufferMain1;
|
||||
//_bufferMain1 = _bufferMain2;
|
||||
//_bufferMain2 = temp;
|
||||
@ -629,7 +629,7 @@ void cGdi::present( GRAPHICS_ENGINE engine )
|
||||
|
||||
fillMemory( (void *)(_bufferMain2 + _layerPitch), 256 * 192 * 2, 0 );
|
||||
|
||||
} else if ( GE_SUB == engine ) { // 翻转副引擎
|
||||
} else if ( GE_SUB == engine ) { // 翻转副引擎
|
||||
if( SEM_GRAPHICS == _subEngineMode )
|
||||
dmaCopyWordsGdi( 3, (void *)_bufferSub2, (void *)_bufferSub1, 256 * 192 * 2 );
|
||||
//else if( SEM_TEXT == _subEngineMode )
|
||||
@ -651,16 +651,16 @@ void cGdi::present(void)
|
||||
#ifdef DEBUG
|
||||
void cGdi::switchSubEngineMode()
|
||||
{
|
||||
// 需要保存和恢复文本模式的现场
|
||||
// 需要保存和恢复文本模式的现场
|
||||
switch( _subEngineMode )
|
||||
{
|
||||
case SEM_GRAPHICS: // 当前是图形模式的话,就恢复刚才的text现场
|
||||
case SEM_GRAPHICS: // 当前是图形模式的话,就恢复刚才的text现场
|
||||
videoSetModeSub( MODE_5_2D | DISPLAY_BG0_ACTIVE );
|
||||
custom_console.fontBgMap=(u16*)0x6204000;
|
||||
custom_console.fontBgGfx=(u16*)0x6200000;
|
||||
dmaCopyWordsGdi( 3, (void *)_bufferSub3, (void *)_bufferSub1, 0x4800 );
|
||||
break;
|
||||
case SEM_TEXT: // 当前是文字模式的话,保存现场,切到图形模式
|
||||
case SEM_TEXT: // 当前是文字模式的话,保存现场,切到图形模式
|
||||
videoSetModeSub( MODE_5_2D | DISPLAY_BG2_ACTIVE );
|
||||
custom_console.fontBgMap=_bufferSub3+0x2000;
|
||||
custom_console.fontBgGfx=_bufferSub3;
|
||||
|
@ -28,9 +28,7 @@
|
||||
cGlobalSettings::cGlobalSettings()
|
||||
{
|
||||
fontHeight=12;
|
||||
#if defined(_STORAGE_r4)
|
||||
brightness=1;
|
||||
#endif
|
||||
language=1;
|
||||
langDirectory="English";
|
||||
uiName="zelda";
|
||||
@ -98,11 +96,9 @@ void cGlobalSettings::loadSettings()
|
||||
struct stat st;
|
||||
if(0==stat(SFN_CHEATS,&st)) cheatDB=true;
|
||||
|
||||
#if defined(_STORAGE_r4)
|
||||
CIniFile iniBacklight(SFN_BACKLIGHT);
|
||||
brightness=iniBacklight.GetInt("brightness","brightness",brightness);
|
||||
setBrightness(brightness);
|
||||
#endif
|
||||
updateSafeMode();
|
||||
}
|
||||
|
||||
@ -154,9 +150,6 @@ u32 cGlobalSettings::CopyBufferSize(void)
|
||||
|
||||
void cGlobalSettings::nextBrightness(void)
|
||||
{
|
||||
#if defined(_STORAGE_rpg) || defined(_STORAGE_ak2i) || defined(_STORAGE_r4idsn)
|
||||
fifoSendValue32(FIFO_USER_01,MENU_MSG_BRIGHTNESS_NEXT);
|
||||
#elif defined(_STORAGE_r4)
|
||||
fifoSendValue32(FIFO_USER_01,MENU_MSG_BRIGHTNESS_GET);
|
||||
while(!fifoCheckValue32(FIFO_USER_01));
|
||||
u32 currentLevel=fifoGetValue32(FIFO_USER_01);
|
||||
@ -166,12 +159,9 @@ void cGlobalSettings::nextBrightness(void)
|
||||
CIniFile ini(SFN_BACKLIGHT);
|
||||
ini.SetInt("brightness","brightness",brightness);
|
||||
ini.SaveIniFile(SFN_BACKLIGHT);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(_STORAGE_r4)
|
||||
void cGlobalSettings::setBrightness(u32 level)
|
||||
{
|
||||
fifoSendValue32(FIFO_USER_01,MENU_MSG_BRIGHTNESS_SET0+(brightness&3));
|
||||
}
|
||||
#endif
|
||||
|
@ -60,14 +60,10 @@ public:
|
||||
void updateSafeMode(void);
|
||||
static u32 CopyBufferSize(void);
|
||||
void nextBrightness(void);
|
||||
#if defined(_STORAGE_r4)
|
||||
void setBrightness(u32 level);
|
||||
#endif
|
||||
public:
|
||||
u8 fontHeight;
|
||||
#if defined(_STORAGE_r4)
|
||||
u8 brightness;
|
||||
#endif
|
||||
u8 language;
|
||||
u8 fileListType;
|
||||
u8 romTrim;
|
||||
|
@ -18,7 +18,6 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "iocmn.h"
|
||||
#include "helpwnd.h"
|
||||
#include "msgbox.h"
|
||||
#include "windowmanager.h"
|
||||
@ -61,9 +60,8 @@ _buttonOK(0,0,46,18,this,"\x01 OK")
|
||||
|
||||
//u8 nandDriverVer = getNandDriverVer();
|
||||
_helpText += '\n';
|
||||
_helpText += formatString( "wood akmenu %s.%s ", AKMENU_VRESION_MAIN, AKMENU_VRESION_SUB );
|
||||
_helpText += formatString( "HW: %02x", ioVersion() );
|
||||
_helpText += formatString( "\nfont: %dk size: %x", font().FontRAM()/1024, ioSize() );
|
||||
_helpText += formatString( "wood akmenu %s.%s ", AKMENU_VERSION_MAIN, AKMENU_VERSION_SUB );
|
||||
_helpText += formatString( "\nfont: %dk", font().FontRAM()/1024 );
|
||||
}
|
||||
|
||||
cHelpWnd::~cHelpWnd()
|
||||
|
@ -21,9 +21,9 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include "inifile.h"
|
||||
#include "../../share/stringtool.h"
|
||||
#include "stringtool.h"
|
||||
#include "dbgtool.h"
|
||||
#include <elm.h>
|
||||
#include <fat.h>
|
||||
|
||||
static bool freadLine(FILE* f,std::string& str)
|
||||
{
|
||||
@ -229,11 +229,9 @@ bool CIniFile::SaveIniFile(const std::string& FileName)
|
||||
if(FileName!="")
|
||||
m_sFileName=FileName;
|
||||
|
||||
NandFast();
|
||||
FILE* f=fopen(m_sFileName.c_str(),"wb");
|
||||
if(NULL==f)
|
||||
{
|
||||
NandFlush();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -255,7 +253,6 @@ bool CIniFile::SaveIniFile(const std::string& FileName)
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
NandFlush();
|
||||
|
||||
m_bModified=false;
|
||||
|
||||
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
iocmn.h
|
||||
Copyright (C) 2010 yellow wood goblin
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __IOCMN_H__
|
||||
#define __IOCMN_H__
|
||||
|
||||
#if defined(_STORAGE_rpg)
|
||||
#include <iorpg.h>
|
||||
#elif defined(_STORAGE_r4)
|
||||
#include <ior4.h>
|
||||
#elif defined(_STORAGE_ak2i)
|
||||
#include <ioak2i.h>
|
||||
#elif defined(_STORAGE_r4idsn)
|
||||
#include <ior4idsn.h>
|
||||
#endif
|
||||
|
||||
#endif
|
@ -28,7 +28,6 @@
|
||||
#include "bigclock.h"
|
||||
#include "timer.h"
|
||||
#include "animation.h"
|
||||
#include "files.h"
|
||||
#include "userwnd.h"
|
||||
|
||||
using namespace akui;
|
||||
@ -64,17 +63,6 @@ void cIRQ::vBlank()
|
||||
if( !_vblankStarted )
|
||||
return;
|
||||
|
||||
// get inputs when file copying because the main route
|
||||
// can't do any thing at that time
|
||||
if( true == copyingFile) {
|
||||
if( false == stopCopying ) {
|
||||
INPUT & input = updateInput();
|
||||
if( (input.keysDown & KEY_B) ) {
|
||||
stopCopying = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
timer().updateTimer();
|
||||
|
||||
static u32 vBlankCounter = 0;
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include <map>
|
||||
#include <list>
|
||||
|
||||
#include <elm.h>
|
||||
#include <fat.h>
|
||||
|
||||
#include "dbgtool.h"
|
||||
#include "gdi.h"
|
||||
@ -91,8 +91,7 @@ int main(void)
|
||||
|
||||
//wait_press_b();
|
||||
// init fat
|
||||
//bool succ = fatInitDefault();
|
||||
bool succ = (ELM_Mount()&1)?false:true;
|
||||
bool succ = fatInitDefault();
|
||||
if( !succ )
|
||||
dbg_printf( "init fat %d\n", succ );
|
||||
|
||||
@ -172,25 +171,7 @@ int main(void)
|
||||
}
|
||||
|
||||
{ //backup save data from chip to flash. pressing LShift+Up aborts backup.
|
||||
#if defined(_STORAGE_rpg)
|
||||
INPUT & inputs = updateInput();
|
||||
if((inputs.keysHeld&(KEY_UP|KEY_L))==(KEY_UP|KEY_L))
|
||||
{
|
||||
u32 ret = messageBox( NULL, LANG("abort save", "title"), LANG("abort save", "text"), MB_YES | MB_NO );
|
||||
if(ret==ID_YES)
|
||||
{
|
||||
saveManager().clearLastInfo();
|
||||
saveManager().clearSaveBlocks();
|
||||
}
|
||||
else saveManager().backupSaveData();
|
||||
}
|
||||
else
|
||||
{
|
||||
saveManager().backupSaveData();
|
||||
}
|
||||
#elif defined(_STORAGE_r4) || defined(_STORAGE_ak2i) || defined(_STORAGE_r4idsn)
|
||||
saveManager().clearLastInfo();
|
||||
#endif
|
||||
//backup gba sram save date to flash.
|
||||
if(gs().gbaAutoSave&&expansion().IsValid())
|
||||
{
|
||||
|
@ -21,16 +21,14 @@
|
||||
//<2F>
|
||||
|
||||
#include <sys/dir.h>
|
||||
#include <elm.h>
|
||||
#define ATTRIB_HID 0x02
|
||||
#include <fat.h>
|
||||
#include "mainlist.h"
|
||||
#include "files.h"
|
||||
#include "dbgtool.h"
|
||||
#include "startmenu.h"
|
||||
#include "systemfilenames.h"
|
||||
#include "romloader.h"
|
||||
#include "windowmanager.h"
|
||||
#include "../../share/timetool.h"
|
||||
#include "timetool.h"
|
||||
#include "../../share/memtool.h"
|
||||
#include "inifile.h"
|
||||
#include "unknown_banner_bin.h"
|
||||
@ -47,11 +45,7 @@ using namespace akui;
|
||||
|
||||
cMainList::cMainList( s32 x, s32 y, u32 w, u32 h, cWindow * parent, const std::string & text )
|
||||
: cListView( x, y, w, h, parent, text ),_showAllFiles(false),
|
||||
#if defined(_STORAGE_rpg)
|
||||
_topCount(4),_topuSD(1),_topSlot2(2),_topFavorites(3)
|
||||
#elif defined(_STORAGE_r4) || defined(_STORAGE_ak2i) || defined(_STORAGE_r4idsn)
|
||||
_topCount(3),_topuSD(0),_topSlot2(1),_topFavorites(2)
|
||||
#endif
|
||||
{
|
||||
_viewMode = VM_LIST;
|
||||
_activeIconScale = 1;
|
||||
@ -59,7 +53,6 @@ _topCount(3),_topuSD(0),_topSlot2(1),_topFavorites(2)
|
||||
_activeIcon.update();
|
||||
animationManager().addAnimation( &_activeIcon );
|
||||
dbg_printf("_activeIcon.init\n");
|
||||
#if defined(_STORAGE_ak2i) || defined(_STORAGE_r4idsn)
|
||||
fifoSendValue32(FIFO_USER_01,MENU_MSG_SYSTEM);
|
||||
while(!fifoCheckValue32(FIFO_USER_02));
|
||||
u32 system=fifoGetValue32(FIFO_USER_02);
|
||||
@ -69,7 +62,6 @@ _topCount(3),_topuSD(0),_topSlot2(1),_topFavorites(2)
|
||||
_topSlot2=2;
|
||||
_topFavorites=1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
cMainList::~cMainList()
|
||||
@ -144,15 +136,6 @@ bool cMainList::enterDir( const std::string & dirName )
|
||||
std::vector< std::string > a_row;
|
||||
a_row.push_back( "" ); // make a space for icon
|
||||
DSRomInfo rominfo;
|
||||
#if defined(_STORAGE_rpg)
|
||||
if( 0 == i ) {
|
||||
a_row.push_back( LANG("mainlist","flash memory") );
|
||||
a_row.push_back( "" );
|
||||
a_row.push_back( "fat0:/" );
|
||||
rominfo.setBanner("nand",nand_banner_bin);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if( _topuSD == i ) {
|
||||
a_row.push_back( LANG("mainlist","microsd card") );
|
||||
a_row.push_back( "" );
|
||||
@ -184,11 +167,12 @@ bool cMainList::enterDir( const std::string & dirName )
|
||||
}
|
||||
|
||||
bool favorites=("favorites:/"==dirName);
|
||||
DIR_ITER* dir=NULL;
|
||||
DIR* dir=NULL;
|
||||
struct dirent *entry;
|
||||
|
||||
if(!favorites)
|
||||
{
|
||||
dir = diropen( dirName.c_str() );
|
||||
dir = opendir( dirName.c_str() );
|
||||
|
||||
if (dir == NULL) {
|
||||
if( SD_ROOT == dirName ) {
|
||||
@ -217,10 +201,7 @@ bool cMainList::enterDir( const std::string & dirName )
|
||||
savNames.push_back( ".sav" );
|
||||
|
||||
// insert 一堆文件, 两列,一列作为显示,一列作为真实文件名
|
||||
struct stat st;
|
||||
char longFilename[MAX_FILENAME_LENGTH];
|
||||
std::string extName;
|
||||
u8 attr=0;
|
||||
|
||||
// list dir
|
||||
{
|
||||
@ -257,21 +238,20 @@ bool cMainList::enterDir( const std::string & dirName )
|
||||
}
|
||||
else if(dir)
|
||||
{
|
||||
while(dirnext(dir,longFilename,&st)==0)
|
||||
while((entry=readdir(dir))!=NULL)
|
||||
{
|
||||
attr=st.st_spare1;
|
||||
std::string lfn( longFilename );
|
||||
std::string lfn( entry->d_name );
|
||||
|
||||
// st.st_mode & S_IFDIR indicates a directory
|
||||
// entry->d_type == DT_DIR indicates a directory
|
||||
size_t lastDotPos = lfn.find_last_of( '.' );
|
||||
if( lfn.npos != lastDotPos )
|
||||
extName = lfn.substr( lastDotPos );
|
||||
else
|
||||
extName = "";
|
||||
|
||||
dbg_printf( "%s: %s %s\n", (st.st_mode & S_IFDIR ? " DIR" : "FILE"), longFilename, extName.c_str() );
|
||||
bool showThis=(st.st_mode & S_IFDIR)?(strcmp(longFilename,".")&&strcmp(longFilename,"..")):extnameFilter( extNames, extName );
|
||||
showThis=showThis&&(_showAllFiles||gs().showHiddenFiles||!(attr&ATTRIB_HID));
|
||||
dbg_printf( "%s: %s %s\n", (entry->d_type == DT_DIR ? " DIR" : "FILE"), entry->d_name, extName.c_str() );
|
||||
bool showThis=(entry->d_type == DT_DIR)?(strcmp(entry->d_name,".")&&strcmp(entry->d_name,"..")):extnameFilter( extNames, extName );
|
||||
showThis=showThis&&(_showAllFiles||gs().showHiddenFiles||!(FAT_getAttr(entry->d_name) & ATTR_HIDDEN));
|
||||
|
||||
// 如果有后缀名,或者是个目录,就push进去
|
||||
if(showThis) {
|
||||
@ -282,7 +262,7 @@ bool cMainList::enterDir( const std::string & dirName )
|
||||
a_row.push_back( "" ); // make a space for internal name
|
||||
|
||||
a_row.push_back(dirName+lfn); //real name
|
||||
if( st.st_mode & S_IFDIR ) {
|
||||
if( entry->d_type == DT_DIR ) {
|
||||
a_row[SHOWNAME_COLUMN] += "/";
|
||||
a_row[REALNAME_COLUMN] += "/";
|
||||
}
|
||||
@ -297,7 +277,7 @@ bool cMainList::enterDir( const std::string & dirName )
|
||||
_saves.push_back(dirName+lfn);
|
||||
}
|
||||
}
|
||||
dirclose( dir );
|
||||
closedir( dir );
|
||||
}
|
||||
std::sort( _rows.begin(), _rows.end(), itemSortComp );
|
||||
std::sort(_saves.begin(),_saves.end(),stringComp);
|
||||
@ -379,7 +359,7 @@ void cMainList::backParentDir()
|
||||
return;
|
||||
|
||||
bool fat1=(SD_ROOT==_currentDir),favorites=("favorites:/"==_currentDir);
|
||||
if( "fat0:/" == _currentDir || fat1 || favorites || "/" == _currentDir ) {
|
||||
if( "fat:/" == _currentDir || fat1 || favorites || "/" == _currentDir ) {
|
||||
enterDir( "..." );
|
||||
if(fat1) selectRow(_topuSD);
|
||||
if(favorites) selectRow(_topFavorites);
|
||||
|
@ -29,11 +29,7 @@
|
||||
#include "dsrom.h"
|
||||
#include "zoomingicon.h"
|
||||
|
||||
#if defined(_STORAGE_rpg)
|
||||
#define SD_ROOT_0 "fat1:"
|
||||
#else
|
||||
#define SD_ROOT_0 "fat0:"
|
||||
#endif
|
||||
#define SD_ROOT_0 "fat:"
|
||||
#define SD_ROOT SD_ROOT_0"/"
|
||||
|
||||
// 显示游戏列表,文件列表等等
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include "msgbox.h"
|
||||
#include "systemfilenames.h"
|
||||
#include "timer.h"
|
||||
#include "../../share/timetool.h"
|
||||
#include "timetool.h"
|
||||
#include "../../share/fifotool.h"
|
||||
|
||||
#include "testcases.h"
|
||||
@ -32,7 +32,6 @@
|
||||
|
||||
#include "romloader.h"
|
||||
#include "progresswnd.h"
|
||||
#include "files.h"
|
||||
#include "inifile.h"
|
||||
#include "language.h"
|
||||
#include "testcases.h"
|
||||
@ -41,15 +40,11 @@
|
||||
#include "expwnd.h"
|
||||
#include "gbaloader.h"
|
||||
#include "romlauncher.h"
|
||||
#include "sdidentify.h"
|
||||
#include "favorites.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "iocmn.h"
|
||||
#endif
|
||||
|
||||
#include <dirent.h>
|
||||
#include <sys/iosupport.h>
|
||||
#include <elm.h>
|
||||
#include <fat.h>
|
||||
|
||||
using namespace akui;
|
||||
|
||||
@ -96,7 +91,7 @@ void cMainWnd::init()
|
||||
_mainList->selectedRowHeadClicked.connect( this, &cMainWnd::onMainListSelItemHeadClicked );
|
||||
_mainList->directoryChanged.connect( this, &cMainWnd::onFolderChanged );
|
||||
_mainList->animateIcons.connect( this, &cMainWnd::onAnimation );
|
||||
//_mainList->enterDir( "fat0:/" );
|
||||
//_mainList->enterDir( "fat:/" );
|
||||
addChildWindow( _mainList );
|
||||
dbg_printf( "mainlist %08x\n", _mainList );
|
||||
|
||||
@ -200,64 +195,7 @@ void cMainWnd::startMenuItemClicked( s16 i )
|
||||
dbg_printf( "start menu item %d\n", i );
|
||||
//messageBox( this, "Power Off", "Are you sure you want to turn off ds?", MB_YES | MB_NO );
|
||||
|
||||
if( START_MENU_ITEM_COPY == i ) {
|
||||
if( "" == _mainList->getSelectedFullPath() )
|
||||
return;
|
||||
struct stat st;
|
||||
stat( _mainList->getSelectedFullPath().c_str(), &st );
|
||||
if( st.st_mode & S_IFDIR ) {
|
||||
messageBox( this, LANG("no copy dir", "title"), LANG("no copy dir", "text"), MB_YES | MB_NO );
|
||||
return;
|
||||
}
|
||||
setSrcFile( _mainList->getSelectedFullPath(), SFM_COPY );
|
||||
}
|
||||
|
||||
else if( START_MENU_ITEM_CUT == i ) {
|
||||
if( "" == _mainList->getSelectedFullPath() )
|
||||
return;
|
||||
struct stat st;
|
||||
stat( _mainList->getSelectedFullPath().c_str(), &st );
|
||||
if( st.st_mode & S_IFDIR ) {
|
||||
messageBox( this, LANG("no copy dir", "title"), LANG("no copy dir", "text"), MB_YES | MB_NO );
|
||||
return;
|
||||
}
|
||||
setSrcFile( _mainList->getSelectedFullPath(), SFM_CUT );
|
||||
}
|
||||
|
||||
else if( START_MENU_ITEM_PASTE == i )
|
||||
{
|
||||
bool ret=false;
|
||||
if(_mainList->IsFavorites())
|
||||
{
|
||||
ret=cFavorites::AddToFavorites(getSrcFile());
|
||||
}
|
||||
else
|
||||
{
|
||||
ret=copyOrMoveFile(_mainList->getCurrentDir());
|
||||
}
|
||||
if(ret) // refresh current directory
|
||||
_mainList->enterDir(_mainList->getCurrentDir());
|
||||
}
|
||||
|
||||
else if( START_MENU_ITEM_DELETE == i ) {
|
||||
std::string fullPath = _mainList->getSelectedFullPath();
|
||||
if( "" != fullPath )
|
||||
{
|
||||
bool ret=false;
|
||||
if(_mainList->IsFavorites())
|
||||
{
|
||||
ret=cFavorites::RemoveFromFavorites(fullPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret=deleteFile(fullPath);
|
||||
}
|
||||
if(ret)
|
||||
_mainList->enterDir(_mainList->getCurrentDir());
|
||||
}
|
||||
}
|
||||
|
||||
else if( START_MENU_ITEM_SETTING == i ) {
|
||||
if( START_MENU_ITEM_SETTING == i ) {
|
||||
showSettings();
|
||||
}
|
||||
|
||||
@ -389,18 +327,7 @@ bool cMainWnd::processKeyMessage( const cKeyMessage & msg )
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(_STORAGE_rpg)
|
||||
const std::string dir = _mainList->getCurrentDir();
|
||||
if( dir.length() < 5 ) {
|
||||
_mainList->enterDir( "fat0:/" );
|
||||
} else if( dir.substr( 0, 5 ) == "fat0:" ) {
|
||||
_mainList->enterDir( "fat1:/" );
|
||||
} else {
|
||||
_mainList->enterDir( "fat0:/" );
|
||||
}
|
||||
#elif defined(_STORAGE_r4) || defined(_STORAGE_ak2i) || defined(_STORAGE_r4idsn)
|
||||
_mainList->enterDir( "favorites:/" );
|
||||
#endif
|
||||
}
|
||||
ret = true;
|
||||
break;
|
||||
@ -463,12 +390,6 @@ bool cMainWnd::processTouchMessage( const cTouchMessage & msg )
|
||||
void cMainWnd::onKeyYPressed()
|
||||
{
|
||||
if(gs().safeMode) return;
|
||||
#ifdef DEBUG
|
||||
// hardware version check
|
||||
{
|
||||
dbg_printf("HW: %02x\n",ioVersion());
|
||||
}
|
||||
#endif//#ifdef DEBUG
|
||||
showFileInfo();
|
||||
}
|
||||
|
||||
@ -517,26 +438,6 @@ void cMainWnd::launchSelected()
|
||||
std::string title,text; bool show=true;
|
||||
switch(launchRom(fullPath,rominfo,rominfo.isHomebrew()&&"akmenu4.nds"==_mainList->getSelectedShowName()))
|
||||
{
|
||||
#if defined(_STORAGE_rpg)
|
||||
case ELaunchSDOnly:
|
||||
title=LANG("sd save","title");
|
||||
text=LANG("sd save","text");
|
||||
break;
|
||||
case ELaunchRestoreFail:
|
||||
title=LANG("restore save fail","title");
|
||||
text=LANG("restore save fail","text");
|
||||
break;
|
||||
#endif
|
||||
#if defined(_STORAGE_rpg) || defined(_STORAGE_ak2i)
|
||||
case ELaunchSlowSD:
|
||||
{
|
||||
std::string model=sdidGetSDManufacturerName()+" "+sdidGetSDName();
|
||||
title=LANG("unsupported sd","title");
|
||||
text=LANG("unsupported sd","text");
|
||||
text=formatString(text.c_str(),model.c_str());
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case ELaunchNoFreeSpace:
|
||||
title=LANG("no free space","title");
|
||||
text=LANG("no free space","text");
|
||||
@ -564,17 +465,16 @@ void cMainWnd::setParam(void)
|
||||
//user interface style
|
||||
_values.clear();
|
||||
std::vector<std::string> uiNames;
|
||||
DIR_ITER* dir=diropen(SFN_UI_DIRECTORY);
|
||||
DIR* dir=opendir(SFN_UI_DIRECTORY);
|
||||
struct dirent *entry;
|
||||
if(NULL!=dir)
|
||||
{
|
||||
struct stat st;
|
||||
char longFilename[MAX_FILENAME_LENGTH];
|
||||
while(dirnext(dir,longFilename,&st)==0)
|
||||
while((entry=readdir(dir))!=NULL)
|
||||
{
|
||||
std::string lfn(longFilename);
|
||||
std::string lfn(entry->d_name);
|
||||
if(lfn!=".."&&lfn!=".") _values.push_back(lfn);
|
||||
}
|
||||
dirclose(dir);
|
||||
closedir(dir);
|
||||
dir=NULL;
|
||||
}
|
||||
else
|
||||
@ -584,7 +484,7 @@ void cMainWnd::setParam(void)
|
||||
std::sort(_values.begin(),_values.end());
|
||||
for(size_t ii=0;ii<_values.size();++ii)
|
||||
{
|
||||
if(0==stricmp(_values[ii].c_str(),gs().uiName.c_str())) uiIndex=ii;
|
||||
if(0==strcasecmp(_values[ii].c_str(),gs().uiName.c_str())) uiIndex=ii;
|
||||
}
|
||||
uiNames=_values;
|
||||
settingWnd.addSettingItem(LANG("ui style","text"),_values,uiIndex);
|
||||
@ -592,17 +492,15 @@ void cMainWnd::setParam(void)
|
||||
//language
|
||||
_values.clear();
|
||||
std::vector<std::string> langNames;
|
||||
dir=diropen(SFN_LANGUAGE_DIRECTORY);
|
||||
dir=opendir(SFN_LANGUAGE_DIRECTORY);
|
||||
if(NULL!=dir )
|
||||
{
|
||||
struct stat st;
|
||||
char longFilename[MAX_FILENAME_LENGTH];
|
||||
while(dirnext(dir,longFilename,&st)==0)
|
||||
while ((entry=readdir(dir))!=NULL)
|
||||
{
|
||||
std::string lfn(longFilename);
|
||||
std::string lfn(entry->d_name);
|
||||
if(lfn!=".."&&lfn!=".") _values.push_back(lfn);
|
||||
}
|
||||
dirclose(dir);
|
||||
closedir(dir);
|
||||
dir=NULL;
|
||||
}
|
||||
else
|
||||
@ -612,7 +510,7 @@ void cMainWnd::setParam(void)
|
||||
std::sort(_values.begin(),_values.end());
|
||||
for(size_t ii=0;ii<_values.size();++ii)
|
||||
{
|
||||
if(0==stricmp(_values[ii].c_str(),gs().langDirectory.c_str())) langIndex=ii;
|
||||
if(0==strcasecmp(_values[ii].c_str(),gs().langDirectory.c_str())) langIndex=ii;
|
||||
}
|
||||
langNames=_values;
|
||||
settingWnd.addSettingItem(LANG("language","text"),_values,langIndex);
|
||||
@ -682,12 +580,6 @@ void cMainWnd::setParam(void)
|
||||
settingWnd.addSettingItem(LANG("patches","cheating system"),_values,gs().cheats);
|
||||
settingWnd.addSettingItem(LANG("patches","reset in game"),_values,gs().softreset);
|
||||
settingWnd.addSettingItem(LANG("patches","homebrew reset"),_values,gs().homebrewreset);
|
||||
#if defined(_STORAGE_rpg) || defined(_STORAGE_ak2i)
|
||||
settingWnd.addSettingItem(LANG("patches","dma"),_values,gs().dma);
|
||||
#endif
|
||||
#if defined(_STORAGE_rpg)
|
||||
settingWnd.addSettingItem(LANG("patches","sd save"),_values,gs().sdsave);
|
||||
#endif
|
||||
|
||||
//page 5: gba
|
||||
settingWnd.addSettingTab(LANG("gba settings","title"));
|
||||
@ -737,12 +629,6 @@ void cMainWnd::setParam(void)
|
||||
gs().cheats=settingWnd.getItemSelection(3,0);
|
||||
gs().softreset=settingWnd.getItemSelection(3,1);
|
||||
gs().homebrewreset=settingWnd.getItemSelection(3,2);
|
||||
#if defined(_STORAGE_rpg) || defined(_STORAGE_ak2i)
|
||||
gs().dma=settingWnd.getItemSelection(3,3);
|
||||
#endif
|
||||
#if defined(_STORAGE_rpg)
|
||||
gs().sdsave=settingWnd.getItemSelection(3,4);
|
||||
#endif
|
||||
|
||||
//page 5: gba
|
||||
gs().gbaSleepHack=settingWnd.getItemSelection(4,0);
|
||||
@ -758,16 +644,7 @@ void cMainWnd::setParam(void)
|
||||
gs().uiName = uiNames[uiIndexAfter];
|
||||
gs().langDirectory = langNames[langIndexAfter];
|
||||
gs().saveSettings();
|
||||
#if defined(_STORAGE_rpg)
|
||||
loadRom( "fat0:/akmenu4.nds", 0, 0, 0 );
|
||||
#elif defined(_STORAGE_r4)
|
||||
loadRom( "fat0:/_ds_menu.dat", "", 0, 0, 0 );
|
||||
#elif defined(_STORAGE_ak2i)
|
||||
loadRom( "fat0:/akmenu4.nds", "", 0, 0, 0 );
|
||||
#elif defined(_STORAGE_r4idsn)
|
||||
loadRom( "fat0:/_dsmenu.dat", "", 0, 0, 0 );
|
||||
#endif
|
||||
|
||||
loadRom( "fat:/akmenu4.nds", "", 0, 0, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
@ -781,15 +658,7 @@ void cMainWnd::setParam(void)
|
||||
{
|
||||
gs().langDirectory = langNames[langIndexAfter];
|
||||
gs().saveSettings();
|
||||
#if defined(_STORAGE_rpg)
|
||||
loadRom( "fat0:/akmenu4.nds", 0, 0, 0 );
|
||||
#elif defined(_STORAGE_r4)
|
||||
loadRom( "fat0:/_ds_menu.dat", "", 0, 0, 0 );
|
||||
#elif defined(_STORAGE_ak2i)
|
||||
loadRom( "fat0:/akmenu4.nds", "", 0, 0, 0 );
|
||||
#elif defined(_STORAGE_r4idsn)
|
||||
loadRom( "fat0:/_dsmenu.dat", "", 0, 0, 0 );
|
||||
#endif
|
||||
loadRom( "fat:/akmenu4.nds", "", 0, 0, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
@ -840,11 +709,6 @@ void cMainWnd::onFolderChanged()
|
||||
{
|
||||
resetInputIdle();
|
||||
std::string dirShowName = _mainList->getCurrentDir();
|
||||
#if defined(_STORAGE_rpg)
|
||||
if( dirShowName.substr( 0, 5 ) == "fat0:" )
|
||||
dirShowName.replace( 0, 4, "Flash" );
|
||||
else
|
||||
#endif
|
||||
if( dirShowName.substr( 0, 5 ) == SD_ROOT_0 )
|
||||
dirShowName.replace( 0, 4, "SD" );
|
||||
else if( "favorites:/" != dirShowName && "slot2:/" == _mainList->getSelectedFullPath() )
|
||||
@ -878,11 +742,7 @@ void cMainWnd::onFolderChanged()
|
||||
}
|
||||
if(mode==cGlobalSettings::ESlot2Nds)
|
||||
{
|
||||
#if defined(_STORAGE_rpg)
|
||||
loadRom("slot2:/",0,0,0);
|
||||
#elif defined(_STORAGE_r4) || defined(_STORAGE_ak2i) || defined(_STORAGE_r4idsn)
|
||||
loadRom("slot2:/","",0,0,0);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
padding.s
|
||||
Copyright (C) 2010 yellow wood goblin
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.arch armv5te
|
||||
.cpu arm946e-s
|
||||
.section .pad,"ax",%progbits
|
||||
.align 2
|
||||
.arm
|
||||
#if defined(_STORAGE_r4idsn)
|
||||
ldr pc, target
|
||||
target:
|
||||
.word 0x02000450
|
||||
#endif
|
||||
.end
|
@ -27,7 +27,6 @@
|
||||
#include "uisettings.h"
|
||||
#include "language.h"
|
||||
#include "unicode.h"
|
||||
#include "files.h"
|
||||
#include "gbaloader.h"
|
||||
#include "cheatwnd.h"
|
||||
#include "ui/binaryfind.h"
|
||||
@ -229,21 +228,6 @@ static std::string getFriendlyFileSizeString( u64 size )
|
||||
return fileSize+sizeUnit;
|
||||
}
|
||||
|
||||
void cRomInfoWnd::setDiskInfo(void)
|
||||
{
|
||||
u64 total = 0;
|
||||
u64 used = 0;
|
||||
u64 freeSpace = 0;
|
||||
|
||||
if( !getDiskSpaceInfo( _fullName, total, used, freeSpace ) )
|
||||
return;
|
||||
|
||||
_filenameText = formatString( LANG("disk info", "total").c_str(), getFriendlyFileSizeString(total).c_str() );
|
||||
_fileDateText = formatString( LANG("disk info", "used").c_str(), getFriendlyFileSizeString(used).c_str() );
|
||||
_fileSizeText = formatString( LANG("disk info", "free").c_str(), getFriendlyFileSizeString(freeSpace).c_str() );
|
||||
|
||||
}
|
||||
|
||||
void cRomInfoWnd::setFileInfo( const std::string & fullName, const std::string & showName )
|
||||
{
|
||||
_fullName=fullName;
|
||||
@ -258,8 +242,7 @@ void cRomInfoWnd::setFileInfo( const std::string & fullName, const std::string &
|
||||
return;
|
||||
}
|
||||
|
||||
if( "fat0:/" == fullName || "fat1:/" == fullName ) {
|
||||
setDiskInfo();
|
||||
if( "fat:/" == fullName ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -339,21 +322,6 @@ void cRomInfoWnd::onShow()
|
||||
centerScreen();
|
||||
}
|
||||
|
||||
#if defined(_STORAGE_rpg)
|
||||
#define ITEM_SAVETYPE 0,0
|
||||
#define ITEM_DOWNLOADPLAY 0,1
|
||||
#define ITEM_DMA 0,2
|
||||
#define ITEM_PROTECTION 0,3
|
||||
#define ITEM_LINKAGE 0,4
|
||||
#define ITEM_RUMBLE 0,5
|
||||
|
||||
#define ITEM_CHEATS 1,0
|
||||
#define ITEM_SOFTRESET 1,1
|
||||
#define ITEM_SDSAVE 1,2
|
||||
#define ITEM_SAVESLOT 1,3
|
||||
#define ITEM_ICON 1,4
|
||||
#define ITEM_LANGUAGE 1,5
|
||||
#elif defined(_STORAGE_r4) || defined(_STORAGE_r4idsn)
|
||||
#define ITEM_SAVETYPE 0,0
|
||||
#define ITEM_LINKAGE 0,1
|
||||
#define ITEM_RUMBLE 0,2
|
||||
@ -363,20 +331,6 @@ void cRomInfoWnd::onShow()
|
||||
#define ITEM_SAVESLOT 1,2
|
||||
#define ITEM_ICON 1,3
|
||||
#define ITEM_LANGUAGE 1,4
|
||||
#elif defined(_STORAGE_ak2i)
|
||||
#define ITEM_SAVETYPE 0,0
|
||||
#define ITEM_DOWNLOADPLAY 0,1
|
||||
#define ITEM_DMA 0,2
|
||||
#define ITEM_PROTECTION 0,3
|
||||
#define ITEM_LINKAGE 0,4
|
||||
#define ITEM_RUMBLE 0,5
|
||||
|
||||
#define ITEM_CHEATS 1,0
|
||||
#define ITEM_SOFTRESET 1,1
|
||||
#define ITEM_SAVESLOT 1,2
|
||||
#define ITEM_ICON 1,3
|
||||
#define ITEM_LANGUAGE 1,4
|
||||
#endif
|
||||
|
||||
void cRomInfoWnd::pressSaveType(void)
|
||||
{
|
||||
@ -398,25 +352,9 @@ void cRomInfoWnd::pressSaveType(void)
|
||||
_values.push_back( LANG("save type", "64M" ) );
|
||||
settingWnd.addSettingItem( LANG("save type", "text" ), _values, cSaveManager::SaveTypeToDisplaySaveType((SAVE_TYPE)_romInfo.saveInfo().saveType) );
|
||||
|
||||
#if defined(_STORAGE_rpg) || defined(_STORAGE_ak2i)
|
||||
_values.clear();
|
||||
_values.push_back( LANG("switches", "Disable" ) );
|
||||
_values.push_back( LANG("switches", "Enable" ) );
|
||||
settingWnd.addSettingItem( LANG("patches", "download play" ), _values, _romInfo.saveInfo().getDownloadPlay() );
|
||||
|
||||
_values.clear();
|
||||
_values.push_back( LANG("switches", "Disable" ) );
|
||||
_values.push_back( LANG("switches", "Enable" ) );
|
||||
_values.push_back(formatString(LANG("switches","Global").c_str(),gs().dma?LANG("switches","Enable").c_str():LANG("switches","Disable").c_str()));
|
||||
settingWnd.addSettingItem( LANG("patches", "dma" ), _values, _romInfo.saveInfo().getDMA() );
|
||||
#endif
|
||||
|
||||
_values.clear();
|
||||
_values.push_back( LANG("switches", "Disable" ) );
|
||||
_values.push_back( LANG("switches", "Enable" ) );
|
||||
#if defined(_STORAGE_rpg) || defined(_STORAGE_ak2i)
|
||||
settingWnd.addSettingItem( LANG("patches", "protection" ), _values, _romInfo.saveInfo().getProtection() );
|
||||
#endif
|
||||
settingWnd.addSettingItem( LANG("patches", "linkage" ), _values, _romInfo.saveInfo().getLinkage() );
|
||||
|
||||
_values.clear();
|
||||
@ -440,14 +378,6 @@ void cRomInfoWnd::pressSaveType(void)
|
||||
_values.push_back(formatString(LANG("switches","Global").c_str(),gs().softreset?LANG("switches","Enable").c_str():LANG("switches","Disable").c_str()));
|
||||
settingWnd.addSettingItem( LANG("patches", "reset in game" ), _values, _romInfo.saveInfo().getSoftReset() );
|
||||
|
||||
#if defined(_STORAGE_rpg)
|
||||
_values.clear();
|
||||
_values.push_back( LANG("switches", "Disable" ) );
|
||||
_values.push_back( LANG("switches", "Enable" ) );
|
||||
_values.push_back(formatString(LANG("switches","Global").c_str(),gs().sdsave?LANG("switches","Enable").c_str():LANG("switches","Disable").c_str()));
|
||||
settingWnd.addSettingItem( LANG("patches", "sd save" ), _values, _romInfo.saveInfo().getSDSave() );
|
||||
#endif
|
||||
|
||||
_values.clear();
|
||||
std::string slotValue;
|
||||
for(size_t ii=0;ii<4;++ii)
|
||||
@ -476,7 +406,6 @@ void cRomInfoWnd::pressSaveType(void)
|
||||
settingWnd.addSettingItem( LANG("language", "text" ), _values, _romInfo.saveInfo().getLanguage() );
|
||||
|
||||
_settingWnd = &settingWnd;
|
||||
settingWnd.addYButton(LANG("rom info","copy slot"),this,&cRomInfoWnd::pressCopySlot);
|
||||
|
||||
u32 ret = settingWnd.doModal();
|
||||
_settingWnd = NULL;
|
||||
@ -494,70 +423,21 @@ void cRomInfoWnd::pressSaveType(void)
|
||||
_romInfo.saveInfo().setFlags
|
||||
(
|
||||
settingWnd.getItemSelection(ITEM_RUMBLE),
|
||||
#if defined(_STORAGE_rpg) || defined(_STORAGE_ak2i)
|
||||
settingWnd.getItemSelection(ITEM_DOWNLOADPLAY),
|
||||
#elif defined(_STORAGE_r4) || defined(_STORAGE_r4idsn)
|
||||
0,
|
||||
#endif
|
||||
settingWnd.getItemSelection(ITEM_SOFTRESET),
|
||||
settingWnd.getItemSelection(ITEM_CHEATS),
|
||||
settingWnd.getItemSelection(ITEM_SAVESLOT),
|
||||
#if defined(_STORAGE_rpg) || defined(_STORAGE_ak2i)
|
||||
settingWnd.getItemSelection(ITEM_DMA),
|
||||
settingWnd.getItemSelection(ITEM_PROTECTION),
|
||||
#elif defined(_STORAGE_r4) || defined(_STORAGE_r4idsn)
|
||||
2,
|
||||
0,
|
||||
#endif
|
||||
settingWnd.getItemSelection(ITEM_LINKAGE),
|
||||
settingWnd.getItemSelection(ITEM_ICON),
|
||||
#if defined(_STORAGE_rpg)
|
||||
settingWnd.getItemSelection(ITEM_SDSAVE),
|
||||
#elif defined(_STORAGE_r4) || defined(_STORAGE_ak2i) || defined(_STORAGE_r4idsn)
|
||||
2,
|
||||
#endif
|
||||
settingWnd.getItemSelection(ITEM_LANGUAGE)
|
||||
);
|
||||
|
||||
saveManager().updateCustomSaveList( _romInfo.saveInfo() );
|
||||
}
|
||||
|
||||
void cRomInfoWnd::pressCopySlot(void)
|
||||
{
|
||||
if(_settingWnd)
|
||||
{
|
||||
u8 slot=_settingWnd->getItemSelection(ITEM_SAVESLOT);
|
||||
std::string saveSrc=cSaveManager::generateSaveName(_fullName,slot);
|
||||
struct stat st;
|
||||
if(0==stat(saveSrc.c_str(),&st))
|
||||
{
|
||||
std::vector<std::string> values;
|
||||
std::string slotValue,srcValue;
|
||||
for(size_t ii=0;ii<4;++ii)
|
||||
{
|
||||
if(ii) slotValue='0'+ii;
|
||||
else slotValue=LANG("save type","default");
|
||||
if(slot!=ii)
|
||||
{
|
||||
if(SlotExists(ii)) slotValue+="*";
|
||||
values.push_back(slotValue);
|
||||
}
|
||||
else srcValue=slotValue;
|
||||
}
|
||||
cSettingWnd settingWnd(0,0,252,188,NULL,LANG("saveslot","title")+": "+srcValue);
|
||||
settingWnd.addSettingItem(LANG("saveslot","target slot" ),values,0);
|
||||
settingWnd.setConfirmMessage(LANG("saveslot","confirm"));
|
||||
u32 ret=settingWnd.doModal();
|
||||
if(ret==ID_CANCEL) return;
|
||||
|
||||
u8 new_slot=settingWnd.getItemSelection(0,0);
|
||||
if(new_slot>=slot) ++new_slot;
|
||||
std::string saveDst=cSaveManager::generateSaveName(_fullName,new_slot);
|
||||
copyFile(saveSrc,saveDst,false,st.st_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cRomInfoWnd::pressFlash(void)
|
||||
{
|
||||
if(_romInfo.isGbaRom())
|
||||
|
@ -59,8 +59,6 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
void setDiskInfo(void);
|
||||
|
||||
void pressFlash(void);
|
||||
|
||||
void pressSaveType(void);
|
||||
@ -69,8 +67,6 @@ protected:
|
||||
|
||||
void pressCheats(void);
|
||||
|
||||
void pressCopySlot(void);
|
||||
|
||||
bool processKeyMessage( const akui::cKeyMessage & msg );
|
||||
|
||||
void onOK();
|
||||
|
@ -16,38 +16,13 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "iocmn.h"
|
||||
#include "romlauncher.h"
|
||||
#include "../../share/flags.h"
|
||||
#include "flags.h"
|
||||
#include "language.h"
|
||||
#include "save64m.h"
|
||||
#include "exptools.h"
|
||||
#include "romloader.h"
|
||||
#include "sdidentify.h"
|
||||
#include "cheatwnd.h"
|
||||
|
||||
#if defined(_STORAGE_rpg)
|
||||
static bool OnlySDGame(u32 aGameCode)
|
||||
{
|
||||
if(0x45444759==aGameCode) //YGDE: 2209 - Diary Girl (USA)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
switch(aGameCode&0xffffff)
|
||||
{
|
||||
case 0x385959: //YY8*: 2436 - Kakushi E Mystery - Riku to Yohan - Kieta 2-mai no E (Japan)
|
||||
case 0x425841: //AXB*: 2385 - Daigassou! Band-Brothers DX (Japan)
|
||||
case 0x425855: //UXB*: 4950 - Jam with the Band (Europe) (En,Fr,De,Es,It)
|
||||
case 0x524f55: //UOR*: 3690 - Made in Ore (Japan) & 4812 - WarioWare D.I.Y. (USA) & 4913 - WarioWare - Do It Yourself (Europe) (En,Fr,De,Es,It)
|
||||
case 0x414156: //VAA*: 5054 - Eigokoro Kyoushitsu DS (Japan) (NDSi Enhanced)
|
||||
case 0x444759: //YGD*: 3453 - Winx Club - Secret Diary 2009 (Europe) (En,Fr,De,Es,It)
|
||||
case 0x565042: //BPV*: 4244 - Puzzler World (Europe) (En,Fr,De,Es,It)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static SAVE_TYPE PrefillGame(u32 aGameCode)
|
||||
{
|
||||
if(0x45444759==aGameCode) //YGDE: 2209 - Diary Girl (USA)
|
||||
@ -59,10 +34,8 @@ static SAVE_TYPE PrefillGame(u32 aGameCode)
|
||||
{
|
||||
case 0x385959: //YY8*: 2436 - Kakushi E Mystery - Riku to Yohan - Kieta 2-mai no E (Japan)
|
||||
return ST_64K;
|
||||
#if defined(_STORAGE_r4) || defined(_STORAGE_ak2i) || defined(_STORAGE_r4idsn)
|
||||
case 0x533243: //C2S*: Pokemon Mystery Dungeon - Explorers of Sky
|
||||
return ST_1M;
|
||||
#endif
|
||||
case 0x593241: //A2Y*: Ganbaru Watashi no Kakei Diary
|
||||
case 0x4c5a41: //AZL*: Nintendo Presents - Style Boutique
|
||||
case 0x494b42: //BKI*: Legend of Zelda, The - Spirit Tracks
|
||||
@ -175,9 +148,7 @@ TLaunchResult launchRom(const std::string& aFullPath,DSRomInfo& aRomInfo,bool aM
|
||||
{
|
||||
u32 flags=0;
|
||||
long cheatOffset=0; size_t cheatSize=0;
|
||||
#if defined(_STORAGE_r4) || defined(_STORAGE_ak2i) || defined(_STORAGE_r4idsn)
|
||||
std::string saveName;
|
||||
#endif
|
||||
if(!aRomInfo.isHomebrew())
|
||||
{
|
||||
u32 gameCode;
|
||||
@ -188,42 +159,10 @@ TLaunchResult launchRom(const std::string& aFullPath,DSRomInfo& aRomInfo,bool aM
|
||||
// reading speed setting
|
||||
std::string disk=aFullPath.substr(0,5);
|
||||
bool dma=false,protection=aRomInfo.saveInfo().isProtection(); u32 speed=0;
|
||||
int mount=0;
|
||||
#if defined(_STORAGE_rpg)
|
||||
if(disk=="fat0:"||disk=="FAT0:") // if we are using internal NAND flash, use fast reading setting
|
||||
{
|
||||
speed=0xd0;
|
||||
if(OnlySDGame(gameCode))
|
||||
{
|
||||
return ELaunchSDOnly;
|
||||
}
|
||||
}
|
||||
else if(disk=="fat1:"||disk=="FAT1:") // check sd card, warn user if sd card is not suitable for running offical ds program
|
||||
#endif
|
||||
{
|
||||
if(protection) speed=0x1fff;
|
||||
mount=ioSD();
|
||||
dma=aRomInfo.saveInfo().isDMA();
|
||||
#if defined(_STORAGE_rpg) || defined(_STORAGE_ak2i)
|
||||
if(dma)
|
||||
#endif
|
||||
{
|
||||
flags|=PATCH_DMA;
|
||||
}
|
||||
#if defined(_STORAGE_rpg) || defined(_STORAGE_ak2i)
|
||||
else
|
||||
{
|
||||
u32 sdSpeed=sdidCheckSDSpeed(8192);
|
||||
if(sdSpeed>=0x2000)
|
||||
{
|
||||
return ELaunchSlowSD;
|
||||
}
|
||||
else
|
||||
{
|
||||
speed=(sdSpeed&0x1fff);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
flags|=PATCH_DMA;
|
||||
/*
|
||||
if((gameCode&0xffffff)==0x425841) //2385 - Daigassou! Band-Brothers DX (Japan)
|
||||
{
|
||||
@ -248,38 +187,13 @@ TLaunchResult launchRom(const std::string& aFullPath,DSRomInfo& aRomInfo,bool aM
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_STORAGE_r4) || defined(_STORAGE_ak2i) || defined(_STORAGE_r4idsn)
|
||||
saveName=cSaveManager::generateSaveName(aFullPath,aRomInfo.saveInfo().getSlot());
|
||||
#endif
|
||||
if(isBigSave)
|
||||
{
|
||||
isBigSave=cSaveManager::initializeSaveFile(aFullPath,aRomInfo.saveInfo().getSlot(),bigSaveSize);
|
||||
if(!isBigSave) return ELaunchNoFreeSpace;
|
||||
}
|
||||
if
|
||||
(
|
||||
isBigSave
|
||||
#if defined(_STORAGE_rpg)
|
||||
&&cSave64m::GenerateSaveMap(aFullPath,aRomInfo.saveInfo().getSlot())
|
||||
#endif
|
||||
)
|
||||
{
|
||||
flags|=PATCH_SD_SAVE|(bigSaveMask<<PATCH_SAVE_SHIFT);
|
||||
#if defined(_STORAGE_rpg)
|
||||
saveManager().restoreSaveData(aFullPath.c_str(),ST_NOSAVE,aRomInfo.saveInfo().getSlot());
|
||||
if(!dma) speed=0x1fff;
|
||||
#elif defined(_STORAGE_r4)
|
||||
saveManager().saveLastInfo(aFullPath);
|
||||
if(!bigSaveMask) //MiO
|
||||
{
|
||||
if(!cSave64m::GenerateSaveMap(saveName)) return ELaunchNoFreeSpace;
|
||||
}
|
||||
#elif defined(_STORAGE_ak2i)
|
||||
saveManager().saveLastInfo(aFullPath);
|
||||
if(!dma) speed=0x1fff;
|
||||
#elif defined(_STORAGE_r4idsn)
|
||||
saveManager().saveLastInfo(aFullPath);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -296,43 +210,15 @@ TLaunchResult launchRom(const std::string& aFullPath,DSRomInfo& aRomInfo,bool aM
|
||||
saveManager().updateCustomSaveList(aRomInfo.saveInfo());
|
||||
}
|
||||
}
|
||||
#if defined(_STORAGE_rpg)
|
||||
if(ioSD()==mount&&(aRomInfo.saveInfo().isSDSave()||OnlySDGame(gameCode)))
|
||||
#endif
|
||||
if(cSaveManager::initializeSaveFile(aFullPath,aRomInfo.saveInfo().getSlot(),SaveSize(st)))
|
||||
{
|
||||
if
|
||||
(
|
||||
cSaveManager::initializeSaveFile(aFullPath,aRomInfo.saveInfo().getSlot(),SaveSize(st))
|
||||
#if defined(_STORAGE_rpg)
|
||||
&&cSave64m::GenerateSaveMap(aFullPath,aRomInfo.saveInfo().getSlot())
|
||||
#endif
|
||||
)
|
||||
{
|
||||
flags|=PATCH_SD_SAVE|(SaveMask(st)<<PATCH_SAVE_SHIFT);
|
||||
#if defined(_STORAGE_rpg)
|
||||
saveManager().restoreSaveData(aFullPath.c_str(),ST_NOSAVE,aRomInfo.saveInfo().getSlot());
|
||||
if(!dma) speed=0x1fff;
|
||||
#elif defined(_STORAGE_r4) || defined(_STORAGE_r4idsn)
|
||||
saveManager().saveLastInfo(aFullPath);
|
||||
#elif defined(_STORAGE_ak2i)
|
||||
saveManager().saveLastInfo(aFullPath);
|
||||
if(!dma) speed=0x1fff;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
return ELaunchNoFreeSpace;
|
||||
}
|
||||
flags|=PATCH_SD_SAVE|(SaveMask(st)<<PATCH_SAVE_SHIFT);
|
||||
saveManager().saveLastInfo(aFullPath);
|
||||
}
|
||||
#if defined(_STORAGE_rpg)
|
||||
else
|
||||
{
|
||||
if(!saveManager().restoreSaveData(aFullPath.c_str(),st,aRomInfo.saveInfo().getSlot()))
|
||||
{
|
||||
return ELaunchRestoreFail;
|
||||
}
|
||||
return ELaunchNoFreeSpace;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
__NDSHeader->cardControl13=0x00406000|speed;
|
||||
//3in1 support
|
||||
@ -367,16 +253,6 @@ TLaunchResult launchRom(const std::string& aFullPath,DSRomInfo& aRomInfo,bool aM
|
||||
}
|
||||
if(aRomInfo.saveInfo().isSoftReset()) flags|=PATCH_SOFT_RESET;
|
||||
if(expansion().Rampage()==cExpansion::EPsramPage) flags|=PATCH_PSRAM;
|
||||
#if defined(_STORAGE_rpg) || defined(_STORAGE_ak2i)
|
||||
if(protection)
|
||||
{
|
||||
u32 bytesPerCluster;
|
||||
if(ELM_ClusterSizeFromDisk(mount,&bytesPerCluster)&&cSaveManager::generateProtectionFix(aFullPath,bytesPerCluster))
|
||||
{
|
||||
flags|=PATCH_PROTECTION;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(aRomInfo.saveInfo().isLinkage()) flags|=PATCH_LINKAGE;
|
||||
u8 language=aRomInfo.saveInfo().getLanguage();
|
||||
if(language) flags|=(language<<PATCH_LANGUAGE_SHIFT)&PATCH_LANGUAGE_MASK;
|
||||
@ -392,11 +268,7 @@ TLaunchResult launchRom(const std::string& aFullPath,DSRomInfo& aRomInfo,bool aM
|
||||
}
|
||||
if(gs().homebrewreset) flags|=PATCH_SOFT_RESET;
|
||||
}
|
||||
#if defined(_STORAGE_rpg)
|
||||
loadRom(aFullPath,flags,cheatOffset,cheatSize);
|
||||
#elif defined(_STORAGE_r4) || defined(_STORAGE_ak2i) || defined(_STORAGE_r4idsn)
|
||||
loadRom(aFullPath,saveName,flags,cheatOffset,cheatSize);
|
||||
#endif
|
||||
return ELaunchRomOk;
|
||||
}
|
||||
|
||||
|
@ -19,20 +19,30 @@
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <nds.h>
|
||||
#include <elm.h>
|
||||
#include <fat.h>
|
||||
#include "romloader.h"
|
||||
#include "dbgtool.h"
|
||||
#include "akloader_arm7_bin.h"
|
||||
#include "akloader_arm9_bin.h"
|
||||
#include "savechip.h"
|
||||
//#include "akloader_arm7_bin.h"
|
||||
//#include "akloader_arm9_bin.h"
|
||||
#include "savemngr.h"
|
||||
#include "../../share/fifotool.h"
|
||||
#include "../../share/timetool.h"
|
||||
#include "timetool.h"
|
||||
#include "globalsettings.h"
|
||||
#if defined(_STORAGE_rpg)
|
||||
#include <iorpg.h>
|
||||
#endif
|
||||
|
||||
// FIFO_CHANNEL_BITS - number of bits used to specify the channel in a packet - default=4
|
||||
#define FIFO_CHANNEL_BITS 4
|
||||
#define FIFO_CHANNEL_SHIFT (32-FIFO_CHANNEL_BITS)
|
||||
#define FIFO_IMMEDIATEBIT_SHIFT (FIFO_CHANNEL_SHIFT-2)
|
||||
#define FIFO_IMMEDIATEBIT (1<<FIFO_IMMEDIATEBIT_SHIFT)
|
||||
#define FIFO_EXTRABIT_SHIFT (FIFO_CHANNEL_SHIFT-3)
|
||||
#define FIFO_EXTRABIT (1<<FIFO_EXTRABIT_SHIFT)
|
||||
#define FIFO_VALUE32_MASK (FIFO_EXTRABIT-1)
|
||||
|
||||
#define FIFO_PACK_VALUE32(channel, value32) \
|
||||
( ((channel)<<FIFO_CHANNEL_SHIFT) | FIFO_IMMEDIATEBIT | \
|
||||
(((value32))&FIFO_VALUE32_MASK) )
|
||||
|
||||
static void resetAndLoop()
|
||||
{
|
||||
@ -55,49 +65,27 @@ static void resetAndLoop()
|
||||
swiSoftReset();
|
||||
}
|
||||
|
||||
#if defined(_STORAGE_rpg)
|
||||
bool loadRom( const std::string & filename, u32 flags, long cheatOffset,size_t cheatSize )
|
||||
#elif defined(_STORAGE_r4) || defined(_STORAGE_ak2i) || defined(_STORAGE_r4idsn)
|
||||
bool loadRom( const std::string & filename, const std::string & savename, u32 flags, long cheatOffset,size_t cheatSize )
|
||||
#endif
|
||||
{
|
||||
#if defined(_STORAGE_rpg)
|
||||
// copy filename to sram
|
||||
ALIGN(4) u8 filenameBuffer[MAX_FILENAME_LENGTH];
|
||||
memset( filenameBuffer, 0, MAX_FILENAME_LENGTH );
|
||||
memcpy( filenameBuffer, filename.c_str(), filename.length() );
|
||||
|
||||
u32 address=SRAM_LOADING_FILENAME_START;
|
||||
ioRpgWriteSram( address, filenameBuffer, MAX_FILENAME_LENGTH );
|
||||
address+=MAX_FILENAME_LENGTH;
|
||||
ioRpgWriteSram( address, &flags, sizeof(flags) );
|
||||
address+=sizeof(u32);
|
||||
ioRpgWriteSram( address, &cheatOffset, sizeof(cheatOffset) );
|
||||
address+=sizeof(u32);
|
||||
ioRpgWriteSram( address, &cheatSize, sizeof(cheatSize) );
|
||||
#elif defined(_STORAGE_r4) || defined(_STORAGE_ak2i) || defined(_STORAGE_r4idsn)
|
||||
*(u32*)0x23fd900=flags;
|
||||
*(u32*)0x23fd904=cheatOffset;
|
||||
*(u32*)0x23fd908=cheatSize;
|
||||
memset((void*)0x23fda00,0,MAX_FILENAME_LENGTH*2);
|
||||
memset((void*)0x23fda00,0,PATH_MAX*2);
|
||||
strcpy((char*)0x23fda00,filename.c_str());
|
||||
strcpy((char*)(0x23fda00+MAX_FILENAME_LENGTH),savename.c_str());
|
||||
#endif
|
||||
strcpy((char*)(0x23fda00+PATH_MAX),savename.c_str());
|
||||
|
||||
dbg_printf( "load %s\n", filename.c_str() );
|
||||
|
||||
// copy loader's arm7 code
|
||||
memcpy( (void *)0x023FA000, akloader_arm7_bin, akloader_arm7_bin_size );
|
||||
__NDSHeader->arm7executeAddress = 0x023FA000;
|
||||
// memcpy( (void *)0x023FA000, akloader_arm7_bin, akloader_arm7_bin_size );
|
||||
__NDSHeader->arm7executeAddress = (void*)0x023FA000;
|
||||
|
||||
// copy loader's arm9 code
|
||||
memcpy( (void *)0x023c0000, akloader_arm9_bin, akloader_arm9_bin_size );
|
||||
__NDSHeader->arm9executeAddress = 0x023c0000;
|
||||
// memcpy( (void *)0x023c0000, akloader_arm9_bin, akloader_arm9_bin_size );
|
||||
__NDSHeader->arm9executeAddress = (void*)0x023c0000;
|
||||
|
||||
dbg_printf( "load done\n" );
|
||||
|
||||
ELM_Unmount();
|
||||
|
||||
resetAndLoop();
|
||||
return true;
|
||||
}
|
||||
|
@ -21,12 +21,9 @@
|
||||
#ifndef _ROMLOADER_H_
|
||||
#define _ROMLOADER_H_
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
#include <string>
|
||||
|
||||
#if defined(_STORAGE_rpg)
|
||||
bool loadRom( const std::string & filename, u32 flags, long cheatOffset,size_t cheatSize );
|
||||
#elif defined(_STORAGE_r4) || defined(_STORAGE_ak2i) || defined(_STORAGE_r4idsn)
|
||||
bool loadRom( const std::string & filename, const std::string & savename, u32 flags, long cheatOffset,size_t cheatSize );
|
||||
#endif
|
||||
|
||||
#endif//_ROMLOADER_H_
|
||||
|
@ -1,105 +0,0 @@
|
||||
/*
|
||||
save64m.cpp
|
||||
Copyright (C) 2008 somebody
|
||||
Copyright (C) 2009 yellow wood goblin
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if defined(_STORAGE_rpg) || defined(_STORAGE_r4)
|
||||
|
||||
#include "save64m.h"
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include "dbgtool.h"
|
||||
#include "../../share/memtool.h"
|
||||
#if defined(_STORAGE_rpg)
|
||||
#include "savemngr.h"
|
||||
#include <iorpg.h>
|
||||
#elif defined(_STORAGE_r4)
|
||||
#include <ior4.h>
|
||||
#endif
|
||||
|
||||
void cSave64m::IterateFileCluster(int aFileDes,u32* aFatMap)
|
||||
{
|
||||
u32 sectorsPerCluster;
|
||||
u32 shift=isSDHC()?0:9;
|
||||
if(ELM_SectorsPerClusterFromHandle(aFileDes,§orsPerCluster))
|
||||
{
|
||||
u32 cluster=1;
|
||||
while(true)
|
||||
{
|
||||
u32 sector;
|
||||
cluster=ELM_GetFAT(aFileDes,cluster,§or);
|
||||
if(!cluster) break;
|
||||
for(u32 ii=0;ii<sectorsPerCluster;ii++)
|
||||
*aFatMap++=(sector+ii)<<shift;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool cSave64m::GenerateSaveMapInternal(const char* aPath,u32* aFatMap)
|
||||
{
|
||||
int fd=open(aPath,O_RDONLY);
|
||||
if(fd<0) return false;
|
||||
IterateFileCluster(fd,aFatMap);
|
||||
close(fd);
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(_STORAGE_rpg)
|
||||
bool cSave64m::GenerateSaveMap(const std::string& aRomFilename,u8 aSlot)
|
||||
{
|
||||
bool res=false;
|
||||
u32* buffer=new u32[KMaxSave];
|
||||
fillMemory(buffer,KMaxSave*sizeof(u32),0xffffffff);
|
||||
std::string saveFilename=cSaveManager::generateSaveName(aRomFilename,aSlot);
|
||||
if(GenerateSaveMapInternal(saveFilename.c_str(),buffer))
|
||||
{
|
||||
u32 saveMapAddress=SRAM_SAVEDATA_START;
|
||||
for(u32 ii=0;ii<KMaxSave;++ii)
|
||||
{
|
||||
ioRpgWriteSram(saveMapAddress+ii*4,buffer+ii,sizeof(u32));
|
||||
}
|
||||
res=true;
|
||||
}
|
||||
delete[] buffer;
|
||||
return res;
|
||||
}
|
||||
#elif defined(_STORAGE_r4)
|
||||
bool cSave64m::GenerateSaveMap(std::string& aSaveName)
|
||||
{
|
||||
bool success=false;
|
||||
std::string result=aSaveName;
|
||||
u32* buffer=new u32[KMaxSave];
|
||||
fillMemory(buffer,KMaxSave*sizeof(u32),0xffffffff);
|
||||
if(GenerateSaveMapInternal(aSaveName.c_str(),buffer))
|
||||
{
|
||||
result+=".fix";
|
||||
int f=open(result.c_str(),O_WRONLY|O_CREAT|O_TRUNC);
|
||||
if(f>=0)
|
||||
{
|
||||
if(write(f,buffer,KMaxSave*sizeof(u32))==KMaxSave*sizeof(u32))
|
||||
{
|
||||
success=true;
|
||||
aSaveName=result;
|
||||
}
|
||||
close(f);
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
save64m.h
|
||||
Copyright (C) 2008 somebody
|
||||
Copyright (C) 2009 yellow wood goblin
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __SAVE64M_H__
|
||||
#define __SAVE64M_H__
|
||||
|
||||
#include <nds.h>
|
||||
#include <elm.h>
|
||||
|
||||
#if defined(_STORAGE_rpg) || defined(_STORAGE_r4)
|
||||
|
||||
#include <sys/iosupport.h>
|
||||
#include <string>
|
||||
|
||||
class cSave64m
|
||||
{
|
||||
private:
|
||||
enum
|
||||
{
|
||||
KMaxSave=(32*1024*1024)/512 //32 megabytes
|
||||
};
|
||||
private:
|
||||
static void IterateFileCluster(int aFileDes,u32* aFatMap);
|
||||
static bool GenerateSaveMapInternal(const char* aPath,u32* aFatMap);
|
||||
public:
|
||||
#if defined(_STORAGE_rpg)
|
||||
static bool GenerateSaveMap(const std::string& aRomFilename,u8 aSlot);
|
||||
#elif defined(_STORAGE_r4)
|
||||
static bool GenerateSaveMap(std::string& aSaveName);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,489 +0,0 @@
|
||||
/*
|
||||
savechip.cpp
|
||||
Copyright (C) 2007 Acekard, www.acekard.com
|
||||
Copyright (C) 2007-2009 somebody
|
||||
Copyright (C) 2009 yellow wood goblin
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if defined(_STORAGE_rpg)
|
||||
#include <cstring>
|
||||
#include "savechip.h"
|
||||
#include "dbgtool.h"
|
||||
#include "rpgprotocol.h"
|
||||
#include "diskicon.h"
|
||||
|
||||
#define EepromWaitBusy() while (REG_AUXSPICNT & /*BUSY*/0x80);
|
||||
|
||||
//void saveChipReadEeprom(u32 address, u8 *data, u32 length, u8 chipType);
|
||||
void saveChipWriteT1(u32 address, u8 *apData, u32 aLength, u8 chipType);
|
||||
void saveChipWriteT2(u32 address, u8 *apData, u32 aLength, u8 chipType);
|
||||
void saveChipWriteT3(u32 address, u8 *apData, u32 aLength, u8 chipType);
|
||||
|
||||
u8 saveChipCMD( u8 cmd, u32 address )
|
||||
{
|
||||
// int address=i & 1;
|
||||
u8 ret;
|
||||
int k;
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
|
||||
REG_AUXSPICNT = 0xFFFF;
|
||||
REG_AUXSPIDATA = cmd; //
|
||||
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPIDATA = (address >> 16) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPIDATA = (address >> 8) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPIDATA = (address) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
|
||||
for(k=0;k<256;k++)
|
||||
{
|
||||
ret = REG_AUXSPIDATA;
|
||||
if(ret!=0xFF)break;
|
||||
EepromWaitBusy();
|
||||
}
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
u8 saveChipReadID(int i)
|
||||
{
|
||||
int address=i & 1;
|
||||
u8 ret;
|
||||
int k;
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
|
||||
REG_AUXSPICNT = 0xFFFF;
|
||||
REG_AUXSPIDATA = 0xAB; // READ ID
|
||||
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPIDATA = (address >> 16) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPIDATA = (address >> 8) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPIDATA = (address) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
|
||||
for(k=0;k<16;k++)
|
||||
{
|
||||
ret = REG_AUXSPIDATA;
|
||||
if(ret!=0xFF)break;
|
||||
EepromWaitBusy();
|
||||
}
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
u8 saveChipGetType(void)
|
||||
{
|
||||
u8 c00;
|
||||
u8 c05;
|
||||
u8 c9f;
|
||||
u8 c03;
|
||||
|
||||
REG_EXMEMCNT &= ~0x0880; // DS Card access ARM9:bit11=0 GBA Cart access ARM9:bit7=0
|
||||
c03=saveChipCMD(0x03,0);
|
||||
c05=saveChipCMD(0x05,0);
|
||||
c9f=saveChipCMD(0x9f,0);
|
||||
c00=saveChipCMD(0x00,0);
|
||||
if((c00==0x00) && (c9f==0x00))return 0; // PassMe? 判別不可
|
||||
if((c00==0xff) && (c05==0xff) && (c9f==0xff))return -1;
|
||||
|
||||
if((c00==0xff) && (c05 & 0xFD) == 0xF0 && (c9f==0xff))return 1;
|
||||
if((c00==0xff) && (c05 & 0xFD) == 0x00 && (c9f==0xff))return 2;
|
||||
if((c00==0xff) && (c05 & 0xFD) == 0x00 && (c9f==0x00))return 3;
|
||||
if((c00==0xff) && (c05 & 0xFD) == 0x00 && (c9f==0x12))return 3; // NEW TYPE 3
|
||||
if((c00==0xff) && (c05 & 0xFD) == 0x00 && (c9f==0x13))return 3; // NEW TYPE 3+ 4Mbit
|
||||
if((c00==0xff) && (c05 & 0xFD) == 0x00 && (c9f==0x14))return 3; // NEW TYPE 3++ 8Mbit
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 saveChipSizeT3(void)
|
||||
{
|
||||
u8 c9f;
|
||||
c9f=saveChipCMD(0x9f,0);
|
||||
|
||||
if(c9f==0x12) {
|
||||
return 256*1024; // TYPE 3 2Mbit(256KByte)
|
||||
}
|
||||
if(c9f==0x13) {
|
||||
return 512*1024; // NEW TYPE 3+ 4Mbit(512KByte)
|
||||
}
|
||||
if(c9f==0x14) {
|
||||
return 1024*1204; // NEW TYPE 3++ 8Mbit(512KByte)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int saveChipSizeT2(void)
|
||||
{
|
||||
int tp=2;
|
||||
#define OFOT0 (8*1024-1) // 8KBの末端
|
||||
#define OFOT1 (2*8*1024-1) // 16KBの末端
|
||||
u8 buf1[1]; // +0k data read -> write
|
||||
u8 buf2[1]; // +8k data read -> read
|
||||
u8 buf3[1]; // +0k ~data write
|
||||
u8 buf4[1]; // +8k data new comp buf2
|
||||
saveChipRead(OFOT0,buf1,1,tp);
|
||||
saveChipRead(OFOT1,buf2,1,tp);
|
||||
buf3[0]=~buf1[0];
|
||||
saveChipWrite(OFOT0,buf3,1,tp);
|
||||
saveChipRead(OFOT1,buf4,1,tp);
|
||||
saveChipWrite(OFOT0,buf1,1,tp);
|
||||
if(buf4[0]!=buf2[0]) // +8kも書き換わっている
|
||||
{
|
||||
return 8*1024; // 8KB(64kbit)
|
||||
}
|
||||
return 64*1024; // 64KB(512kbit)
|
||||
}
|
||||
|
||||
u32 saveChipSize(int tp)
|
||||
{
|
||||
if(-1 <= tp && tp <= 3)
|
||||
{
|
||||
// -1 0 1 2 3
|
||||
// int eepsz[5]={ 0,8192, 512, 8192, 256*1024};
|
||||
int eepsz[5]={ 0,8192, 512, 64*1024, 256*1024};
|
||||
if(tp==2)
|
||||
{
|
||||
return saveChipSizeT2();
|
||||
}
|
||||
if(tp==3)
|
||||
{
|
||||
return saveChipSizeT3();
|
||||
}
|
||||
tp++;
|
||||
return eepsz[tp];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
void saveChipRead( u32 address, u8 *data, u32 length, u8 chipType )
|
||||
{
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
// REG_AUXSPICNT = 0xFFFF;
|
||||
REG_AUXSPIDATA = 0x03 | ((chipType == 1) ? address>>8<<3 : 0);
|
||||
EepromWaitBusy();
|
||||
|
||||
if (chipType == 3)
|
||||
{
|
||||
REG_AUXSPIDATA = (address >> 16) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
}
|
||||
if (chipType >= 2)
|
||||
{
|
||||
REG_AUXSPIDATA = (address >> 8) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
}
|
||||
REG_AUXSPIDATA = (address) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
|
||||
while (length > 0)
|
||||
{
|
||||
REG_AUXSPIDATA = 0;
|
||||
EepromWaitBusy();
|
||||
*data++ = REG_AUXSPIDATA;
|
||||
length--;
|
||||
}
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void saveChipWrite( u32 address, u8 *apData, u32 aLength, u8 chipType )
|
||||
{
|
||||
switch(chipType)
|
||||
{
|
||||
case 1:
|
||||
saveChipWriteT1(address,apData,aLength,chipType);
|
||||
return;
|
||||
case 2:
|
||||
saveChipWriteT2(address,apData,aLength,chipType);
|
||||
return;
|
||||
case 3:
|
||||
saveChipWriteT3(address,apData,aLength,chipType);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define T1BLOCKSZ (16)
|
||||
// TYPE1 4kbit EEPROM
|
||||
void saveChipWriteT1(u32 address, u8 *apData, u32 aLength, u8 chipType)
|
||||
{
|
||||
int i;
|
||||
u32 last=address+aLength;
|
||||
|
||||
while (address < last)
|
||||
{
|
||||
// set WEL (Write Enable Latch)
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0x06;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
|
||||
// program maximum of 16 bytes
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
// WRITE COMMAND 0x02 + A8 << 3
|
||||
REG_AUXSPIDATA = 0x02 | (address & BIT(8)) >> (8-3) ;
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPIDATA = address & 0xFF;
|
||||
EepromWaitBusy();
|
||||
|
||||
|
||||
for (i = 0; address < last && i < T1BLOCKSZ; i++, address++)
|
||||
{
|
||||
REG_AUXSPIDATA = *apData;
|
||||
EepromWaitBusy();
|
||||
apData++;
|
||||
}
|
||||
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
|
||||
// wait programming to finish
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0x05;
|
||||
EepromWaitBusy();
|
||||
|
||||
do
|
||||
{
|
||||
REG_AUXSPIDATA = 0;
|
||||
EepromWaitBusy();
|
||||
} while (REG_AUXSPIDATA & 0x01); // WIP (Write In Progress) ?
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TYPE2 64kbit EEPROM
|
||||
void saveChipWriteT2(u32 address, u8 *apData, u32 aLength, u8 chipType)
|
||||
{
|
||||
int i;
|
||||
u32 last=address+aLength;
|
||||
|
||||
while (address < last)
|
||||
{
|
||||
// set WEL (Write Enable Latch)
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0x06;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
|
||||
// program maximum of 32 bytes
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0x02;
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPIDATA = address >> 8;
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPIDATA = address & 0xFF;
|
||||
EepromWaitBusy();
|
||||
|
||||
|
||||
for (i = 0; address < last && i < 128; i++, address++)
|
||||
{
|
||||
REG_AUXSPIDATA = *apData;
|
||||
EepromWaitBusy();
|
||||
apData++;
|
||||
}
|
||||
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
|
||||
// wait programming to finish
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0x05;
|
||||
EepromWaitBusy();
|
||||
|
||||
do
|
||||
{
|
||||
REG_AUXSPIDATA = 0;
|
||||
EepromWaitBusy();
|
||||
} while (REG_AUXSPIDATA & 0x01); // WIP (Write In Progress) ?
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#define T3BLOCKSZ (256)
|
||||
// TYPE3 2Mbit FLASH MEMORY
|
||||
void saveChipWriteT3(u32 address, u8 *apData, u32 aLength, u8 chipType)
|
||||
{
|
||||
int i;
|
||||
u32 last=address+aLength;
|
||||
|
||||
while (address < last)
|
||||
{
|
||||
// set WEL (Write Enable Latch)
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0x06;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
|
||||
// program maximum of 32 bytes
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0x02;
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPIDATA = (address >> 16) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPIDATA = (address >> 8) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPIDATA = address & 0xFF;
|
||||
EepromWaitBusy();
|
||||
|
||||
|
||||
for (i = 0; address < last && i < T3BLOCKSZ; i++, address++)
|
||||
{
|
||||
REG_AUXSPIDATA = *apData;
|
||||
EepromWaitBusy();
|
||||
apData++;
|
||||
}
|
||||
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
|
||||
// wait programming to finish
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0x05;
|
||||
EepromWaitBusy();
|
||||
|
||||
do
|
||||
{
|
||||
REG_AUXSPIDATA = 0;
|
||||
EepromWaitBusy();
|
||||
} while (REG_AUXSPIDATA & 0x01); // WIP (Write In Progress) ?
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void saveChipEEPROMErase( int type )
|
||||
{
|
||||
u32 save_size = 0;
|
||||
if( 1 == type ) save_size = 512;
|
||||
if( 2 == type ) save_size = 65536;
|
||||
if( 0 == save_size )
|
||||
return ;
|
||||
u8 * buffer = new u8[save_size];
|
||||
memset( buffer, 0xff, save_size );
|
||||
saveChipWrite( 0, buffer, save_size, type );
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
// Chip Erase NEW : clear FLASH MEMORY (TYPE 3 ONLY)
|
||||
int saveChipFlashErase(u32 sectorCount)
|
||||
{
|
||||
for(u32 ii=0;ii<sectorCount;++ii)
|
||||
{
|
||||
saveChipSectorErase(0x10000*ii);
|
||||
diskIcon().blink();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// COMMAND Sec.erase 0xD8
|
||||
void saveChipSectorErase(u32 address)
|
||||
{
|
||||
// int i;
|
||||
// set WEL (Write Enable Latch)
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0x06;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
|
||||
// SectorErase 0xD8
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0xD8;
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPIDATA = (address >> 16) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPIDATA = (address >> 8) & 0xFF;
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPIDATA = address & 0xFF;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
|
||||
// wait erase to finish
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0x05;
|
||||
EepromWaitBusy();
|
||||
|
||||
do
|
||||
{
|
||||
REG_AUXSPIDATA = 0;
|
||||
EepromWaitBusy();
|
||||
} while (REG_AUXSPIDATA & 0x01); // WIP (Write In Progress) ?
|
||||
// EepromWaitBusy();
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
}
|
||||
|
||||
|
||||
// Chip Erase : clear FLASH MEMORY (TYPE 3 ONLY)
|
||||
// COMMAND 0xC7
|
||||
int saveChipFlashErase2(void)
|
||||
{
|
||||
// set WEL (Write Enable Latch)
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0x06;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
|
||||
// Chip Erase 0xC7
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0xC7;
|
||||
EepromWaitBusy();
|
||||
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
|
||||
// wait programming to finish
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
REG_AUXSPIDATA = 0x05;
|
||||
EepromWaitBusy();
|
||||
|
||||
do
|
||||
{
|
||||
REG_AUXSPIDATA = 0;
|
||||
EepromWaitBusy();
|
||||
} while (REG_AUXSPIDATA & 0x01); // WIP (Write In Progress) ?
|
||||
EepromWaitBusy();
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
#endif
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
savechip.h
|
||||
Copyright (C) 2007 Acekard, www.acekard.com
|
||||
Copyright (C) 2007-2009 somebody
|
||||
Copyright (C) 2009 yellow wood goblin
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _SAVECHIP_H_
|
||||
#define _SAVECHIP_H_
|
||||
|
||||
#include <nds.h>
|
||||
|
||||
#if defined(_STORAGE_rpg)
|
||||
enum CHIP_TYPE
|
||||
{
|
||||
CT_NONE = 0,
|
||||
CT_4K,
|
||||
CT_512K,
|
||||
CT_8M,
|
||||
CT_AUTO
|
||||
};
|
||||
|
||||
void saveChipRead( u32 address, u8 * data, u32 length, u8 chipType );
|
||||
void saveChipWrite( u32 address, u8 * data, u32 length, u8 chipType );
|
||||
void saveChipSectorErase( u32 address );
|
||||
int saveChipFlashErase(u32 sectorCount);
|
||||
void saveChipEEPROMErase( int type );
|
||||
u8 saveChipGetType();
|
||||
u32 saveChipSize( u8 chipType );
|
||||
u8 saveChipCMD( u8 cmd, u32 address );
|
||||
|
||||
#endif
|
||||
|
||||
#endif//_SAVECHIP_H_
|
@ -26,14 +26,10 @@
|
||||
#include "dbgtool.h"
|
||||
#include "systemfilenames.h"
|
||||
#include "progresswnd.h"
|
||||
#if defined(_STORAGE_rpg)
|
||||
#include "rpgprotocol.h"
|
||||
#include "nanddriver.h"
|
||||
#endif
|
||||
#include "language.h"
|
||||
#include "datetime.h"
|
||||
#include "ui.h"
|
||||
#include <elm.h>
|
||||
#include <fat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@ -41,89 +37,12 @@ using namespace akui;
|
||||
|
||||
cSaveManager::cSaveManager()
|
||||
{
|
||||
#if defined(_STORAGE_rpg)
|
||||
lockSave();
|
||||
for( size_t i = 0; i < 64; ++i ) {
|
||||
_saveBlockTable[i] = 0xFFFFFFFF;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
cSaveManager::~cSaveManager()
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(_STORAGE_rpg)
|
||||
//EEP 指令
|
||||
//D2 00 00 00 00 00 00 00
|
||||
//
|
||||
//bit 51 - 48
|
||||
//48 eep enable
|
||||
//49 eep to nand enable
|
||||
//53 - 50 0001=auto 0000=95040 1000=95640 0100=95512 0010=25pe80
|
||||
|
||||
void selectSaveChip( CHIP_TYPE type, bool nandON )
|
||||
{
|
||||
u8 byte2 = 0;
|
||||
switch( type )
|
||||
{
|
||||
case CT_NONE:
|
||||
byte2 = 0x00;
|
||||
break;
|
||||
case CT_4K:
|
||||
byte2 = 0x03; // 0000 0011
|
||||
break;
|
||||
case CT_512K:
|
||||
byte2 = 0x13; // 0001 0011
|
||||
break;
|
||||
case CT_8M:
|
||||
byte2 = 0x0b; // 0000 1011
|
||||
break;
|
||||
case CT_AUTO: // auto detect
|
||||
byte2 = 0x07; // 0000 0111
|
||||
break;
|
||||
default:
|
||||
byte2 = 0x00;
|
||||
};
|
||||
if( !nandON )
|
||||
byte2 &= 0xFD; // 1111 1101
|
||||
|
||||
u32 cmd[2] = { 0xd2000000 | (byte2 <<16 ), 0x00000000 };
|
||||
ioRpgSendCommand( cmd, 0, 0, NULL );
|
||||
}
|
||||
|
||||
|
||||
void cSaveManager::lockChips()
|
||||
{
|
||||
selectSaveChip( CT_NONE, false );
|
||||
}
|
||||
|
||||
bool cSaveManager::unlockChip(SAVE_TYPE saveType,bool writeToDisk)
|
||||
{
|
||||
CHIP_TYPE chipType=chipTypeFromSaveType(saveType);
|
||||
selectSaveChip(chipType,writeToDisk);
|
||||
|
||||
if(writeToDisk||CT_AUTO==chipType)
|
||||
{
|
||||
clearSaveBlocks();
|
||||
u32 nandAddress[64];
|
||||
if(!assignSaveBlocks(saveType,chipType,nandAddress))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void cSaveManager::lockSave()
|
||||
{
|
||||
lockChips();
|
||||
}
|
||||
|
||||
bool cSaveManager::unlockSave(SAVE_TYPE saveType,bool writeToDisk)
|
||||
{
|
||||
return unlockChip(saveType,writeToDisk);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool loadSaveList(const std::string& filename,std::vector<SAVE_INFO_EX>& buffer)
|
||||
{
|
||||
u8* data=NULL;
|
||||
@ -141,7 +60,7 @@ static bool loadSaveList(const std::string& filename,std::vector<SAVE_INFO_EX>&
|
||||
if(1!=fread(&header,sizeof(header),1,f)) break;
|
||||
if(header.marker!=SAVE_INFO_EX_HEADER_MAGIC) break;
|
||||
data=new u8[header.itemSize*header.itemCount];
|
||||
u32 copiedSize=std::min(header.itemSize,sizeof(SAVE_INFO_EX));
|
||||
u32 copiedSize=std::min((unsigned int)header.itemSize,sizeof(SAVE_INFO_EX));
|
||||
if(header.itemCount!=fread(data,header.itemSize,header.itemCount,f)) break;
|
||||
buffer.resize(header.itemCount);
|
||||
for(u32 ii=0;ii<header.itemCount;ii++)
|
||||
@ -199,11 +118,9 @@ bool cSaveManager::importSaveList( const std::string & customFile, const std::st
|
||||
|
||||
bool cSaveManager::exportCustomSaveList(const std::string& filename)
|
||||
{
|
||||
NandFast();
|
||||
int f=open(filename.c_str(),O_WRONLY|O_CREAT|O_TRUNC);
|
||||
if(f<0)
|
||||
{
|
||||
NandFlush();
|
||||
dbg_printf("fopen %s fail\n",filename.c_str());
|
||||
return false;
|
||||
}
|
||||
@ -231,7 +148,6 @@ bool cSaveManager::exportCustomSaveList(const std::string& filename)
|
||||
res=true;
|
||||
} while(false);
|
||||
close(f);
|
||||
NandFlush();
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -286,538 +202,10 @@ bool cSaveManager::clearLastInfo()
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(_STORAGE_rpg)
|
||||
SAVE_BLOCK_INFO cSaveManager::getBlockInfo( CHIP_TYPE chipType )
|
||||
{
|
||||
SAVE_BLOCK_INFO ret;
|
||||
switch( chipType )
|
||||
{
|
||||
case CT_4K:
|
||||
ret.eepPageSize = 16;
|
||||
ret.nandBlockCount = 32;
|
||||
ret.nandPageSize = 16;
|
||||
ret.saveSize = 512;
|
||||
ret.validPageCount = 1;
|
||||
break;
|
||||
case CT_512K:
|
||||
ret.eepPageSize = 128;
|
||||
ret.nandBlockCount = 32;
|
||||
ret.nandPageSize = 2048;
|
||||
ret.saveSize = 65536;
|
||||
ret.validPageCount = 1;
|
||||
break;
|
||||
case CT_8M:
|
||||
ret.eepPageSize = 256;
|
||||
ret.nandBlockCount = 64;
|
||||
ret.nandPageSize = 256;
|
||||
ret.saveSize = 1048576;
|
||||
ret.validPageCount = 64;
|
||||
break;
|
||||
case CT_NONE:
|
||||
default:
|
||||
ret.eepPageSize = 0;
|
||||
ret.nandBlockCount = 0;
|
||||
ret.nandPageSize = 0;
|
||||
ret.saveSize = 0;
|
||||
ret.validPageCount = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool cSaveManager::backupSaveData()
|
||||
{
|
||||
dbg_printf( "SaveManager::backupSaveData()\n" );
|
||||
|
||||
CHIP_TYPE autoCT = CT_NONE;
|
||||
bool buildOK = buildSaveBlockTable( &autoCT );
|
||||
if( !buildOK || CT_NONE == autoCT ) {
|
||||
clearLastInfo();
|
||||
clearSaveBlocks();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string loadLoadedFile;
|
||||
if( !loadLastInfo( loadLoadedFile ) ) {
|
||||
loadLoadedFile = "fat0:/unknown_savedata_" + datetime().getTimeStampString() + ".nds";
|
||||
}
|
||||
|
||||
// update custom savlist if needed
|
||||
DSRomInfo info;
|
||||
info.saveInfo().defaults();
|
||||
info.MayBeDSRom(loadLoadedFile);
|
||||
if( info.isDSRom() ) {
|
||||
if( ST_UNKNOWN == info.saveInfo().saveType ) {
|
||||
info.saveInfo().saveType = saveTypeFromChipType( autoCT );
|
||||
updateCustomSaveList( info.saveInfo() );
|
||||
}
|
||||
}
|
||||
|
||||
////////////////
|
||||
u8 slot=info.saveInfo().getSlot();
|
||||
loadLoadedFile=generateSaveName(loadLoadedFile,slot);
|
||||
NandFast();
|
||||
FILE * f = fopen( loadLoadedFile.c_str(), "wb" );
|
||||
if( NULL == f ) {
|
||||
if( (0 == memcmp( "fat1:/", loadLoadedFile.c_str(), 6 ) ) ) { // no sd card, backup to nand flash, and warn user
|
||||
size_t lastSlashPos = loadLoadedFile.find_last_of( '/' );
|
||||
loadLoadedFile.replace( 0, lastSlashPos + 1, "fat0:/" );
|
||||
loadLoadedFile.insert( loadLoadedFile.size() - 4, "." + datetime().getTimeStampString() );
|
||||
f = fopen( loadLoadedFile.c_str(), "wb" );
|
||||
if( NULL == f )
|
||||
{
|
||||
NandFlush();
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string warningText = formatString( LANG("no sd for save", "text").c_str(), loadLoadedFile.c_str() );
|
||||
messageBox( NULL, LANG("no sd for save", "title"), warningText, MB_OK );
|
||||
} else {
|
||||
NandFlush();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
progressWnd().setTipText( LANG("progress window", "processing save" ) );
|
||||
progressWnd().show();
|
||||
progressWnd().setPercent(0);
|
||||
SAVE_BLOCK_INFO bi = getBlockInfo( autoCT );
|
||||
if(ST_64K==info.saveInfo().saveType&&CT_512K==autoCT) bi.nandBlockCount=4;
|
||||
|
||||
#define SAVEDATA_BUFFER_SIZE (128 * 1024)
|
||||
u8 * saveDataBuffer = new u8[SAVEDATA_BUFFER_SIZE];
|
||||
static ALIGN(4) u8 readNandBuffer[2112];
|
||||
memset( saveDataBuffer, 0x5a, SAVEDATA_BUFFER_SIZE );
|
||||
u8 * pSaveDataBuffer = saveDataBuffer;
|
||||
|
||||
u32 written = 0;
|
||||
for( u32 i = 0; i < bi.nandBlockCount; ++i ) {
|
||||
u8 percent = i * 100 / bi.nandBlockCount;
|
||||
if( !(percent & 0x03) ) {
|
||||
progressWnd().setPercent( percent );
|
||||
}
|
||||
if( _saveBlockTable[i] != 0xFFFFFFFF ) {
|
||||
for( u32 j = 0; j < bi.validPageCount; ++j )
|
||||
{
|
||||
ioRpgReadNand( _saveBlockTable[i] + j * 2048, readNandBuffer, 2048 );
|
||||
memcpy( pSaveDataBuffer, readNandBuffer, bi.nandPageSize );
|
||||
pSaveDataBuffer += bi.nandPageSize;
|
||||
if( pSaveDataBuffer >= saveDataBuffer + SAVEDATA_BUFFER_SIZE ) {
|
||||
written = fwrite( saveDataBuffer, 1, SAVEDATA_BUFFER_SIZE, f );
|
||||
pSaveDataBuffer = saveDataBuffer;
|
||||
dbg_printf("written %d\n", written);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
written = fwrite( saveDataBuffer, 1, pSaveDataBuffer - saveDataBuffer, f );
|
||||
dbg_printf("written %d\n", written);
|
||||
progressWnd().setPercent( 100 );
|
||||
|
||||
progressWnd().hide();
|
||||
fclose( f );
|
||||
NandFlush();
|
||||
clearLastInfo();
|
||||
clearSaveBlocks();
|
||||
|
||||
delete[] saveDataBuffer;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void checkRedund()
|
||||
{
|
||||
ALIGN(4) u8 cfgPage[528];
|
||||
dbg_printf( "checkRedund cfgPage\n");
|
||||
ioRpgReadNand( 0x00000000, cfgPage, 528 );
|
||||
|
||||
// read zones count
|
||||
u32 totalZones = 1 << (cfgPage[0x0c] - 10);
|
||||
//wait_press_b();
|
||||
|
||||
u32 saveBlockTable[64];
|
||||
for( size_t i = 0; i < 64; ++i )
|
||||
saveBlockTable[i] = 0xFFFFFFFF;
|
||||
|
||||
ALIGN(4) u8 redundData[16];
|
||||
u8 ctByte = 0x00;
|
||||
u32 saveBlockCountCheck = 0;
|
||||
for( size_t i = 0; i < totalZones * 1024; ++i ) {
|
||||
ioRpgReadNandRedundant( (i << 17) + 512 * 3, redundData );
|
||||
if( redundData[0] != 0xff && redundData[0] != 0x00 )
|
||||
dbg_printf("(%02x%02x%02x)", redundData[1],redundData[2],redundData[3] );
|
||||
if( redundData[0] >= 0x80 && redundData[0] < 0x80 + 64 ) {
|
||||
saveBlockCountCheck++;
|
||||
u8 saveIndex = redundData[3] - 0x80;
|
||||
if( saveBlockTable[saveIndex] != 0xFFFFFFFF ) {
|
||||
dbg_printf("checkRedund() FATAL ERROR: Multi save block assign found\n");
|
||||
dbg_printf("saveTable[%d] 1=%08x 2=%08x\n", saveIndex, saveBlockTable[saveIndex], (i << 17) );
|
||||
wait_press_b();
|
||||
}
|
||||
saveBlockTable[saveIndex] = (i << 17);
|
||||
if( redundData[2] >= 0xc0 && redundData[2] <= 0xc4 && 0 == ctByte ) {
|
||||
ctByte = redundData[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( saveBlockCountCheck != 0 && saveBlockCountCheck != 16 && saveBlockCountCheck != 32 && saveBlockCountCheck != 64 )
|
||||
{
|
||||
dbg_printf("checkRedund() FATAL ERROR: saveblock COUNT ERROR %d\n", saveBlockCountCheck );
|
||||
dbg_printf("totalZones %d\n", totalZones );
|
||||
wait_press_b();
|
||||
} else {
|
||||
dbg_printf("checkRedund() OK OK OK OK OK OK OK OK OK OK OK %d\n", saveBlockCountCheck );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void clearSaveSram()
|
||||
{
|
||||
progressWnd().setTipText( LANG("progress window", "processing save") );
|
||||
progressWnd().show();
|
||||
progressWnd().setPercent( 0 );
|
||||
|
||||
// clear sram, fill with 0xff, to keep consist with empty save blocks
|
||||
u32 fillData = 0xFFFFFFFF;
|
||||
for( size_t i = 0;i < 1024 * 1024; i += 4 ) {
|
||||
ioRpgWriteSram( SRAM_SAVEDATA_START + i, &fillData, 4 );
|
||||
if( !(i % (1024 * 128)) ) {
|
||||
dbg_printf("clear sram %d%s\n", i*100/(1024*1024), "%" );
|
||||
progressWnd().setPercent( i*100 / (1024 * 1024) );
|
||||
}
|
||||
}
|
||||
for( size_t i = 0;i < 2048; i += 4 ) {
|
||||
ioRpgWriteSram( SRAM_EEP_BUFFER_START + i, &fillData, 4 );
|
||||
}
|
||||
progressWnd().setPercent(100);
|
||||
}
|
||||
|
||||
bool cSaveManager::restoreSaveData( const std::string & romFilename, SAVE_TYPE saveType, u8 slot )
|
||||
{
|
||||
dbg_printf( "SaveManager::restoreSaveData()\n" );
|
||||
|
||||
CHIP_TYPE chipType = chipTypeFromSaveType( saveType );
|
||||
if( CT_NONE == chipType ) {
|
||||
lockChips();
|
||||
saveLastInfo( romFilename );
|
||||
return true;
|
||||
}
|
||||
|
||||
unlockSave( saveType, true );
|
||||
checkRedund();
|
||||
|
||||
if( ST_UNKNOWN == saveType || ST_AUTO == saveType ) {
|
||||
clearSaveSram();
|
||||
saveLastInfo( romFilename );
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 saveSize = saveSizeFromSaveType( saveType );
|
||||
std::string saveFilename=generateSaveName(romFilename,slot);
|
||||
|
||||
//
|
||||
FILE * f = fopen( saveFilename.c_str(), "rb" );
|
||||
if( NULL == f ) {
|
||||
clearSaveSram();
|
||||
saveLastInfo( romFilename );
|
||||
return true;
|
||||
}
|
||||
|
||||
// clear FLASH
|
||||
if(saveType>=ST_2M&&saveType<=ST_8M )
|
||||
{
|
||||
switch(saveType)
|
||||
{
|
||||
case ST_2M:
|
||||
saveChipFlashErase(4);
|
||||
break;
|
||||
case ST_4M:
|
||||
saveChipFlashErase(8);
|
||||
break;
|
||||
case ST_8M:
|
||||
saveChipFlashErase(16);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const u32 blockSize = 512;
|
||||
static ALIGN(4) u8 buffer[blockSize];
|
||||
u32 readCount = 0;
|
||||
|
||||
progressWnd().setTipText( LANG("progress window", "processing save") );
|
||||
progressWnd().show();
|
||||
progressWnd().setPercent( 0 );
|
||||
for( u32 i = 0; i < saveSize; i += blockSize )
|
||||
{
|
||||
u8 percent = i * 100 / saveSize;
|
||||
if( !(percent & 0x07) )
|
||||
progressWnd().setPercent( percent );
|
||||
|
||||
u32 readed = fread( buffer, 1, blockSize, f );
|
||||
readCount += readed;
|
||||
//if( blockSize != readed ) {
|
||||
// break;
|
||||
//}
|
||||
if( 0 == readed )
|
||||
break;
|
||||
saveChipWrite( i, buffer, readed, chipType );
|
||||
}
|
||||
progressWnd().setPercent( 100 );
|
||||
progressWnd().hide();
|
||||
fclose( f );
|
||||
|
||||
saveLastInfo( romFilename );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static ALIGN(4) u8 cfgPage[528];
|
||||
bool cSaveManager::buildSaveBlockTable( CHIP_TYPE * ct )
|
||||
{
|
||||
// read cfg page
|
||||
// 53 4d 54 44 4d 47 20 00 0e 00 01 06 0d (14) 03 02
|
||||
dbg_printf( "cfgPage\n");
|
||||
ioRpgReadNand( 0x00000000, cfgPage, 528 );
|
||||
for( u32 i = 0; i < 16; ++i ) {
|
||||
dbg_printf("%02x", cfgPage[i] );
|
||||
}
|
||||
// read zones count
|
||||
u32 totalZones = 1 << (cfgPage[0x0c] - 10);
|
||||
|
||||
for( size_t i = 0; i < 64; ++i )
|
||||
_saveBlockTable[i] = 0xFFFFFFFF;
|
||||
|
||||
// if user turn power off during writting save data(in game or in menu),
|
||||
// the content of save blocks is undefined. Don't write save data to .sav
|
||||
// file if this function returns false
|
||||
ALIGN(4) u8 redundData[16];
|
||||
u8 ctByte = 0x00;
|
||||
u32 saveBlockCount = 0;
|
||||
for( size_t i = 0; i < totalZones * 1024; ++i ) {
|
||||
ioRpgReadNandRedundant( (i << 17) + 512 * 3, redundData );
|
||||
if( redundData[0] != 0xff && redundData[0] != 0x00 && redundData[0] != 0xf0 )
|
||||
dbg_printf("(%02x%02x%02x)", redundData[1],redundData[2],redundData[3] );
|
||||
|
||||
if( redundData[0] >= 0x80 && redundData[0] < 0x80 + 64 ) {
|
||||
u8 saveIndex = redundData[3] - 0x80;
|
||||
if( saveIndex < 64 ) {
|
||||
saveBlockCount++;
|
||||
if( _saveBlockTable[saveIndex] != 0xFFFFFFFF ) {
|
||||
dbg_printf("FATAL ERROR: Multi save block assign found\n");
|
||||
dbg_printf("saveTable[%d] 1=%08x 2=%08x\n", saveIndex, _saveBlockTable[saveIndex], (i << 17) );
|
||||
wait_press_b();
|
||||
return false;
|
||||
}
|
||||
_saveBlockTable[saveIndex] = (i << 17);
|
||||
if( redundData[2] >= 0xc0 && redundData[2] <= 0xc4 && 0 == ctByte ) {
|
||||
ctByte = redundData[2];
|
||||
}
|
||||
} else {
|
||||
dbg_printf("FATAL ERROR: idx err, shouldn't have a %d\n", saveIndex );
|
||||
dbg_printf("redunt0-4:(%02x%02x%02x%02x%02x)\n", redundData[0], redundData[1],
|
||||
redundData[2],redundData[3], redundData[4] );
|
||||
dbg_printf("at block: %d\n", i );
|
||||
wait_press_b();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
dbg_printf( "saveBlockCount %d\n", saveBlockCount );
|
||||
if( 0 != saveBlockCount && saveBlockCount != 16 && saveBlockCount != 32 && saveBlockCount != 64 ) {
|
||||
dbg_printf("FATAL ERROR: Multi save block assign found, saveBlockCount %d\n", saveBlockCount );
|
||||
wait_press_b();
|
||||
return false;
|
||||
}
|
||||
|
||||
*ct = CT_NONE;
|
||||
switch( ctByte ) {
|
||||
case 0xc0: // 40
|
||||
*ct = CT_4K;
|
||||
break;
|
||||
case 0xc1: // 80
|
||||
*ct = CT_8M;
|
||||
break;
|
||||
case 0xc2: // 512
|
||||
*ct = CT_512K;
|
||||
break;
|
||||
case 0xc4: // 640
|
||||
*ct = CT_512K;
|
||||
break;
|
||||
default:
|
||||
*ct = CT_NONE;
|
||||
}
|
||||
dbg_printf("save mark %02x, type %d\n", ctByte, *ct );
|
||||
//wait_press_b();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cSaveManager::clearSaveBlocks()
|
||||
{
|
||||
ioRpgReadNand( 0x00000000, cfgPage, 528 );
|
||||
for( u32 i = 0; i < 16; ++i ) {
|
||||
dbg_printf("%02x", cfgPage[i] );
|
||||
}
|
||||
// read zones count
|
||||
u32 totalZones = 1 << (cfgPage[0x0c] - 10);
|
||||
|
||||
dbg_printf("clear save: \n");
|
||||
ALIGN(4) u8 redundData[16];
|
||||
for( size_t i = 0; i < totalZones * 1024; ++i ) {
|
||||
ioRpgReadNandRedundant( (i << 17) + 512 * 3, redundData );
|
||||
if( redundData[0] >= 0x80 && redundData[0] < 0x80 + 64 ) {
|
||||
ioRpgEraseNand( i << 17 );
|
||||
}
|
||||
}
|
||||
dbg_printf( "end\n" );
|
||||
|
||||
// 这个地方是否需要重新建表?
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int cSaveManager::CompareIndex(const void* a,const void* b)
|
||||
{
|
||||
return (static_cast<const SZoneInfo*>(a)->iIndex-static_cast<const SZoneInfo*>(b)->iIndex);
|
||||
}
|
||||
|
||||
int cSaveManager::CompareFree(const void* a,const void* b)
|
||||
{
|
||||
return (static_cast<const SZoneInfo*>(a)->iFree-static_cast<const SZoneInfo*>(b)->iFree);
|
||||
}
|
||||
|
||||
bool cSaveManager::assignSaveBlocks(SAVE_TYPE saveType,CHIP_TYPE chipType,u32 nandAddress[64])
|
||||
{
|
||||
if( CT_NONE == chipType ) {
|
||||
lockChips();
|
||||
return true;
|
||||
}
|
||||
|
||||
memset( nandAddress, 0xFF, 64 * 4 );
|
||||
|
||||
ioRpgReadNand( 0x00000000, cfgPage, 528 );
|
||||
for( u32 i = 0; i < 16; ++i ) {
|
||||
dbg_printf("%02x", cfgPage[i] );
|
||||
}
|
||||
u32 neededBlocks=32;
|
||||
if(saveType==ST_8M) neededBlocks=64;
|
||||
else if(saveType==ST_2M) neededBlocks=16;
|
||||
// read zones count
|
||||
u32 totalZones = 1 << (cfgPage[0x0c] - 10);
|
||||
|
||||
SZoneInfo zones[totalZones];
|
||||
memset(zones,0,sizeof(SZoneInfo)*totalZones);
|
||||
u32 totalFreeBlocks=0,totalAllocatedBlocks=0;
|
||||
for(u32 ii=0;ii<totalZones;ii++)
|
||||
{
|
||||
zones[ii].iIndex=ii;
|
||||
zones[ii].iFree=ndCountFreeBlock(ii);
|
||||
totalFreeBlocks+=zones[ii].iFree;
|
||||
}
|
||||
if(totalFreeBlocks<neededBlocks)
|
||||
{
|
||||
dbg_printf("no needed free blocks, needed %d, free %d\n",neededBlocks,totalFreeBlocks);
|
||||
wait_press_b();
|
||||
return false;
|
||||
}
|
||||
|
||||
qsort(zones,totalZones,sizeof(SZoneInfo),CompareFree);
|
||||
for(u32 ii=0;ii<(totalZones-1);ii++)
|
||||
{
|
||||
zones[ii].iAllocated=(zones[ii].iFree*neededBlocks+totalFreeBlocks/2)/totalFreeBlocks;
|
||||
totalAllocatedBlocks+=zones[ii].iAllocated;
|
||||
}
|
||||
zones[totalZones-1].iAllocated=neededBlocks-totalAllocatedBlocks;
|
||||
qsort(zones,totalZones,sizeof(SZoneInfo),CompareIndex);
|
||||
|
||||
// 获取存档要分配的block的信息
|
||||
SAVE_BLOCK_INFO bi = getBlockInfo( chipType );
|
||||
|
||||
//u32 saveBlockPerZone = bi.nandBlockCount / totalZones;
|
||||
//u32 saveBlockPerZone = 32 / totalZones; // always assign 32 blocks (4M max), change this value to 64 will enlarge save space to 8M
|
||||
|
||||
static ALIGN(4) u8 markData[528];
|
||||
memset( markData, 0xFF, 528 );
|
||||
markData[512] = 0xBF; ///// these two bytes must be 0xbf
|
||||
markData[513] = 0xBF;
|
||||
u32 indexShift=0;
|
||||
|
||||
for(u32 ii=0;ii<totalZones;ii++)
|
||||
{
|
||||
dbg_printf("zone %d=%d,%d,%d\n",ii,zones[ii].iIndex,zones[ii].iFree,zones[ii].iAllocated);
|
||||
}
|
||||
wait_press_b();
|
||||
|
||||
for( u8 zone = 0; zone < totalZones; ++zone )
|
||||
{
|
||||
for( u8 b = 0; b < zones[zone].iAllocated; ++b )
|
||||
{
|
||||
u32 blockAddr = 0x0400;
|
||||
blockAddr = ndSearchFreeBlock( zone, true );
|
||||
if( 0x0400 == blockAddr ) {
|
||||
dbg_printf("ERROR, ZONE %d HAS NO FREE BLOCK FOR SAVE\n", zone);
|
||||
wait_press_b();
|
||||
return false;
|
||||
}
|
||||
blockAddr = (zone * 1024 + blockAddr) << 17;
|
||||
|
||||
for( size_t i = 0; i < neededBlocks; ++i ) {
|
||||
if( nandAddress[i] == blockAddr ) {
|
||||
dbg_printf("ERROR, multi assign, i=%d addr=%08x\n", i, blockAddr );
|
||||
wait_press_b();
|
||||
}
|
||||
}
|
||||
|
||||
nandAddress[ indexShift + b ] = blockAddr;
|
||||
|
||||
//ioRpgWriteSram528( SRAM_DISKBUFFER_START, markData );
|
||||
//ioRpgPageCopySramToNand( SRAM_DISKBUFFER_START, blockAddr + 512 * 3 );
|
||||
markData[515] = 0x80 + (indexShift + b);
|
||||
ioRpgWriteNand( blockAddr + 512 * 3, markData, 528 );
|
||||
}
|
||||
indexShift+=zones[zone].iAllocated;
|
||||
}
|
||||
switch(neededBlocks)
|
||||
{
|
||||
case 16:
|
||||
memcpy(nandAddress+16,nandAddress,4*16); //assign the second 16 blocks to the first 16
|
||||
case 32:
|
||||
memcpy(nandAddress+32,nandAddress,4*32); //assign the second 32 blocks to the first 32
|
||||
break;
|
||||
}
|
||||
|
||||
ioRpgWriteSram( SRAM_SAVETABLE_START, nandAddress, 4 * 64 );
|
||||
|
||||
for( size_t i = 0; i < 16; ++i ) { // print first 16 blocks for debug
|
||||
dbg_printf("savblk(%08x)", nandAddress[i] );
|
||||
}
|
||||
ioRpgSetMapTableAddress( MTN_SAVE_TABLE, SRAM_SAVETABLE_START );
|
||||
|
||||
/* IMPORTANT */
|
||||
ndBuildLUT(); // this is very necessary or lookup table system will be messed up
|
||||
|
||||
dbg_printf("CT: %d\n", chipType );
|
||||
dbg_printf("(bi.saveSize %d)", bi.saveSize );
|
||||
dbg_printf("(bi.nandBlockCount %d)", bi.nandBlockCount );
|
||||
dbg_printf("(bi.validPageCount %d)", bi.validPageCount );
|
||||
dbg_printf("(bi.eepPageSize %d)", bi.eepPageSize );
|
||||
dbg_printf("(bi.nandPageSize %d)", bi.nandPageSize );
|
||||
|
||||
//wait_press_b();
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool cSaveManager::initializeSaveFile(const std::string& romFilename,u8 slot,u32 size)
|
||||
{
|
||||
bool res=false;
|
||||
std::string saveFilename=generateSaveName(romFilename,slot);
|
||||
NandFast();
|
||||
int f=open(saveFilename.c_str(),O_WRONLY|O_CREAT);
|
||||
if(f>=0)
|
||||
{
|
||||
@ -856,60 +244,9 @@ bool cSaveManager::initializeSaveFile(const std::string& romFilename,u8 slot,u32
|
||||
}
|
||||
close(f);
|
||||
}
|
||||
NandFlush();
|
||||
return res;
|
||||
}
|
||||
|
||||
#if defined(_STORAGE_rpg) || defined(_STORAGE_ak2i)
|
||||
bool cSaveManager::generateProtectionFix(const std::string& romFilename,u32 bytesPerCluster)
|
||||
{
|
||||
bool result=false;
|
||||
std::string fixFilename(romFilename);
|
||||
fixFilename+=".fix";
|
||||
FILE* check=fopen(fixFilename.c_str(),"rb");
|
||||
if(check)
|
||||
{
|
||||
fclose(check);
|
||||
return true;
|
||||
}
|
||||
NandFast();
|
||||
FILE* rom=fopen(romFilename.c_str(),"rb");
|
||||
if(rom)
|
||||
{
|
||||
fseek(rom,0x8000,SEEK_SET);
|
||||
char buffer[512];
|
||||
if(fread(buffer,512,1,rom)==1)
|
||||
{
|
||||
FILE* fix=fopen(fixFilename.c_str(),"wb");
|
||||
if(fix)
|
||||
{
|
||||
for(int ii=0;ii<64;ii++)
|
||||
{
|
||||
if(fwrite(buffer,512,1,fix)!=1) goto error;
|
||||
}
|
||||
if(bytesPerCluster>32768)
|
||||
{
|
||||
if(fwrite(buffer,512,1,fix)!=1) goto error;
|
||||
int counter=bytesPerCluster-32768-512;
|
||||
while(counter>0)
|
||||
{
|
||||
if(fread(buffer,512,1,rom)!=1) goto error;
|
||||
if(fwrite(buffer,512,1,fix)!=1) goto error;
|
||||
counter-=512;
|
||||
}
|
||||
}
|
||||
result=true;
|
||||
error:
|
||||
fclose(fix);
|
||||
}
|
||||
}
|
||||
fclose(rom);
|
||||
}
|
||||
NandFlush();
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string cSaveManager::generateSaveName(const std::string& romFilename,u8 slot)
|
||||
{
|
||||
std::string saveFilename(romFilename);
|
||||
@ -927,68 +264,6 @@ std::string cSaveManager::generateSaveName(const std::string& romFilename,u8 slo
|
||||
return saveFilename;
|
||||
}
|
||||
|
||||
#if defined(_STORAGE_rpg)
|
||||
CHIP_TYPE cSaveManager::chipTypeFromSaveType( SAVE_TYPE saveType )
|
||||
{
|
||||
if( saveType == ST_NOSAVE )
|
||||
return CT_NONE;
|
||||
if( saveType <= ST_4K )
|
||||
return CT_4K;
|
||||
if( saveType <= ST_512K )
|
||||
return CT_512K;
|
||||
if( saveType <= ST_8M )
|
||||
return CT_8M;
|
||||
if( ST_AUTO == saveType )
|
||||
return CT_AUTO;
|
||||
|
||||
return CT_NONE;
|
||||
}
|
||||
|
||||
SAVE_TYPE cSaveManager::saveTypeFromChipType( CHIP_TYPE chipType )
|
||||
{
|
||||
switch( chipType )
|
||||
{
|
||||
case CT_4K:
|
||||
return ST_4K;
|
||||
case CT_512K:
|
||||
return ST_512K;
|
||||
case CT_8M:
|
||||
return ST_4M;
|
||||
default:
|
||||
return ST_UNKNOWN;
|
||||
}
|
||||
return ST_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
u32 cSaveManager::saveSizeFromSaveType( SAVE_TYPE saveType )
|
||||
{
|
||||
switch( saveType )
|
||||
{
|
||||
case ST_UNKNOWN:
|
||||
return 0;
|
||||
case ST_NOSAVE:
|
||||
return 0;
|
||||
case ST_4K:
|
||||
return 512;
|
||||
case ST_64K:
|
||||
return 8192;
|
||||
case ST_512K:
|
||||
return 65536;
|
||||
case ST_2M:
|
||||
return 262144;
|
||||
case ST_4M:
|
||||
return 524288;
|
||||
case ST_8M:
|
||||
return 1048576;
|
||||
case ST_NEW:
|
||||
return 2097152;
|
||||
default:
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
SAVE_TYPE cSaveManager::getSaveTypeByFile( const std::string & romFilename )
|
||||
{
|
||||
return ST_UNKNOWN;
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "singleton.h"
|
||||
#include "savechip.h"
|
||||
#include "globalsettings.h"
|
||||
|
||||
typedef struct _SAVE_INFO_T
|
||||
@ -186,17 +185,6 @@ typedef struct SAVE_INFO_EX_HEADER_T
|
||||
u32 reserved;
|
||||
} SAVE_INFO_EX_HEADER;
|
||||
|
||||
#if defined(_STORAGE_rpg)
|
||||
typedef struct _SAVE_BLOCK_INFO_T
|
||||
{
|
||||
u32 saveSize;
|
||||
u32 eepPageSize;
|
||||
u32 nandPageSize;
|
||||
u32 validPageCount;
|
||||
u32 nandBlockCount;
|
||||
} SAVE_BLOCK_INFO;
|
||||
#endif
|
||||
|
||||
class cSaveManager
|
||||
{
|
||||
public:
|
||||
@ -219,18 +207,8 @@ class cSaveManager
|
||||
|
||||
bool clearLastInfo();
|
||||
|
||||
#if defined(_STORAGE_rpg)
|
||||
bool backupSaveData();
|
||||
|
||||
bool restoreSaveData( const std::string & romFilename, SAVE_TYPE saveType, u8 slot );
|
||||
#endif
|
||||
|
||||
static bool initializeSaveFile(const std::string& romFilename,u8 slot,u32 size);
|
||||
|
||||
#if defined(_STORAGE_rpg) || defined(_STORAGE_ak2i)
|
||||
static bool generateProtectionFix(const std::string& romFilename,u32 bytesPerCluster);
|
||||
#endif
|
||||
|
||||
static std::string generateSaveName(const std::string& romFilename,u8 slot);
|
||||
|
||||
SAVE_TYPE getSaveTypeByFile( const std::string & romFilename );
|
||||
@ -240,46 +218,7 @@ class cSaveManager
|
||||
static DISPLAY_SAVE_TYPE SaveTypeToDisplaySaveType(SAVE_TYPE aSaveType);
|
||||
static SAVE_TYPE DisplaySaveTypeToSaveType(DISPLAY_SAVE_TYPE aSaveType);
|
||||
|
||||
#if defined(_STORAGE_rpg)
|
||||
void lockSave();
|
||||
|
||||
bool unlockSave( SAVE_TYPE st, bool writeToDisk );
|
||||
|
||||
bool clearSaveBlocks();
|
||||
|
||||
bool buildSaveBlockTable( CHIP_TYPE * ct );
|
||||
|
||||
protected:
|
||||
struct SZoneInfo
|
||||
{
|
||||
u32 iIndex;
|
||||
u32 iFree;
|
||||
u32 iAllocated;
|
||||
u32 iUnused;
|
||||
};
|
||||
#endif
|
||||
protected:
|
||||
|
||||
#if defined(_STORAGE_rpg)
|
||||
void lockChips();
|
||||
|
||||
bool unlockChip( SAVE_TYPE saveType, bool writeToDisk );
|
||||
|
||||
static u32 saveSizeFromSaveType( SAVE_TYPE saveType );
|
||||
|
||||
static CHIP_TYPE chipTypeFromSaveType( SAVE_TYPE saveType );
|
||||
|
||||
static SAVE_TYPE saveTypeFromChipType( CHIP_TYPE chipType );
|
||||
|
||||
static SAVE_BLOCK_INFO getBlockInfo( CHIP_TYPE chipType );
|
||||
|
||||
bool assignSaveBlocks( SAVE_TYPE saveType, CHIP_TYPE chipType, u32 nandAddress[64] );
|
||||
|
||||
static int CompareIndex(const void* a,const void* b);
|
||||
static int CompareFree(const void* a,const void* b);
|
||||
|
||||
u32 _saveBlockTable[64];
|
||||
#endif
|
||||
|
||||
std::vector<SAVE_INFO> _saveList;
|
||||
|
||||
|
@ -1,138 +0,0 @@
|
||||
/*
|
||||
sdidentify.cpp
|
||||
Copyright (C) 2007 Acekard, www.acekard.com
|
||||
Copyright (C) 2007-2009 somebody
|
||||
Copyright (C) 2009 yellow wood goblin
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "iocmn.h"
|
||||
#if defined(_STORAGE_rpg) || defined(_STORAGE_ak2i)
|
||||
#include <elm.h>
|
||||
#include "timer.h"
|
||||
#include "sdidentify.h"
|
||||
#include "irqs.h"
|
||||
#include "inifile.h"
|
||||
#include "stringtool.h"
|
||||
#include "systemfilenames.h"
|
||||
#include "language.h"
|
||||
#include "progresswnd.h"
|
||||
|
||||
std::string sdidGetSDName()
|
||||
{
|
||||
u8 sdinfo[8] = {};
|
||||
sddGetSDInfo( sdinfo );
|
||||
for( u8 i = 0; i < 5; ++i ) {
|
||||
if( ' ' ==sdinfo[i+1] )
|
||||
sdinfo[i+1] = '_';
|
||||
}
|
||||
return (const char *)(sdinfo + 1);
|
||||
|
||||
}
|
||||
|
||||
std::string sdidGetSDManufacturerID()
|
||||
{
|
||||
u8 sdinfo[8] = {};
|
||||
sddGetSDInfo( sdinfo );
|
||||
return formatString( "%02x", sdinfo[0] );
|
||||
}
|
||||
|
||||
std::string sdidGetSDManufacturerName()
|
||||
{
|
||||
CIniFile ini( SFN_SDCARD_LIST );
|
||||
u8 sdinfo[8] = {};
|
||||
sddGetSDInfo( sdinfo );
|
||||
std::string manufacturerID = formatString( "%02x", sdinfo[0] );
|
||||
std::string manufacturerName = ini.GetString( "SD Card Manufacturers", manufacturerID, manufacturerID );
|
||||
return manufacturerName;
|
||||
}
|
||||
|
||||
u32 sdidCheckSDSpeed( u32 readCount )
|
||||
{
|
||||
CIniFile ini( SFN_SDCARD_LIST );
|
||||
|
||||
std::string name = sdidGetSDName();
|
||||
std::string manufacturerID = sdidGetSDManufacturerID();
|
||||
|
||||
u32 ret = ini.GetInt( "SD Card Speed", manufacturerID + name, 0 );
|
||||
|
||||
if( ret != 0 )
|
||||
return ret;
|
||||
|
||||
u32 totalSectors;
|
||||
if(!ELM_SectorsFromDisk(ioSD(),&totalSectors))
|
||||
{
|
||||
dbg_printf("no sd card\n");
|
||||
return 0;
|
||||
}
|
||||
dbg_printf("total sectors %d, max addr %08x\n", totalSectors, (totalSectors << 9) - 0x200);
|
||||
|
||||
// some sd card needs to be readed one time for initialization
|
||||
sddReadBlocks( 0, 1, NULL );
|
||||
|
||||
irq().vblankStop();
|
||||
double maxAccessTime = 0.f;
|
||||
|
||||
std::string tipText = LANG("progress window", "first use sd");
|
||||
progressWnd().setTipText( tipText );
|
||||
progressWnd().show();
|
||||
progressWnd().setPercent( 0 );
|
||||
|
||||
vu64 tick1 = 0;
|
||||
vu64 tick2 = 0;
|
||||
for( size_t i = 0; i < readCount; ++i ) {
|
||||
u32 randAddr = ((rand() % totalSectors)<<(isSDHC()?0:9) ) & (~(0x200-1));
|
||||
|
||||
u32 sdReadSingleBlock[2] = { 0xD5030011, randAddr }; // input read address here
|
||||
ioRpgSendCommand( sdReadSingleBlock, 0, 80, NULL );
|
||||
timer().initTimer();
|
||||
tick1 = timer().getTick();
|
||||
ioRpgWaitCmdBusy( true );
|
||||
tick2 = timer().getTick();
|
||||
|
||||
u32 readSD[2] = { 0xB7000000, 0x00000000 | 0x00130000 }; // address dont care here
|
||||
ioRpgSendCommand( readSD, 512, 4, NULL );
|
||||
|
||||
if( tick2 < tick1 ) {
|
||||
tick2 += 65536;
|
||||
}
|
||||
tick1 = tick2 - tick1;
|
||||
double timeCostUs = timer().tickToUs( tick1 );
|
||||
if( timeCostUs > maxAccessTime ) {
|
||||
maxAccessTime = timeCostUs;
|
||||
}
|
||||
|
||||
u32 percent = i * 100 / readCount;
|
||||
if( (i & 0x1ff) == 0x1ff ) {
|
||||
dbg_printf( "%02d ", percent );
|
||||
progressWnd().setPercent( percent );
|
||||
}
|
||||
}
|
||||
progressWnd().hide();
|
||||
irq().vblankStart();
|
||||
|
||||
|
||||
maxAccessTime = ((u32)(maxAccessTime / 15 + 0.5)) * 15;
|
||||
|
||||
ret = ((u32)(maxAccessTime * 1000 / 150));
|
||||
|
||||
dbg_printf("max access time: max %4.2fus\n", maxAccessTime );
|
||||
|
||||
ini.SetInt( "SD Card Speed", manufacturerID + name, ret );
|
||||
ini.SaveIniFile( SFN_SDCARD_LIST );
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
sdidentify.h
|
||||
Copyright (C) 2007 Acekard, www.acekard.com
|
||||
Copyright (C) 2007-2009 somebody
|
||||
Copyright (C) 2009 yellow wood goblin
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _SDIDENTIFY_H_
|
||||
#define _SDIDENTIFY_H_
|
||||
|
||||
#include <nds.h>
|
||||
#include <string>
|
||||
|
||||
#if defined(_STORAGE_rpg) || defined(_STORAGE_ak2i)
|
||||
|
||||
std::string sdidGetSDName();
|
||||
|
||||
std::string sdidGetSDManufacturerID();
|
||||
|
||||
std::string sdidGetSDManufacturerName();
|
||||
|
||||
u32 sdidCheckSDSpeed( u32 readCount );
|
||||
|
||||
#endif
|
||||
|
||||
#endif//_SDIDENTIFY_H_
|
@ -34,8 +34,8 @@ public:
|
||||
{
|
||||
create_instance();
|
||||
//atexit( release_instance );
|
||||
// t_singleton 他自己是不会有实例的,无法利用析构函数来释放内存
|
||||
// 所以利用 atexit 来在整个程序退出时释放内存
|
||||
// t_singleton 他自己是不会有实例的,无法利用析构函数来释放内存
|
||||
// 所以利用 atexit 来在整个程序退出时释放内存
|
||||
}
|
||||
return *_instance;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <string.h>
|
||||
#include "progresswnd.h"
|
||||
#include "language.h"
|
||||
#include <elm.h>
|
||||
#include <fat.h>
|
||||
|
||||
bool cSram::SaveFileName(const char* romName,char* saveName)
|
||||
{
|
||||
@ -120,7 +120,6 @@ void cSram::SaveSramToFile(const char* romName,u16 aStartPage)
|
||||
saveFile=NULL;
|
||||
}
|
||||
NormalizeSize(saveInfo);
|
||||
NandFast();
|
||||
saveFile=fopen(saveName,"wb");
|
||||
if(saveFile)
|
||||
{
|
||||
@ -138,7 +137,6 @@ void cSram::SaveSramToFile(const char* romName,u16 aStartPage)
|
||||
progressWnd().hide();
|
||||
fclose(saveFile);
|
||||
}
|
||||
NandFlush();
|
||||
}
|
||||
|
||||
u8* cSram::SaveSramToMemory(u16 aStartPage,sSaveInfo& aSaveInfo,bool aShowProgress)
|
||||
@ -179,14 +177,12 @@ void cSram::CreateDefaultFile(const char* romName,u32 size)
|
||||
}
|
||||
else
|
||||
{
|
||||
NandFast();
|
||||
FILE* saveFile=fopen(saveName,"wb");
|
||||
if(saveFile)
|
||||
{
|
||||
fwrite(&saveInfo,sizeof(saveInfo),1,saveFile);
|
||||
fclose(saveFile);
|
||||
}
|
||||
NandFlush();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,10 +29,6 @@ using namespace akui;
|
||||
|
||||
void cStartMenu::init()
|
||||
{
|
||||
addItem( START_MENU_ITEM_COPY, LANG("start menu", "Copy") );
|
||||
addItem( START_MENU_ITEM_CUT, LANG("start menu", "Cut") );
|
||||
addItem( START_MENU_ITEM_DELETE, LANG("start menu", "Delete") );
|
||||
addItem( START_MENU_ITEM_PASTE, LANG("start menu", "Paste") );
|
||||
addItem( START_MENU_ITEM_SETTING, LANG("start menu", "Setting") );
|
||||
addItem( START_MENU_ITEM_INFO, LANG("start menu", "Info") );
|
||||
addItem( START_MENU_ITEM_HELP, LANG("start menu", "Help") );
|
||||
|
@ -23,14 +23,10 @@
|
||||
|
||||
#include "popmenu.h"
|
||||
|
||||
#define START_MENU_ITEM_COPY 0
|
||||
#define START_MENU_ITEM_CUT 1
|
||||
#define START_MENU_ITEM_DELETE 2
|
||||
#define START_MENU_ITEM_PASTE 3
|
||||
#define START_MENU_ITEM_SETTING 4
|
||||
#define START_MENU_ITEM_INFO 5
|
||||
#define START_MENU_ITEM_HELP 6
|
||||
#define START_MENU_ITEM_TOOLS 7
|
||||
#define START_MENU_ITEM_SETTING 0
|
||||
#define START_MENU_ITEM_INFO 1
|
||||
#define START_MENU_ITEM_HELP 2
|
||||
#define START_MENU_ITEM_TOOLS 3
|
||||
|
||||
class cStartMenu : public akui::cPopMenu
|
||||
{
|
||||
|
@ -21,7 +21,7 @@
|
||||
#ifndef _SYSTEMFILENAMES_H_
|
||||
#define _SYSTEMFILENAMES_H_
|
||||
|
||||
#define SFN_SYSTEM_DIR "fat0:/__rpg/"
|
||||
#define SFN_SYSTEM_DIR "fat:/__rpg/"
|
||||
#define SFN_OFFICIAL_SAVELIST SFN_SYSTEM_DIR"savelist.bin"
|
||||
#define SFN_CUSTOM_SAVELIST SFN_SYSTEM_DIR"gamedata.bin"
|
||||
#define SFN_LAST_SAVEINFO SFN_SYSTEM_DIR"lastsave.ini"
|
||||
@ -29,9 +29,7 @@
|
||||
#define SFN_SDCARD_LIST SFN_SYSTEM_DIR"sdlist.ini"
|
||||
#define SFN_GLOBAL_SETTINGS SFN_SYSTEM_DIR"globalsettings.ini"
|
||||
#define SFN_FAVORITES SFN_SYSTEM_DIR"favorites.ini"
|
||||
#if defined(_STORAGE_r4)
|
||||
#define SFN_BACKLIGHT SFN_SYSTEM_DIR"backlight.ini"
|
||||
#endif
|
||||
|
||||
#define SFN_UI_DIRECTORY SFN_SYSTEM_DIR"ui/"
|
||||
#define SFN_UI_CURRENT_DIRECTORY SFN_UI_DIRECTORY + gs().uiName + "/"
|
||||
|
@ -20,11 +20,8 @@
|
||||
|
||||
#include <nds.h>
|
||||
#include <unistd.h>
|
||||
#include <elm.h>
|
||||
#include <fat.h>
|
||||
#include <sys/iosupport.h>
|
||||
#if defined(_STORAGE_rpg)
|
||||
#include <iorpg.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#include "dbgtool.h"
|
||||
@ -38,7 +35,7 @@
|
||||
void testIni()
|
||||
{
|
||||
CIniFile ini;
|
||||
ini.LoadIniFile( "fat0:/moonshl/moonshl.ini" );
|
||||
ini.LoadIniFile( "fat:/moonshl/moonshl.ini" );
|
||||
int bright = ini.GetInt( "System", "NDSLiteDefaultBrightness", 0 );
|
||||
int WhenStandby= ini.GetInt( "BacklightTimeout", "WhenStandby", 0 );
|
||||
int WhenPicture = ini.GetInt( "BacklightTimeout", "WhenPicture", 0 );
|
||||
@ -103,18 +100,15 @@ void testUnicode()
|
||||
void testCopy()
|
||||
{
|
||||
#define CONTINUOUS_COPY_SIZE 16384
|
||||
#if defined(_STORAGE_rpg)
|
||||
ioRpgSetMapTableAddress( MTN_NAND_OFFSET1, 0 );
|
||||
#endif
|
||||
static ALIGN(4) u8 copyBuffer[CONTINUOUS_COPY_SIZE];
|
||||
|
||||
struct stat srcSt;
|
||||
if( 0 != stat( "fat0:/1Mdummy.nds", &srcSt ) ) {
|
||||
if( 0 != stat( "fat:/1Mdummy.nds", &srcSt ) ) {
|
||||
printf( "copy file error\n" );
|
||||
return;
|
||||
}
|
||||
FILE * rf = fopen( "fat0:/1Mdummy.nds", "rb" );
|
||||
FILE * wf = fopen( "fat0:/__rpg/1Mdummy.nds", "wb" );
|
||||
FILE * rf = fopen( "fat:/1Mdummy.nds", "rb" );
|
||||
FILE * wf = fopen( "fat:/__rpg/1Mdummy.nds", "wb" );
|
||||
|
||||
u32 writeCount = srcSt.st_size / CONTINUOUS_COPY_SIZE;
|
||||
if( srcSt.st_size & (CONTINUOUS_COPY_SIZE - 1) )
|
||||
@ -148,12 +142,9 @@ void testCopy()
|
||||
void testWrite()
|
||||
{
|
||||
#define CONTINUOUS_COPY_SIZE 16384
|
||||
#if defined(_STORAGE_rpg)
|
||||
ioRpgSetMapTableAddress( MTN_NAND_OFFSET1, 0 );
|
||||
#endif
|
||||
static ALIGN(4) u8 copyBuffer[CONTINUOUS_COPY_SIZE];
|
||||
|
||||
FILE * wf = fopen( "fat0:/__rpg/1mdummy2.bin", "wb" );
|
||||
FILE * wf = fopen( "fat:/__rpg/1mdummy2.bin", "wb" );
|
||||
|
||||
u32 writeCount = 1024 * 1024 / CONTINUOUS_COPY_SIZE;
|
||||
|
||||
@ -184,8 +175,8 @@ void testWrite()
|
||||
|
||||
void testWriteFile()
|
||||
{
|
||||
FILE * f = fopen( "fat0:/testWriteSpeed.bin", "wb" );
|
||||
//FILE * f = fopen( "fat0:/test_nand4.nds", "wb" );
|
||||
FILE * f = fopen( "fat:/testWriteSpeed.bin", "wb" );
|
||||
//FILE * f = fopen( "fat:/test_nand4.nds", "wb" );
|
||||
if( NULL == f )
|
||||
return;
|
||||
#define SAVEDATA_BUFFER_SIZE (1024 * 1024)
|
||||
@ -205,43 +196,6 @@ void testWriteFile()
|
||||
fclose( f );
|
||||
}
|
||||
|
||||
#include "files.h"
|
||||
void testViolenceCopy()
|
||||
{
|
||||
while( true ) {
|
||||
unlink( "fat0:/800mdummy.rar" );
|
||||
if( !copyFile( "fat1:/800mdummy.rar", "fat0:/800mdummy.rar", false ) )
|
||||
return;
|
||||
|
||||
FILE * f = fopen("fat0:/800mdummy.rar", "rb");
|
||||
u32 readed = 0;
|
||||
//PrintFreeMem();
|
||||
u8 * buffer = new u8[1048576];
|
||||
//PrintFreeMem();
|
||||
do {
|
||||
readed = fread( buffer, 1, 1048555, f );
|
||||
dbg_printf(".");
|
||||
scanKeys();
|
||||
if( keysHeld() & KEY_R ) {
|
||||
delete[] buffer;
|
||||
dbg_printf("\n");
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
} while( readed > 0 );
|
||||
delete[] buffer;
|
||||
dbg_printf("\n");
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
void testSDIdentify()
|
||||
{
|
||||
//u16 sdspeed = sdidCheckSDSpeed( 4096 );
|
||||
//dbg_printf("sd speed %04x\n\n", sdspeed );
|
||||
}
|
||||
|
||||
void testTextOut()
|
||||
{
|
||||
//char msg[32] = {};
|
||||
@ -280,289 +234,4 @@ void testLoadWithOutSave()
|
||||
//loadRom( shortPath );
|
||||
}
|
||||
|
||||
|
||||
#if defined(_STORAGE_rpg)
|
||||
static void checkRedund( u32 saveBlockTable[64] )
|
||||
{
|
||||
ALIGN(4) u8 cfgPage[528];
|
||||
dbg_printf( "checkRedund cfgPage\n");
|
||||
ioRpgReadNand( 0x00000000, cfgPage, 528 );
|
||||
|
||||
// read zones count
|
||||
u32 totalZones = 1 << (cfgPage[0x0c] - 10);
|
||||
//wait_press_b();
|
||||
|
||||
for( size_t i = 0; i < 64; ++i )
|
||||
saveBlockTable[i] = 0xFFFFFFFF;
|
||||
|
||||
ALIGN(4) u8 redundData[16];
|
||||
u8 ctByte = 0x00;
|
||||
u32 saveBlockCountCheck = 0;
|
||||
for( size_t i = 0; i < totalZones * 1024; ++i ) {
|
||||
ioRpgReadNandRedundant( (i << 17) + 512 * 3, redundData );
|
||||
if( redundData[0] != 0xff && redundData[0] != 0x00 )
|
||||
dbg_printf("(%02x%02x%02x)", redundData[1],redundData[2],redundData[3] );
|
||||
if( redundData[0] >= 0x80 && redundData[0] < 0x80 + 64 ) {
|
||||
u8 saveIndex = redundData[3] - 0x80;
|
||||
if( saveIndex < 64 ) {
|
||||
saveBlockCountCheck++;
|
||||
if( saveBlockTable[saveIndex] != 0xFFFFFFFF ) {
|
||||
dbg_printf("checkRedund() FATAL ERROR: Multi save block assign found\n");
|
||||
dbg_printf("saveTable[%d] 1=%08x 2=%08x\n", saveIndex, saveBlockTable[saveIndex], (i << 17) );
|
||||
wait_press_b();
|
||||
}
|
||||
saveBlockTable[saveIndex] = (i << 17);
|
||||
if( redundData[2] >= 0xc0 && redundData[2] <= 0xc4 && 0 == ctByte ) {
|
||||
ctByte = redundData[2];
|
||||
}
|
||||
} else {
|
||||
dbg_printf("idx err, shouldn't have a %d\n", saveIndex );
|
||||
dbg_printf("redunt0-4:(%02x%02x%02x%02x%02x)\n", redundData[0], redundData[1],redundData[2],redundData[3], redundData[4] );
|
||||
dbg_printf("at block: %d\n", i );
|
||||
wait_press_b();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
if( saveBlockCountCheck != 0 && saveBlockCountCheck != 32 && saveBlockCountCheck != 64 )
|
||||
{
|
||||
dbg_printf("checkRedund() FATAL ERROR: saveblock COUNT ERROR %d\n", saveBlockCountCheck );
|
||||
dbg_printf("totalZones %d\n", totalZones );
|
||||
wait_press_b();
|
||||
} else {
|
||||
dbg_printf("checkRedund() OK OK OK OK %d\n", saveBlockCountCheck );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void testViolenceEEP4Kauto( u32 count )
|
||||
{
|
||||
static ALIGN(4) u8 buffer[512];
|
||||
static ALIGN(4) u8 verifyBuffer[512];
|
||||
|
||||
memset( buffer, 0xff, 512 );
|
||||
u32 saveBlockTable1[64];
|
||||
u32 saveBlockTable2[64];
|
||||
u32 round = 0;
|
||||
while( count-- )
|
||||
{
|
||||
saveManager().unlockSave( ST_AUTO, true );
|
||||
|
||||
checkRedund( saveBlockTable1 );
|
||||
printf("4K");
|
||||
|
||||
for( size_t count = 0; count < 8; ++count ) {
|
||||
for( size_t i = 0; i < 512; ++i ) {
|
||||
buffer[i] = rand() & 0xff;
|
||||
}
|
||||
u8 addr = rand() % 512;
|
||||
while( 0 == (addr % 16) ) {
|
||||
addr = rand() % 512;
|
||||
}
|
||||
u8 length = 16 - (addr % 16);
|
||||
length &= (~1);
|
||||
if( length > 0 ) {
|
||||
saveChipWrite( addr, buffer, length, 1 );
|
||||
saveChipRead( addr, verifyBuffer, length, 1 );
|
||||
if( 0 != memcmp( buffer, verifyBuffer, length ) ) {
|
||||
dbg_printf("save verify error\n");
|
||||
wait_press_b();
|
||||
}
|
||||
}
|
||||
dbg_printf(".");
|
||||
}
|
||||
dbg_printf("\n");
|
||||
|
||||
checkRedund( saveBlockTable2 );
|
||||
printf("4K");
|
||||
|
||||
if( 0 != memcmp( saveBlockTable1, saveBlockTable2, 64 * 4 ) ) {
|
||||
dbg_printf("4K save error, table1/2 are different\n");
|
||||
for( size_t i = 0; i < 64; ++i ) {
|
||||
if( saveBlockTable1[i] != saveBlockTable2[i] ) {
|
||||
dbg_printf("%d:%08x-%08x\n", i, saveBlockTable1[i], saveBlockTable2[i]);
|
||||
}
|
||||
}
|
||||
dbg_printf("round %d\n", round );
|
||||
wait_press_b();
|
||||
}
|
||||
|
||||
////////////////////////
|
||||
saveManager().clearSaveBlocks();
|
||||
|
||||
dbg_printf("round %d wait 1 seconds....\n", round );
|
||||
swiDelay( 16 * 1000 * 1000 * 1 );
|
||||
|
||||
scanKeys();
|
||||
if( keysHeld() & KEY_R ) {
|
||||
return;
|
||||
}
|
||||
++round;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void testViolenceEEP512Kauto( u32 count )
|
||||
{
|
||||
static ALIGN(4) u8 buffer[512];
|
||||
static ALIGN(4) u8 verifyBuffer[512];
|
||||
|
||||
memset( buffer, 0xff, 512 );
|
||||
u32 saveBlockTable1[64];
|
||||
u32 saveBlockTable2[64];
|
||||
u32 round = 0;
|
||||
while( count-- )
|
||||
{
|
||||
saveManager().unlockSave( ST_AUTO, true );
|
||||
|
||||
checkRedund( saveBlockTable1 );
|
||||
printf("512K");
|
||||
|
||||
for( size_t count = 0; count < 32; ++count ) {
|
||||
for( size_t i = 0; i < 512; ++i ) {
|
||||
buffer[i] = rand() & 0xff;
|
||||
}
|
||||
u16 addr = rand() % 65536;
|
||||
while( 0 == (addr % 128) ) {
|
||||
addr = rand() % 65536;
|
||||
}
|
||||
u8 length = 128 - (addr % 128);
|
||||
length &= (~1);
|
||||
if( length > 0 ) {
|
||||
saveChipWrite( addr, buffer, length, 2 );
|
||||
saveChipRead( addr, verifyBuffer, length, 2 );
|
||||
if( 0 != memcmp( buffer, verifyBuffer, length ) ) {
|
||||
dbg_printf("save verify error\n");
|
||||
wait_press_b();
|
||||
}
|
||||
}
|
||||
dbg_printf(".");
|
||||
}
|
||||
dbg_printf("\n");
|
||||
|
||||
checkRedund( saveBlockTable2 );
|
||||
printf("512K");
|
||||
|
||||
if( 0 != memcmp( saveBlockTable1, saveBlockTable2, 64 * 4 ) ) {
|
||||
dbg_printf("512K save error, table1/2 are different\n");
|
||||
for( size_t i = 0; i < 64; ++i ) {
|
||||
if( saveBlockTable1[i] != saveBlockTable2[i] ) {
|
||||
dbg_printf("%d:%08x-%08x\n", i, saveBlockTable1[i], saveBlockTable2[i]);
|
||||
}
|
||||
}
|
||||
dbg_printf("round %d\n", round );
|
||||
wait_press_b();
|
||||
}
|
||||
|
||||
////////////////////////
|
||||
saveManager().clearSaveBlocks();
|
||||
|
||||
dbg_printf("round %d wait 1 seconds....\n", round );
|
||||
swiDelay( 16 * 1000 * 1000 * 1 );
|
||||
|
||||
scanKeys();
|
||||
if( keysHeld() & KEY_R ) {
|
||||
return;
|
||||
}
|
||||
++round;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void testViolenceEEP8Mauto( u32 count )
|
||||
{
|
||||
static ALIGN(4) u8 buffer[512];
|
||||
static ALIGN(4) u8 verifyBuffer[512];
|
||||
|
||||
memset( buffer, 0xff, 512 );
|
||||
u32 saveBlockTable1[64];
|
||||
u32 saveBlockTable2[64];
|
||||
u32 round = 0;
|
||||
while( count-- )
|
||||
{
|
||||
saveManager().unlockSave( ST_AUTO, true );
|
||||
|
||||
checkRedund( saveBlockTable1 );
|
||||
printf("8M");
|
||||
|
||||
for( size_t count = 0; count < 1; ++count ) {
|
||||
for( size_t i = 0; i < 512; ++i ) {
|
||||
buffer[i] = rand() & 0xff;
|
||||
}
|
||||
u32 addr = rand() % 1048576;
|
||||
while( 0 == (addr % 256) ) {
|
||||
addr = rand() % 1048576;
|
||||
}
|
||||
u8 length = 256 - (addr % 256);
|
||||
length &= (~1);
|
||||
if( length > 0 ) {
|
||||
saveChipWrite( addr, buffer, length, 3 );
|
||||
saveChipRead( addr, verifyBuffer, length, 3 );
|
||||
if( 0 != memcmp( buffer, verifyBuffer, length ) ) {
|
||||
dbg_printf("save verify error\n");
|
||||
wait_press_b();
|
||||
}
|
||||
}
|
||||
dbg_printf(".");
|
||||
}
|
||||
dbg_printf("\n");
|
||||
|
||||
checkRedund( saveBlockTable2 );
|
||||
printf("8M");
|
||||
|
||||
if( 0 != memcmp( saveBlockTable1, saveBlockTable2, 64 * 4 ) ) {
|
||||
dbg_printf("8M save error, table1/2 are different\n");
|
||||
for( size_t i = 0; i < 64; ++i ) {
|
||||
if( saveBlockTable1[i] != saveBlockTable2[i] ) {
|
||||
dbg_printf("%d:%08x-%08x\n", i, saveBlockTable1[i], saveBlockTable2[i]);
|
||||
}
|
||||
}
|
||||
dbg_printf("round %d\n", round );
|
||||
wait_press_b();
|
||||
}
|
||||
|
||||
////////////////////////
|
||||
saveManager().clearSaveBlocks();
|
||||
|
||||
dbg_printf("round %d wait 1 seconds....\n", round );
|
||||
swiDelay( 16 * 1000 * 1000 * 1 );
|
||||
|
||||
scanKeys();
|
||||
if( keysHeld() & KEY_R ) {
|
||||
return;
|
||||
}
|
||||
++round;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void testEEPReadStatus()
|
||||
{
|
||||
REG_AUXSPICNT = /*E*/0x8000 | /*SEL*/0x2000 | /*MODE*/0x40;
|
||||
|
||||
REG_AUXSPIDATA = 0x05;
|
||||
while (REG_AUXSPICNT & /*BUSY*/0x80);
|
||||
|
||||
REG_AUXSPIDATA = 0x00;
|
||||
while (REG_AUXSPICNT & /*BUSY*/0x80);
|
||||
|
||||
u8 d = REG_AUXSPIDATA;
|
||||
|
||||
dbg_printf("cmd 05 returns %02x\n", d );
|
||||
|
||||
REG_AUXSPICNT = /*MODE*/0x40;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void testGetDiskFreeSpace()
|
||||
{
|
||||
u64 dirSize = 0;
|
||||
if( getDirSize( "fat0:/", true, &dirSize ) ) {
|
||||
dbg_printf("fat0 file takes %d bytes\n", dirSize );
|
||||
}
|
||||
}
|
||||
|
||||
#endif//DEBUG
|
||||
|
@ -39,10 +39,6 @@ void testViolenceEEP512Kauto( u32 count );
|
||||
|
||||
void testViolenceEEP8Mauto( u32 count );
|
||||
|
||||
void testViolenceCopy();
|
||||
|
||||
void testEEPReadStatus();
|
||||
|
||||
void testGetDiskFreeSpace();
|
||||
|
||||
#endif//_TESTCASES_H_
|
||||
|
@ -74,7 +74,7 @@ vu64 cTimer::getTick()
|
||||
static vu64 lastTick = 0;
|
||||
vu64 tick = _overFlow + TIMER0_DATA;
|
||||
if( tick < lastTick )
|
||||
tick += 65536;// 有时候 TIMER0_DATA 已经归0,但overflow 还没有加上,这个时候需要加上65536
|
||||
tick += 65536;// 有时候 TIMER0_DATA 已经归0,但overflow 还没有加上,这个时候需要加上65536
|
||||
lastTick = tick;
|
||||
irqEnable( IRQ_TIMER0 );
|
||||
return tick;
|
||||
|
@ -54,7 +54,7 @@ private:
|
||||
double _lastTime;
|
||||
double _currentTime;
|
||||
static vu64 _overFlow;
|
||||
static const double _factor = 1.f/(33.514*1000000.f);
|
||||
const double _factor = 1.f/(33.514*1000000.f);
|
||||
double _fps;
|
||||
u32 _fpsCounter;
|
||||
};
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
namespace akui {
|
||||
|
||||
// bitmap desc,只负责画背景
|
||||
// bitmap desc,只负责画背景
|
||||
enum BLTMODE
|
||||
{
|
||||
BM_BITBLT,
|
||||
|
@ -175,7 +175,7 @@ void cButtonDesc::draw( const cRect & area, GRAPHICS_ENGINE engine ) const
|
||||
_background.width(), height, _button->selectedEngine() );
|
||||
}
|
||||
|
||||
// 按半角字来算
|
||||
// 按半角字来算
|
||||
u32 textPixels = font().getStringScreenWidth( _button->text().c_str(), _button->text().size() );
|
||||
u32 textX = 0, textY = area.position().y + (( area.size().y - SYSTEM_FONT_HEIGHT ) >> 1 ) + 1;
|
||||
switch(_button->alignment())
|
||||
|
@ -110,7 +110,7 @@ protected:
|
||||
|
||||
};
|
||||
|
||||
// form desc,只负责画背景
|
||||
// form desc,只负责画背景
|
||||
class cButtonDesc : public cRenderDesc
|
||||
{
|
||||
public:
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "ui.h"
|
||||
#include "form.h"
|
||||
#include "timer.h"
|
||||
//#include "files.h"
|
||||
//#include "dbgtool.h"
|
||||
//#include "windowmanager.h"
|
||||
|
||||
@ -165,7 +164,7 @@ bool cForm::processKeyMessage( const cKeyMessage & msg )
|
||||
|
||||
cWindow* cForm::windowBelow(const cPoint& p)
|
||||
{
|
||||
cWindow* ret = cWindow::windowBelow(p); // 先看自己在不在点下面
|
||||
cWindow* ret = cWindow::windowBelow(p); // 先看自己在不在点下面
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
|
@ -27,9 +27,9 @@
|
||||
namespace akui
|
||||
{
|
||||
|
||||
// 边框颜色:b5c71f
|
||||
// 边框颜色:b5c71f
|
||||
// 23, 25, 4
|
||||
// 框内背景色:eeebae
|
||||
// 框内背景色:eeebae
|
||||
// 30, 29, 22
|
||||
|
||||
cFormDesc::cFormDesc()
|
||||
|
@ -18,12 +18,11 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//à
|
||||
//<EFBFBD>
|
||||
|
||||
#include "ui.h"
|
||||
#include "listview.h"
|
||||
//#include "gdi.h"
|
||||
//#include "files.h"
|
||||
//#include "dbgtool.h"
|
||||
|
||||
namespace akui {
|
||||
@ -99,7 +98,7 @@ bool cListView::insertRow( size_t index, const std::vector< std::string > & text
|
||||
{
|
||||
std::string itemText;
|
||||
if( col >= texts.size() )
|
||||
itemText = "Empty"; // ĬÈÏ×Ö·û´®
|
||||
itemText = "Empty"; // 默认字符串
|
||||
else
|
||||
itemText = texts[col];
|
||||
|
||||
|
@ -109,10 +109,10 @@ cMessageBox::cMessageBox( s32 x, s32 y, u32 w, u32 h, cWindow * parent, const st
|
||||
s16 nextButtonX = size().x;
|
||||
s16 buttonPitch = 60;
|
||||
s16 buttonY = size().y - _buttonNO->size().y - 4;
|
||||
// 下一个要画的按钮的位置
|
||||
// 下一个要画的按钮的位置
|
||||
if( _style & MB_NO ) {
|
||||
// 在nextButtonX位置画 NO 按钮
|
||||
// nextButtonX -= 按钮宽度 + 空白区宽度
|
||||
// 在nextButtonX位置画 NO 按钮
|
||||
// nextButtonX -= 按钮宽度 + 空白区宽度
|
||||
buttonPitch = _buttonNO->size().x + 8;
|
||||
nextButtonX -= buttonPitch;
|
||||
_buttonNO->setRelativePosition( cPoint(nextButtonX, buttonY) );
|
||||
@ -121,8 +121,8 @@ cMessageBox::cMessageBox( s32 x, s32 y, u32 w, u32 h, cWindow * parent, const st
|
||||
|
||||
|
||||
if( _style & MB_YES ) {
|
||||
// 在nextButtonX位置画 YES 按钮
|
||||
// nextButtonX -= 按钮宽度 + 空白区宽度
|
||||
// 在nextButtonX位置画 YES 按钮
|
||||
// nextButtonX -= 按钮宽度 + 空白区宽度
|
||||
buttonPitch = _buttonYES->size().x + 8;
|
||||
nextButtonX -= buttonPitch;
|
||||
_buttonYES->setRelativePosition( cPoint(nextButtonX, buttonY) );
|
||||
@ -131,8 +131,8 @@ cMessageBox::cMessageBox( s32 x, s32 y, u32 w, u32 h, cWindow * parent, const st
|
||||
|
||||
|
||||
if( _style & MB_CANCEL ) {
|
||||
// 在nextButtonX位置画 CANCEL 按钮
|
||||
// nextButtonX -= 按钮宽度 + 空白区宽度
|
||||
// 在nextButtonX位置画 CANCEL 按钮
|
||||
// nextButtonX -= 按钮宽度 + 空白区宽度
|
||||
buttonPitch = _buttonCANCEL->size().x + 8;
|
||||
nextButtonX -= buttonPitch;
|
||||
_buttonCANCEL->setRelativePosition( cPoint(nextButtonX, buttonY) );
|
||||
@ -140,8 +140,8 @@ cMessageBox::cMessageBox( s32 x, s32 y, u32 w, u32 h, cWindow * parent, const st
|
||||
}
|
||||
|
||||
if( _style & MB_OK ) {
|
||||
// 在nextButtonX位置画 OK 按钮
|
||||
// nextButtonX -= 按钮宽度 + 空白区宽度
|
||||
// 在nextButtonX位置画 OK 按钮
|
||||
// nextButtonX -= 按钮宽度 + 空白区宽度
|
||||
buttonPitch = _buttonOK->size().x + 8;
|
||||
nextButtonX -= buttonPitch;
|
||||
_buttonOK->setRelativePosition( cPoint(nextButtonX, buttonY) );
|
||||
@ -238,7 +238,7 @@ cWindow& cMessageBox::loadAppearance(const std::string& aFileName )
|
||||
|
||||
u32 messageBox( cWindow * parent, const std::string & title, const std::string & msg, u32 style )
|
||||
{
|
||||
// check point 如果出现奇怪的对话框消失问题就检查这里
|
||||
// check point 如果出现奇怪的对话框消失问题就检查这里
|
||||
cMessageBox msgbox( 12, 36, 232, 120, parent, title, msg, style );
|
||||
//cMessageBox msgbox( 0, 0, 256, 192, parent, text, style );
|
||||
|
||||
|
@ -43,14 +43,14 @@ namespace akui
|
||||
t_point& operator+=(const t_point &p) { x+=p.x,y+=p.y; return *this; }
|
||||
t_point& operator-=(const t_point &p) { x-=p.x,y-=p.y; return *this; }
|
||||
t_point& operator=(const t_point &p) { x=p.x,y=p.y; return *this; }
|
||||
//当前点是否在p的左侧
|
||||
bool is_left(const t_point &p) const { return x<p.x; } // 是否在点的左边
|
||||
//当前点是否在p的右侧
|
||||
bool is_right(const t_point &p) const { return x>p.x; } // 是否在点的右边
|
||||
//当前点是否在p的上方
|
||||
bool is_up(const t_point &p) const { return y<p.y; } // 是否在点的上边
|
||||
//当前点是否在p的下方
|
||||
bool is_down(const t_point &p) const { return y>p.y; } // 是否在点的下边
|
||||
//当前点是否在p的左侧
|
||||
bool is_left(const t_point &p) const { return x<p.x; } // 是否在点的左边
|
||||
//当前点是否在p的右侧
|
||||
bool is_right(const t_point &p) const { return x>p.x; } // 是否在点的右边
|
||||
//当前点是否在p的上方
|
||||
bool is_up(const t_point &p) const { return y<p.y; } // 是否在点的上边
|
||||
//当前点是否在p的下方
|
||||
bool is_down(const t_point &p) const { return y>p.y; } // 是否在点的下边
|
||||
t_point& operator () (value_type x_,value_type y_){x=x_;y=y_;return *this;}
|
||||
};
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//à
|
||||
//<EFBFBD>
|
||||
|
||||
#include "ui.h"
|
||||
#include "popmenu.h"
|
||||
@ -92,7 +92,7 @@ void cPopMenu::draw()
|
||||
|
||||
void cPopMenu::drawItems()
|
||||
{
|
||||
// Ñ»·»æÖÆitemÎÄ×Ö£¬Óö¼û selected ÎÄ×Ö¾ÍÏÈ»æÖÆÑ¡ÔñÌõ
|
||||
// 循环绘制item文字,遇见 selected 文字就先绘制选择条
|
||||
for( size_t i = 0; i < _items.size(); ++i )
|
||||
{
|
||||
s16 itemX = _position.x + _itemTopLeftPoint.x;
|
||||
@ -197,7 +197,7 @@ bool cPopMenu::processTouchMessage( const cTouchMessage & msg )
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 cPopMenu::itemBelowPoint( const cPoint & pt )
|
||||
size_t cPopMenu::itemBelowPoint( const cPoint & pt )
|
||||
{
|
||||
cPoint menuPos(position().x + _barLeft, position().y + _itemTopLeftPoint.y - 2); cSize menuSize(barWidth(), _itemHeight * _items.size());
|
||||
cRect rect(menuPos, menuPos + menuSize);
|
||||
|
@ -44,7 +44,7 @@ public:
|
||||
|
||||
bool process( const cMessage & msg );
|
||||
|
||||
// 返回选中的项
|
||||
// 返回选中的项
|
||||
void popup();
|
||||
|
||||
void addItem( size_t index, const std::string & itemText );
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -22,12 +22,11 @@
|
||||
#define _AKUI_H_
|
||||
|
||||
#include <nds.h>
|
||||
#include "files.h"
|
||||
#include "gdi.h"
|
||||
#include "dbgtool.h"
|
||||
#include "../../share/memtool.h"
|
||||
#include "../../share/stringtool.h"
|
||||
#include "../../share/timetool.h"
|
||||
#include "stringtool.h"
|
||||
#include "timetool.h"
|
||||
|
||||
#include "sigslot.h"
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include "inifile.h"
|
||||
#include "globalsettings.h"
|
||||
#include "unicode.h"
|
||||
#include "../../share/stringtool.h"
|
||||
#include "stringtool.h"
|
||||
#include "../../share/memtool.h"
|
||||
|
||||
using namespace akui;
|
||||
|
@ -18,5 +18,5 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define AKMENU_VRESION_MAIN "1"
|
||||
#define AKMENU_VRESION_SUB "25"
|
||||
#define AKMENU_VERSION_MAIN "1"
|
||||
#define AKMENU_VERSION_SUB "25"
|
||||
|
@ -1,254 +0,0 @@
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_start)
|
||||
|
||||
MEMORY {
|
||||
|
||||
rom : ORIGIN = 0x08000000, LENGTH = 32M
|
||||
fwram : ORIGIN = 0x02000000, LENGTH = 0x450
|
||||
ewram : ORIGIN = 0x02000450, LENGTH = 3200K - 0x450
|
||||
dtcm : ORIGIN = 0x0b000000, LENGTH = 16K
|
||||
vectors : ORIGIN = 0x01000000, LENGTH = 256
|
||||
itcm : ORIGIN = 0x01000100, LENGTH = 32K - 256
|
||||
}
|
||||
|
||||
__vectors_start = ORIGIN(vectors);
|
||||
__itcm_start = ORIGIN(itcm);
|
||||
__ewram_end = ORIGIN(ewram) + LENGTH(ewram);
|
||||
__eheap_end = ORIGIN(ewram) + LENGTH(ewram);
|
||||
__dtcm_start = ORIGIN(dtcm);
|
||||
__dtcm_top = ORIGIN(dtcm) + LENGTH(dtcm);
|
||||
__irq_flags = __dtcm_top - 0x08;
|
||||
__irq_vector = __dtcm_top - 0x04;
|
||||
|
||||
__sp_svc = __dtcm_top - 0x100;
|
||||
__sp_irq = __sp_svc - 0x100;
|
||||
__sp_usr = __sp_irq - 0x100;
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.pad :
|
||||
{
|
||||
*(.pad)
|
||||
} >fwram = 0xff
|
||||
.init :
|
||||
{
|
||||
__text_start = . ;
|
||||
KEEP (*(.init))
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >ewram = 0xff
|
||||
|
||||
.plt : { *(.plt) } >ewram = 0xff
|
||||
|
||||
.text : /* ALIGN (4): */
|
||||
{
|
||||
*(EXCLUDE_FILE (*.itcm*) .text)
|
||||
|
||||
*(.text.*)
|
||||
*(.stub)
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
*(.gnu.linkonce.t*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >ewram = 0xff
|
||||
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(.fini))
|
||||
} >ewram =0xff
|
||||
|
||||
__text_end = . ;
|
||||
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata)
|
||||
*all.rodata*(*)
|
||||
*(.roda)
|
||||
*(.rodata.*)
|
||||
*(.gnu.linkonce.r*)
|
||||
SORT(CONSTRUCTORS)
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >ewram = 0xff
|
||||
|
||||
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >ewram
|
||||
__exidx_start = .;
|
||||
.ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >ewram
|
||||
__exidx_end = .;
|
||||
/* Ensure the __preinit_array_start label is properly aligned. We
|
||||
could instead move the label definition inside the section, but
|
||||
the linker would then create the section even if it turns out to
|
||||
be empty, which isn't pretty. */
|
||||
. = ALIGN(32 / 8);
|
||||
PROVIDE (__preinit_array_start = .);
|
||||
.preinit_array : { KEEP (*(.preinit_array)) } >ewram = 0xff
|
||||
PROVIDE (__preinit_array_end = .);
|
||||
PROVIDE (__init_array_start = .);
|
||||
.init_array :
|
||||
{
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
} >ewram = 0xff
|
||||
PROVIDE (__init_array_end = .);
|
||||
PROVIDE (__fini_array_start = .);
|
||||
.fini_array :
|
||||
{
|
||||
KEEP (*(.fini_array))
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
} >ewram = 0xff
|
||||
PROVIDE (__fini_array_end = .);
|
||||
|
||||
.ctors :
|
||||
{
|
||||
/* gcc uses crtbegin.o to find the start of the constructors, so
|
||||
we make sure it is first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not actually link against
|
||||
crtbegin.o; the linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it doesn't matter which
|
||||
directory crtbegin.o is in. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >ewram = 0xff
|
||||
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >ewram = 0xff
|
||||
|
||||
.eh_frame :
|
||||
{
|
||||
KEEP (*(.eh_frame))
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >ewram = 0xff
|
||||
|
||||
.gcc_except_table :
|
||||
{
|
||||
*(.gcc_except_table)
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >ewram = 0xff
|
||||
.jcr : { KEEP (*(.jcr)) } >ewram = 0
|
||||
.got : { *(.got.plt) *(.got) *(.rel.got) } >ewram = 0
|
||||
|
||||
.ewram ALIGN(4) :
|
||||
{
|
||||
__ewram_start = ABSOLUTE(.) ;
|
||||
*(.ewram)
|
||||
*ewram.*(.text)
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
} >ewram = 0xff
|
||||
|
||||
|
||||
.data ALIGN(4) :
|
||||
{
|
||||
__data_start = ABSOLUTE(.);
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d*)
|
||||
CONSTRUCTORS
|
||||
. = ALIGN(4);
|
||||
__data_end = ABSOLUTE(.) ;
|
||||
} >ewram = 0xff
|
||||
|
||||
|
||||
__dtcm_lma = . ;
|
||||
__bss_vma = . ;
|
||||
|
||||
.dtcm __dtcm_start : AT (__dtcm_lma)
|
||||
{
|
||||
*(.dtcm)
|
||||
*(.dtcm.*)
|
||||
. = ALIGN(4);
|
||||
__dtcm_end = ABSOLUTE(.);
|
||||
} >dtcm = 0xff
|
||||
|
||||
|
||||
__itcm_lma = __dtcm_lma + SIZEOF(.dtcm);
|
||||
|
||||
.itcm __itcm_start : AT (__itcm_lma)
|
||||
{
|
||||
*(.itcm)
|
||||
*itcm.*(.text)
|
||||
. = ALIGN(4);
|
||||
__itcm_end = ABSOLUTE(.);
|
||||
} >itcm = 0xff
|
||||
|
||||
__vectors_lma = __itcm_lma + SIZEOF(.itcm);
|
||||
|
||||
.vectors __vectors_start : AT (__vectors_lma)
|
||||
{
|
||||
*(.vectors)
|
||||
*vectors.*(.text)
|
||||
. = ALIGN(4);
|
||||
__vectors_end = ABSOLUTE(.);
|
||||
} >vectors = 0xff
|
||||
|
||||
.sbss __dtcm_end (NOLOAD):
|
||||
{
|
||||
__sbss_start = ABSOLUTE(.);
|
||||
__sbss_start__ = ABSOLUTE(.);
|
||||
*(.sbss)
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
__sbss_end = ABSOLUTE(.);
|
||||
} >dtcm
|
||||
|
||||
.bss __bss_vma (NOLOAD):
|
||||
{
|
||||
__bss_start = ABSOLUTE(.);
|
||||
__bss_start__ = ABSOLUTE(.);
|
||||
*(.dynbss)
|
||||
*(.gnu.linkonce.b*)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
||||
__bss_end = ABSOLUTE(.) ;
|
||||
__bss_end__ = __bss_end ;
|
||||
} AT>ewram
|
||||
|
||||
|
||||
_end = __bss_end__ ;
|
||||
__end__ = __bss_end__ ;
|
||||
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
.stack 0x80000 : { _stack = .; *(.stack) }
|
||||
/* These must appear regardless of . */
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
%rename link old_link
|
||||
|
||||
*link:
|
||||
%(old_link) -T ../../specs/ds_arm9.ld%s
|
||||
|
||||
*startfile:
|
||||
ds_arm9_crt0%O%s crti%O%s crtbegin%O%s
|
||||
|
Before Width: | Height: | Size: 630 B After Width: | Height: | Size: 630 B |
Loading…
Reference in New Issue
Block a user