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:
lifehackerhansol 2024-10-04 12:08:27 -07:00
parent 6fe395b92f
commit a7dd6151a4
No known key found for this signature in database
GPG Key ID: 80FB184AFC0B3B0E
86 changed files with 308 additions and 6711 deletions

108
Makefile
View File

@ -2,113 +2,57 @@
.SUFFIXES: .SUFFIXES:
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITARM)),) 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 endif
include $(DEVKITARM)/ds_rules
export TARGET := $(shell basename $(CURDIR)) export TARGET := $(shell basename $(CURDIR))
export TOPDIR := $(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
# path to tools - this can be deleted if you set the path in windows # this is relative to the Makefile
#--------------------------------------------------------------------------------- NITRO_FILES :=
export PATH := $(DEVKITARM)/bin:$(PATH)
.PHONY: all rpg r4 ak2i r4idsn clean # These set the information text in the nds file
.PHONY: arm7/rpg/$(TARGET).arm7 arm9/rpg/$(TARGET).arm9 GAME_TITLE := acekard
.PHONY: arm7/r4/$(TARGET).arm7 arm9/r4/$(TARGET).arm9 GAME_SUBTITLE1 := Real Play Gear
.PHONY: arm7/ak2i/$(TARGET).arm7 arm9/ak2i/$(TARGET).arm9 GAME_SUBTITLE2 := www.acekard.com
.PHONY: arm7/r4idsn/$(TARGET).arm7 arm9/r4idsn/$(TARGET).arm9
include $(DEVKITARM)/ds_rules
.PHONY: checkarm7 checkarm9 clean
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# main targets # main targets
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
all: rpg r4 all: checkarm7 checkarm9 $(TARGET).nds
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# rpg target checkarm7:
#---------------------------------------------------------------------------------
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:
$(MAKE) -C arm7 $(MAKE) -C arm7
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
arm9/rpg/$(TARGET).arm9: checkarm9:
$(MAKE) -C arm9 $(MAKE) -C arm9
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
_DS_MENU.DAT : $(TARGET)_r4.nds $(TARGET).nds : $(NITRO_FILES) arm7/$(TARGET).elf arm9/$(TARGET).elf
r4denc $(TARGET)_r4.nds _DS_MENU.DAT 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 arm7/$(TARGET).elf:
ndstool -c $(TARGET)_r4.nds -7 arm7/r4/$(TARGET).arm7 -9 arm9/r4/$(TARGET).arm9 -e9 0x02000450 -e7 0x02380000 -b $(TARGET).bmp "wood r4" $(MAKE) -C arm7
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
arm7/r4/$(TARGET).arm7: arm9/$(TARGET).elf:
$(MAKE) -C arm7 STORAGE=r4 $(MAKE) -C arm9
#---------------------------------------------------------------------------------
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
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
clean: clean:
$(MAKE) -C arm9 clean $(MAKE) -C arm9 clean
$(MAKE) -C arm7 clean $(MAKE) -C arm7 clean
$(MAKE) -C arm9 STORAGE=r4 clean rm -f $(TARGET).nds
$(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

View File

@ -14,66 +14,48 @@ include $(DEVKITARM)/ds_rules
# DATA is a list of directories containing binary files # DATA is a list of directories containing binary files
# all directories are relative to this makefile # all directories are relative to this makefile
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
STORAGE ?= rpg BUILD := build
BUILD := $(STORAGE)/build
SOURCES := source SOURCES := source
INCLUDES := include $(BUILD) INCLUDES := include build ../share $(SOURCES)
DATA := DATA :=
CRT := crt/ds_arm7_crt1.o
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# options for code generation # options for code generation
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
ARCH := -mthumb-interwork ARCH := -mthumb-interwork
CFLAGS := -g -Wall -Os\ CFLAGS := -g -Wall -O3\
-mcpu=arm7tdmi -mtune=arm7tdmi -fomit-frame-pointer\ $(ARCH) $(INCLUDE) -DARM7
-ffast-math \ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
$(ARCH)
CFLAGS += $(INCLUDE) -DARM7 -fno-dwarf2-cfi-asm
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -fno-rtti
ASFLAGS := -g $(ARCH) ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=../../specs/ds_arm7.specs -g $(ARCH) -mno-fpu -Wl,-Map,$(notdir $*).map LDFLAGS = -specs=ds_arm7.specs -g $(ARCH) -Wl,--nmagic -Wl,-Map,$(notdir $*).map
LIBS := -lunds7 LIBS := -ldswifi7 -lmm7 -lnds7
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing # list of directories containing libraries, this must be the top level containing
# include and lib # include and lib
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
LIBDIRS := $(LIBUNDS) LIBDIRS := $(LIBNDS)
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional # no real need to edit anything past this point unless you need to add additional
# rules for different file extensions # rules for different file extensions
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
ifneq ($(notdir $(BUILD)),$(notdir $(CURDIR))) ifneq ($(BUILD),$(notdir $(CURDIR)))
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
export ARM7BIN := $(CURDIR)/$(STORAGE)/$(TARGET).arm7 export ARM7ELF := $(CURDIR)/$(TARGET).elf
export ARM7ELF := $(CURDIR)/$(STORAGE)/$(TARGET).arm7.elf
export DEPSDIR := $(CURDIR)/$(BUILD) 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))) CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 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)
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C # use CXX for linking C++ projects, CC for standard C
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
@ -88,18 +70,30 @@ else
endif 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 .PHONY: $(BUILD) clean
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
$(BUILD): $(BUILD):
@[ -d $@ ] || mkdir -p $@ @[ -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: clean:
@echo clean ... @echo clean ...
@rm -fr $(STORAGE) *.elf @rm -fr $(BUILD) $(TARGET).elf
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
@ -110,26 +104,17 @@ DEPENDS := $(OFILES:.o=.d)
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# main targets # main targets
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
$(ARM7BIN) : $(ARM7ELF) $(ARM7ELF) : $(OFILES)
@$(OBJCOPY) -O binary $< $@
@echo built ... $(notdir $@)
$(ARM7ELF) : $(OFILES) $(CRT)
@echo linking $(notdir $@) @echo linking $(notdir $@)
@$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@ @$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# you need a rule like this for each extension you use as binary data %.bin.o %_bin.h : %.bin
#---------------------------------------------------------------------------------
%.bin.o : %.bin
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
@echo $(notdir $<) @echo $(notdir $<)
@$(bin2o) @$(bin2o)
$(CRT) : $(CRT:.o=.s)
-include $(DEPENDS) -include $(DEPENDS)
#--------------------------------------------------------------------------------------- #---------------------------------------------------------------------------------------

View File

@ -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
@---------------------------------------------------------------------------------

View File

@ -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 . */
}

View File

@ -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

View File

@ -11,75 +11,57 @@ include $(DEVKITARM)/ds_rules
# BUILD is the directory where object files & intermediate files will be placed # BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code # SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files # 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 # all directories are relative to this makefile
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
STORAGE ?= rpg BUILD := build
BUILD := $(STORAGE)/build SOURCES := source source/ui source/font
SOURCES := source source/ui ../share source/font INCLUDES := include ../share $(SOURCES)
INCLUDES := source source/ui ../share source/font $(BUILD) DATA := data
DATA := data data/$(STORAGE) GRAPHICS :=
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# options for code generation # 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 CFLAGS := -g -Wall -O3\
# *insists* it has a FPU or VFP, and it won't take no for an answer! $(ARCH) $(INCLUDE) -DARM9
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 CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
#--ansi ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
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)
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project # 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 # list of directories containing libraries, this must be the top level containing
# include and lib # include and lib
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
LIBDIRS := $(LIBELM) $(LIBUNDS) LIBDIRS := $(LIBNDS) $(PORTLIBS)
ifeq ($(STORAGE),rpg)
LIBDIRS += $(LIBIORPG)
endif
ifeq ($(STORAGE),r4)
LIBDIRS += $(LIBIOR4)
endif
ifeq ($(STORAGE),ak2i)
LIBDIRS += $(LIBIOAK2I)
endif
ifeq ($(STORAGE),r4idsn)
LIBDIRS += $(LIBIOR4IDSN)
endif
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional # no real need to edit anything past this point unless you need to add additional
# rules for different file extensions # rules for different file extensions
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
ifneq ($(notdir $(BUILD)),$(notdir $(CURDIR))) ifneq ($(BUILD),$(notdir $(CURDIR)))
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
export ARM9BIN := $(CURDIR)/$(STORAGE)/$(TARGET).arm9 export ARM9ELF := $(CURDIR)/$(TARGET).elf
export ARM9ELF := $(CURDIR)/$(STORAGE)/$(TARGET).arm9.elf
export DEPSDIR := $(CURDIR)/$(BUILD)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir))\
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) $(foreach dir,$(DATA),$(CURDIR)/$(dir))\
$(foreach dir,$(GRAPHICS),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
PNGFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
@ -96,13 +78,17 @@ else
endif endif
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
export OFILES := $(addsuffix .o,$(BINFILES)) \ export OFILES_BIN := $(addsuffix .o,$(BINFILES))
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
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) -I$(CURDIR)/$(BUILD)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
.PHONY: $(BUILD) clean .PHONY: $(BUILD) clean
@ -110,40 +96,41 @@ export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
$(BUILD): $(BUILD):
@[ -d $@ ] || mkdir -p $@ @[ -d $@ ] || mkdir -p $@
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
clean: clean:
@echo clean ... @echo clean ...
@rm -fr $(STORAGE) *.elf *.nds* *.bin @rm -fr $(BUILD) $(TARGET).elf
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
else else
DEPENDS := $(OFILES:.o=.d)
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# main targets # main targets
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
$(ARM9BIN) : $(ARM9ELF)
@$(OBJCOPY) -O binary $< $@
@echo built ... $(notdir $@)
$(ARM9ELF) : $(OFILES) $(ARM9ELF) : $(OFILES)
@echo linking $(notdir $@) @echo linking $(notdir $@)
@$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@ @$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# you need a rule like this for each extension you use as binary data %.bin.o %_bin.h : %.bin
#---------------------------------------------------------------------------------
%.bin.o : %.bin
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
@echo $(notdir $<) @echo $(notdir $<)
@$(bin2o) @$(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 endif

Binary file not shown.

View File

@ -19,7 +19,7 @@
*/ */
#include "bigclock.h" #include "bigclock.h"
#include "../../share/stringtool.h" #include "stringtool.h"
#include "systemfilenames.h" #include "systemfilenames.h"
#include "windowmanager.h" #include "windowmanager.h"
#include "inifile.h" #include "inifile.h"

View File

@ -18,7 +18,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
//<2F> //<2F>
#include <list> #include <list>
#include <string> #include <string>
@ -34,7 +34,7 @@ cBMP15::cBMP15( u32 width, u32 height ) : _width(0), _height(0), _pitch(0), _buf
_width = width; _width = width;
_height = height; _height = height;
_pitch = (width + (width & 1)) << 1; _pitch = (width + (width & 1)) << 1;
//u32 pitch = (((width*16)+31)>>5)<<2; // 通用算法? //u32 pitch = (((width*16)+31)>>5)<<2; // 通用算法?
} }
cBMP15::~cBMP15() cBMP15::~cBMP15()
@ -46,12 +46,12 @@ cBMP15 createBMP15( u32 width, u32 height )
{ {
cBMP15 bmp( width, 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( "pitch: %d bytes\n", pitch );
//dbg_printf( "buffer %08x\n", bmp.buffer() ); //dbg_printf( "buffer %08x\n", bmp.buffer() );
u32 bufferSize = height * pitch; u32 bufferSize = height * pitch;
if( bufferSize & 3 ) // 如果 bufferSize 不是按4字节对齐就把他调整到对齐 if( bufferSize & 3 ) // 如果 bufferSize 不是按4字节对齐就把他调整到对齐
bufferSize += 4 - (bufferSize & 3); bufferSize += 4 - (bufferSize & 3);
bmp._buffer = new u32[bufferSize>>2]; bmp._buffer = new u32[bufferSize>>2];
return bmp; return bmp;
@ -85,7 +85,7 @@ cBMP15 createBMP15FromFile( const std::string & filename )
return cBMP15(); return cBMP15();
} }
// 读取文件长度 // 读取文件长度
fseek( f, 0, SEEK_END ); fseek( f, 0, SEEK_END );
int fileSize = ftell( f ); int fileSize = ftell( f );
@ -103,7 +103,7 @@ cBMP15 createBMP15FromFile( const std::string & filename )
return cBMP15(); return cBMP15();
} }
// 找出bmp高和宽 // 找出bmp高和宽
u32 width = 0; u32 width = 0;
u32 height = 0; u32 height = 0;
fseek( f, 0x12, SEEK_SET ); fseek( f, 0x12, SEEK_SET );

View File

@ -60,7 +60,7 @@ protected:
u32 _pitch; u32 _pitch;
u32 * _buffer; // 按 32 位地址对齐,可以在 bitblt 的时候加快速度 u32 * _buffer; // 按 32 位地址对齐,可以在 bitblt 的时候加快速度
}; };
cBMP15 createBMP15( u32 width, u32 height ); cBMP15 createBMP15( u32 width, u32 height );

View File

@ -23,7 +23,7 @@
#include "windowmanager.h" #include "windowmanager.h"
#include "inifile.h" #include "inifile.h"
#include "globalsettings.h" #include "globalsettings.h"
#include "../../share/stringtool.h" #include "stringtool.h"
#include "../../share/memtool.h" #include "../../share/memtool.h"
using namespace akui; using namespace akui;

View File

@ -23,9 +23,9 @@
#include "windowmanager.h" #include "windowmanager.h"
#include "language.h" #include "language.h"
#include "msgbox.h" #include "msgbox.h"
#include "../../share/gamecode.h" #include "gamecode.h"
#include <sys/stat.h> #include <sys/stat.h>
#include <elm.h> #include <fat.h>
using namespace akui; using namespace akui;
@ -272,7 +272,6 @@ static void updateDB(u8 value,u32 offset,FILE* db)
void cCheatWnd::onGenerate(void) void cCheatWnd::onGenerate(void)
{ {
NandFast();
FILE* db=fopen(SFN_CHEATS,"r+b"); FILE* db=fopen(SFN_CHEATS,"r+b");
if(db) if(db)
{ {
@ -284,7 +283,6 @@ void cCheatWnd::onGenerate(void)
} }
fclose(db); fclose(db);
} }
NandFlush();
cForm::onOK(); cForm::onOK();
} }

View File

@ -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();
}
}

View File

@ -24,7 +24,7 @@
#include <nds.h> #include <nds.h>
#include <time.h> #include <time.h>
#include "singleton.h" #include "singleton.h"
#include "../../share/stringtool.h" #include "stringtool.h"
class cDateTime class cDateTime
{ {

View File

@ -23,7 +23,7 @@
#include "inifile.h" #include "inifile.h"
#include "systemfilenames.h" #include "systemfilenames.h"
#include "../../share/memtool.h" #include "../../share/memtool.h"
#include "../../share/timetool.h" #include "timetool.h"
#include "globalsettings.h" #include "globalsettings.h"
using namespace akui; using namespace akui;

View File

@ -26,7 +26,7 @@
#include "unknown_nds_banner_bin.h" #include "unknown_nds_banner_bin.h"
#include "gbarom_banner_bin.h" #include "gbarom_banner_bin.h"
#include "icon_bg_bin.h" #include "icon_bg_bin.h"
#include "../../share/gamecode.h" #include "gamecode.h"
#include "fileicons.h" #include "fileicons.h"
DSRomInfo & DSRomInfo::operator =( const DSRomInfo & src ) DSRomInfo & DSRomInfo::operator =( const DSRomInfo & src )
@ -47,14 +47,14 @@ bool DSRomInfo::loadDSRomInfo( const std::string & filename, bool loadBanner )
_isDSRom = EFalse; _isDSRom = EFalse;
_isHomebrew = EFalse; _isHomebrew = EFalse;
FILE * f = fopen( filename.c_str(), "rb" ); FILE * f = fopen( filename.c_str(), "rb" );
if( NULL == f )// <EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>ʧ<EFBFBD><EFBFBD> if( NULL == f )// 锟斤拷锟侥硷拷失锟斤拷
{ {
return false; return false;
} }
tNDSHeader header; 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" ); dbg_printf( "read rom header fail\n" );
memcpy( &_banner, unknown_nds_banner_bin, sizeof(_banner) ); memcpy( &_banner, unknown_nds_banner_bin, sizeof(_banner) );
@ -64,7 +64,7 @@ bool DSRomInfo::loadDSRomInfo( const std::string & filename, bool loadBanner )
///////// ROM Header ///////// ///////// ROM Header /////////
u16 crc = swiCRC16( 0xFFFF, &header, 0x15E ); 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() ); dbg_printf( "%s rom header crc error\n", filename.c_str() );
memcpy( &_banner, unknown_nds_banner_bin, sizeof(_banner) ); memcpy( &_banner, unknown_nds_banner_bin, sizeof(_banner) );
@ -72,7 +72,7 @@ bool DSRomInfo::loadDSRomInfo( const std::string & filename, bool loadBanner )
return true; return true;
} else { } else {
_isDSRom = ETrue; _isDSRom = ETrue;
if( header.arm7destination >= 0x037F8000 || 0x23232323 == gamecode(header.gameCode) ) {//23->'#' if( (u32)(header.arm7destination) >= 0x037F8000 || 0x23232323 == gamecode(header.gameCode) ) {//23->'#'
_isHomebrew = ETrue; _isHomebrew = ETrue;
} }

View File

@ -26,7 +26,7 @@
#include "datetime.h" #include "datetime.h"
#include "progresswnd.h" #include "progresswnd.h"
#include "fontfactory.h" #include "fontfactory.h"
#include <elm.h> #include <fat.h>
using namespace akui; using namespace akui;
@ -214,9 +214,8 @@ void cExpWnd::onRAM()
void cExpWnd::onSRAM() 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; const u32 size=4096*128,page=4096,pages=128;
NandFast();
FILE* saveFile=fopen(saveName.c_str(),"wb"); FILE* saveFile=fopen(saveName.c_str(),"wb");
if(saveFile) if(saveFile)
{ {
@ -241,7 +240,6 @@ void cExpWnd::onSRAM()
} }
fclose(saveFile); fclose(saveFile);
} }
NandFlush();
cForm::onOK(); cForm::onOK();
} }

View File

@ -22,7 +22,7 @@
#include "icons.h" #include "icons.h"
#include "globalsettings.h" #include "globalsettings.h"
#include <sys/dir.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) 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) void cFileIcons::LoadFolder(cIconPaths& aPaths,const std::string& aFolder)
{ {
DIR_ITER* dir=diropen(aFolder.c_str()); DIR *dir=opendir(aFolder.c_str());
if(NULL!=dir) struct dirent *entry;
{
struct stat st; if (NULL!=dir){
char longFilename[MAX_FILENAME_LENGTH]; while ((entry=readdir(dir))!=NULL) {
while(dirnext(dir,longFilename,&st)==0) if(entry->d_type != DT_DIR) {
{ size_t len=strlen(entry->d_name);
if((st.st_mode&S_IFDIR)==0)
{
size_t len=strlen(longFilename);
if(len>4) if(len>4)
{ {
char* extName=longFilename+len-4; char* extName=entry->d_name+len-4;
if(strcasecmp(extName,".bmp")==0) if(strcasecmp(extName,".bmp")==0)
{ {
*extName=0; *extName=0;
aPaths.insert(cFileIconItem(aFolder,longFilename)); aPaths.insert(cFileIconItem(aFolder,entry->d_name));
} }
} }
} }
} }
dirclose(dir); closedir(dir);
} }
} }

View File

@ -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( &copyLength, 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;
}

View File

@ -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_

View File

@ -21,7 +21,6 @@
#include <nds.h> #include <nds.h>
#include <string.h> #include <string.h>
#include "font.h" #include "font.h"
#include "files.h"
#include "dbgtool.h" #include "dbgtool.h"
#include "systemfilenames.h" #include "systemfilenames.h"

View File

@ -21,7 +21,7 @@
#include <nds.h> #include <nds.h>
#include <singleton.h> #include "singleton.h"
#include "font.h" #include "font.h"
class cFontFactory class cFontFactory

View File

@ -31,7 +31,7 @@
#include "sram.h" #include "sram.h"
#include "gbapatcher.h" #include "gbapatcher.h"
#include "gbaloader.h" #include "gbaloader.h"
#include <elm.h> #include <fat.h>
#define LEN 0x100000 #define LEN 0x100000
#define LEN_NOR 0x8000 #define LEN_NOR 0x8000
@ -225,7 +225,6 @@ bool CGbaLoader::CheckPSRAM(u32 aSize)
void CGbaLoader::StartGBA(void) void CGbaLoader::StartGBA(void)
{ {
LoadBorder(); LoadBorder();
ELM_Unmount();
BootGBA(); BootGBA();
while(true) swiWaitForVBlank(); while(true) swiWaitForVBlank();
} }
@ -241,7 +240,7 @@ void CGbaLoader::LoadBorder(void)
{ {
videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE); videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
videoSetModeSub(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 // for the main screen
REG_BG3CNT = BG_BMP16_256x256 | BG_BMP_BASE(0) | BG_WRAP_OFF; 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); cSram::CreateDefaultFile(iFileName.c_str(),saveSize);
/* /*
FILE *log; FILE *log;
log=fopen("fat0:/test.bin","wb"); log=fopen("fat:/test.bin","wb");
fwrite((void*)0x08000000,iSize,1,log); fwrite((void*)0x08000000,iSize,1,log);
fclose(log); fclose(log);
// */ // */

View File

@ -20,6 +20,9 @@
#ifndef __GBALOADER_H__ #ifndef __GBALOADER_H__
#define __GBALOADER_H__ #define __GBALOADER_H__
#include <nds/ndstypes.h>
#include <string>
class CGbaLoader class CGbaLoader
{ {
private: private:

View File

@ -155,16 +155,16 @@ void cGdi::activeFbMain(void)
vramSetBankA( VRAM_A_MAIN_SPRITE_0x06400000 ); vramSetBankA( VRAM_A_MAIN_SPRITE_0x06400000 );
REG_BG2CNT = BG_BMP16_256x256 | BG_BMP_BASE(0) | BG_PRIORITY_1; REG_BG2CNT = BG_BMP16_256x256 | BG_BMP_BASE(0) | BG_PRIORITY_1;
REG_BG2PA = 1 << 8; // 2 =放大倍数 REG_BG2PA = 1 << 8; // 2 =放大倍数
REG_BG2PD = 1 << 8; // 2 =放大倍数 REG_BG2PD = 1 << 8; // 2 =放大倍数
REG_BG2PB = 0; REG_BG2PB = 0;
REG_BG2PC = 0; REG_BG2PC = 0;
REG_BG2Y = 0; REG_BG2Y = 0;
REG_BG2X = 0; REG_BG2X = 0;
REG_BG3CNT = BG_BMP16_256x256 | BG_BMP_BASE(8) | BG_PRIORITY_2; REG_BG3CNT = BG_BMP16_256x256 | BG_BMP_BASE(8) | BG_PRIORITY_2;
REG_BG3PA = 1 << 8; // 2 =放大倍数 REG_BG3PA = 1 << 8; // 2 =放大倍数
REG_BG3PD = 1 << 8; // 2 =放大倍数 REG_BG3PD = 1 << 8; // 2 =放大倍数
REG_BG3PB = 0; REG_BG3PB = 0;
REG_BG3PC = 0; REG_BG3PC = 0;
REG_BG3Y = 0; REG_BG3Y = 0;
@ -200,14 +200,14 @@ void cGdi::activeFbSub(void)
MyInitConsole(_bufferSub3+0x2000,_bufferSub3); MyInitConsole(_bufferSub3+0x2000,_bufferSub3);
#endif #endif
// 分配显存存, 128k // 分配显存存, 128k
vramSetBankC( VRAM_C_SUB_BG_0x06200000 ); // 128k vramSetBankC( VRAM_C_SUB_BG_0x06200000 ); // 128k
// 初始化为文字模式 // 初始化为文字模式
_subEngineMode = SEM_GRAPHICS; _subEngineMode = SEM_GRAPHICS;
//_subEngineMode = SEM_TEXT; //_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_BG2CNT_SUB = BG_BMP16_256x256 | BG_BMP_BASE(0) | BG_PRIORITY_1;
REG_BG2PA_SUB = 1<<8; REG_BG2PA_SUB = 1<<8;
REG_BG2PD_SUB = 1<<8; REG_BG2PD_SUB = 1<<8;
@ -225,18 +225,18 @@ void cGdi::activeFbSub(void)
fillMemory( _bufferSub1, 0x18000, 0xffffffff ); fillMemory( _bufferSub1, 0x18000, 0xffffffff );
// text BG // text BG
// text bg 的字模占用 32(字节/字模) * 256(个ascii字) = 8192 字节显存, // text bg 的字模占用 32(字节/字模) * 256(个ascii字) = 8192 字节显存,
// 文字显示占用 32 x 32 * 2 = 2048 字节显存 // 文字显示占用 32 x 32 * 2 = 2048 字节显存
// 字模从 block 8 开始 = 0x06200000 + 8 * 0x4000 = 0x06220000 // 字模从 block 8 开始 = 0x06200000 + 8 * 0x4000 = 0x06220000
// 文字信息从 block 72 开始 = 0x06200000 + 72 * 0x800 = 0x06224000 // 文字信息从 block 72 开始 = 0x06200000 + 72 * 0x800 = 0x06224000
// 优先级 2 // 优先级 2
#ifdef DEBUG #ifdef DEBUG
BG_PALETTE_SUB[255] = RGB15(31,31,31); //by default font will be rendered with color 255 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; REG_BG0CNT_SUB = BG_TILE_BASE(0) | BG_MAP_BASE(8) | BG_PRIORITY_2;
#endif #endif
swiWaitForVBlank(); //remove tearing at top screen swiWaitForVBlank(); //remove tearing at top screen
// 模式5开两层BG一层BMP一层文字(用于调试)bmp层现在默认关闭 // 模式5开两层BG一层BMP一层文字(用于调试)bmp层现在默认关闭
videoSetModeSub( MODE_5_2D | DISPLAY_BG2_ACTIVE );// | DISPLAY_BG2_ACTIVE ); 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是偶数速度可以快一倍 // maskBlt 要destW是偶数速度可以快一倍
// 不是偶数也可以,但要求在内存中 src 的 pitch 凑成偶数 // 不是偶数也可以,但要求在内存中 src 的 pitch 凑成偶数
void cGdi::maskBlt( const void * src, s16 destX, s16 destY, u16 destW, u16 destH, GRAPHICS_ENGINE engine ) 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 ); //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 ) void cGdi::present( GRAPHICS_ENGINE engine )
{ {
if( GE_MAIN == engine ) { // 翻转主引擎 if( GE_MAIN == engine ) { // 翻转主引擎
//u16 * temp = _bufferMain1; //u16 * temp = _bufferMain1;
//_bufferMain1 = _bufferMain2; //_bufferMain1 = _bufferMain2;
//_bufferMain2 = temp; //_bufferMain2 = temp;
@ -629,7 +629,7 @@ void cGdi::present( GRAPHICS_ENGINE engine )
fillMemory( (void *)(_bufferMain2 + _layerPitch), 256 * 192 * 2, 0 ); fillMemory( (void *)(_bufferMain2 + _layerPitch), 256 * 192 * 2, 0 );
} else if ( GE_SUB == engine ) { // 翻转副引擎 } else if ( GE_SUB == engine ) { // 翻转副引擎
if( SEM_GRAPHICS == _subEngineMode ) if( SEM_GRAPHICS == _subEngineMode )
dmaCopyWordsGdi( 3, (void *)_bufferSub2, (void *)_bufferSub1, 256 * 192 * 2 ); dmaCopyWordsGdi( 3, (void *)_bufferSub2, (void *)_bufferSub1, 256 * 192 * 2 );
//else if( SEM_TEXT == _subEngineMode ) //else if( SEM_TEXT == _subEngineMode )
@ -651,16 +651,16 @@ void cGdi::present(void)
#ifdef DEBUG #ifdef DEBUG
void cGdi::switchSubEngineMode() void cGdi::switchSubEngineMode()
{ {
// 需要保存和恢复文本模式的现场 // 需要保存和恢复文本模式的现场
switch( _subEngineMode ) switch( _subEngineMode )
{ {
case SEM_GRAPHICS: // 当前是图形模式的话就恢复刚才的text现场 case SEM_GRAPHICS: // 当前是图形模式的话就恢复刚才的text现场
videoSetModeSub( MODE_5_2D | DISPLAY_BG0_ACTIVE ); videoSetModeSub( MODE_5_2D | DISPLAY_BG0_ACTIVE );
custom_console.fontBgMap=(u16*)0x6204000; custom_console.fontBgMap=(u16*)0x6204000;
custom_console.fontBgGfx=(u16*)0x6200000; custom_console.fontBgGfx=(u16*)0x6200000;
dmaCopyWordsGdi( 3, (void *)_bufferSub3, (void *)_bufferSub1, 0x4800 ); dmaCopyWordsGdi( 3, (void *)_bufferSub3, (void *)_bufferSub1, 0x4800 );
break; break;
case SEM_TEXT: // 当前是文字模式的话,保存现场,切到图形模式 case SEM_TEXT: // 当前是文字模式的话,保存现场,切到图形模式
videoSetModeSub( MODE_5_2D | DISPLAY_BG2_ACTIVE ); videoSetModeSub( MODE_5_2D | DISPLAY_BG2_ACTIVE );
custom_console.fontBgMap=_bufferSub3+0x2000; custom_console.fontBgMap=_bufferSub3+0x2000;
custom_console.fontBgGfx=_bufferSub3; custom_console.fontBgGfx=_bufferSub3;

View File

@ -28,9 +28,7 @@
cGlobalSettings::cGlobalSettings() cGlobalSettings::cGlobalSettings()
{ {
fontHeight=12; fontHeight=12;
#if defined(_STORAGE_r4)
brightness=1; brightness=1;
#endif
language=1; language=1;
langDirectory="English"; langDirectory="English";
uiName="zelda"; uiName="zelda";
@ -98,11 +96,9 @@ void cGlobalSettings::loadSettings()
struct stat st; struct stat st;
if(0==stat(SFN_CHEATS,&st)) cheatDB=true; if(0==stat(SFN_CHEATS,&st)) cheatDB=true;
#if defined(_STORAGE_r4)
CIniFile iniBacklight(SFN_BACKLIGHT); CIniFile iniBacklight(SFN_BACKLIGHT);
brightness=iniBacklight.GetInt("brightness","brightness",brightness); brightness=iniBacklight.GetInt("brightness","brightness",brightness);
setBrightness(brightness); setBrightness(brightness);
#endif
updateSafeMode(); updateSafeMode();
} }
@ -154,9 +150,6 @@ u32 cGlobalSettings::CopyBufferSize(void)
void cGlobalSettings::nextBrightness(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); fifoSendValue32(FIFO_USER_01,MENU_MSG_BRIGHTNESS_GET);
while(!fifoCheckValue32(FIFO_USER_01)); while(!fifoCheckValue32(FIFO_USER_01));
u32 currentLevel=fifoGetValue32(FIFO_USER_01); u32 currentLevel=fifoGetValue32(FIFO_USER_01);
@ -166,12 +159,9 @@ void cGlobalSettings::nextBrightness(void)
CIniFile ini(SFN_BACKLIGHT); CIniFile ini(SFN_BACKLIGHT);
ini.SetInt("brightness","brightness",brightness); ini.SetInt("brightness","brightness",brightness);
ini.SaveIniFile(SFN_BACKLIGHT); ini.SaveIniFile(SFN_BACKLIGHT);
#endif
} }
#if defined(_STORAGE_r4)
void cGlobalSettings::setBrightness(u32 level) void cGlobalSettings::setBrightness(u32 level)
{ {
fifoSendValue32(FIFO_USER_01,MENU_MSG_BRIGHTNESS_SET0+(brightness&3)); fifoSendValue32(FIFO_USER_01,MENU_MSG_BRIGHTNESS_SET0+(brightness&3));
} }
#endif

View File

@ -60,14 +60,10 @@ public:
void updateSafeMode(void); void updateSafeMode(void);
static u32 CopyBufferSize(void); static u32 CopyBufferSize(void);
void nextBrightness(void); void nextBrightness(void);
#if defined(_STORAGE_r4)
void setBrightness(u32 level); void setBrightness(u32 level);
#endif
public: public:
u8 fontHeight; u8 fontHeight;
#if defined(_STORAGE_r4)
u8 brightness; u8 brightness;
#endif
u8 language; u8 language;
u8 fileListType; u8 fileListType;
u8 romTrim; u8 romTrim;

View File

@ -18,7 +18,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "iocmn.h"
#include "helpwnd.h" #include "helpwnd.h"
#include "msgbox.h" #include "msgbox.h"
#include "windowmanager.h" #include "windowmanager.h"
@ -61,9 +60,8 @@ _buttonOK(0,0,46,18,this,"\x01 OK")
//u8 nandDriverVer = getNandDriverVer(); //u8 nandDriverVer = getNandDriverVer();
_helpText += '\n'; _helpText += '\n';
_helpText += formatString( "wood akmenu %s.%s ", AKMENU_VRESION_MAIN, AKMENU_VRESION_SUB ); _helpText += formatString( "wood akmenu %s.%s ", AKMENU_VERSION_MAIN, AKMENU_VERSION_SUB );
_helpText += formatString( "HW: %02x", ioVersion() ); _helpText += formatString( "\nfont: %dk", font().FontRAM()/1024 );
_helpText += formatString( "\nfont: %dk size: %x", font().FontRAM()/1024, ioSize() );
} }
cHelpWnd::~cHelpWnd() cHelpWnd::~cHelpWnd()

View File

@ -21,9 +21,9 @@
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include "inifile.h" #include "inifile.h"
#include "../../share/stringtool.h" #include "stringtool.h"
#include "dbgtool.h" #include "dbgtool.h"
#include <elm.h> #include <fat.h>
static bool freadLine(FILE* f,std::string& str) static bool freadLine(FILE* f,std::string& str)
{ {
@ -229,11 +229,9 @@ bool CIniFile::SaveIniFile(const std::string& FileName)
if(FileName!="") if(FileName!="")
m_sFileName=FileName; m_sFileName=FileName;
NandFast();
FILE* f=fopen(m_sFileName.c_str(),"wb"); FILE* f=fopen(m_sFileName.c_str(),"wb");
if(NULL==f) if(NULL==f)
{ {
NandFlush();
return false; return false;
} }
@ -255,7 +253,6 @@ bool CIniFile::SaveIniFile(const std::string& FileName)
} }
fclose(f); fclose(f);
NandFlush();
m_bModified=false; m_bModified=false;

View File

@ -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

View File

@ -28,7 +28,6 @@
#include "bigclock.h" #include "bigclock.h"
#include "timer.h" #include "timer.h"
#include "animation.h" #include "animation.h"
#include "files.h"
#include "userwnd.h" #include "userwnd.h"
using namespace akui; using namespace akui;
@ -64,17 +63,6 @@ void cIRQ::vBlank()
if( !_vblankStarted ) if( !_vblankStarted )
return; 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(); timer().updateTimer();
static u32 vBlankCounter = 0; static u32 vBlankCounter = 0;

View File

@ -24,7 +24,7 @@
#include <map> #include <map>
#include <list> #include <list>
#include <elm.h> #include <fat.h>
#include "dbgtool.h" #include "dbgtool.h"
#include "gdi.h" #include "gdi.h"
@ -91,8 +91,7 @@ int main(void)
//wait_press_b(); //wait_press_b();
// init fat // init fat
//bool succ = fatInitDefault(); bool succ = fatInitDefault();
bool succ = (ELM_Mount()&1)?false:true;
if( !succ ) if( !succ )
dbg_printf( "init fat %d\n", 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. { //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().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. //backup gba sram save date to flash.
if(gs().gbaAutoSave&&expansion().IsValid()) if(gs().gbaAutoSave&&expansion().IsValid())
{ {

View File

@ -21,16 +21,14 @@
//<2F> //<2F>
#include <sys/dir.h> #include <sys/dir.h>
#include <elm.h> #include <fat.h>
#define ATTRIB_HID 0x02
#include "mainlist.h" #include "mainlist.h"
#include "files.h"
#include "dbgtool.h" #include "dbgtool.h"
#include "startmenu.h" #include "startmenu.h"
#include "systemfilenames.h" #include "systemfilenames.h"
#include "romloader.h" #include "romloader.h"
#include "windowmanager.h" #include "windowmanager.h"
#include "../../share/timetool.h" #include "timetool.h"
#include "../../share/memtool.h" #include "../../share/memtool.h"
#include "inifile.h" #include "inifile.h"
#include "unknown_banner_bin.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 ) 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), : 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) _topCount(3),_topuSD(0),_topSlot2(1),_topFavorites(2)
#endif
{ {
_viewMode = VM_LIST; _viewMode = VM_LIST;
_activeIconScale = 1; _activeIconScale = 1;
@ -59,7 +53,6 @@ _topCount(3),_topuSD(0),_topSlot2(1),_topFavorites(2)
_activeIcon.update(); _activeIcon.update();
animationManager().addAnimation( &_activeIcon ); animationManager().addAnimation( &_activeIcon );
dbg_printf("_activeIcon.init\n"); dbg_printf("_activeIcon.init\n");
#if defined(_STORAGE_ak2i) || defined(_STORAGE_r4idsn)
fifoSendValue32(FIFO_USER_01,MENU_MSG_SYSTEM); fifoSendValue32(FIFO_USER_01,MENU_MSG_SYSTEM);
while(!fifoCheckValue32(FIFO_USER_02)); while(!fifoCheckValue32(FIFO_USER_02));
u32 system=fifoGetValue32(FIFO_USER_02); u32 system=fifoGetValue32(FIFO_USER_02);
@ -69,7 +62,6 @@ _topCount(3),_topuSD(0),_topSlot2(1),_topFavorites(2)
_topSlot2=2; _topSlot2=2;
_topFavorites=1; _topFavorites=1;
} }
#endif
} }
cMainList::~cMainList() cMainList::~cMainList()
@ -144,15 +136,6 @@ bool cMainList::enterDir( const std::string & dirName )
std::vector< std::string > a_row; std::vector< std::string > a_row;
a_row.push_back( "" ); // make a space for icon a_row.push_back( "" ); // make a space for icon
DSRomInfo rominfo; 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 ) { if( _topuSD == i ) {
a_row.push_back( LANG("mainlist","microsd card") ); a_row.push_back( LANG("mainlist","microsd card") );
a_row.push_back( "" ); a_row.push_back( "" );
@ -184,11 +167,12 @@ bool cMainList::enterDir( const std::string & dirName )
} }
bool favorites=("favorites:/"==dirName); bool favorites=("favorites:/"==dirName);
DIR_ITER* dir=NULL; DIR* dir=NULL;
struct dirent *entry;
if(!favorites) if(!favorites)
{ {
dir = diropen( dirName.c_str() ); dir = opendir( dirName.c_str() );
if (dir == NULL) { if (dir == NULL) {
if( SD_ROOT == dirName ) { if( SD_ROOT == dirName ) {
@ -217,10 +201,7 @@ bool cMainList::enterDir( const std::string & dirName )
savNames.push_back( ".sav" ); savNames.push_back( ".sav" );
// insert 一堆文件, 两列,一列作为显示,一列作为真实文件名 // insert 一堆文件, 两列,一列作为显示,一列作为真实文件名
struct stat st;
char longFilename[MAX_FILENAME_LENGTH];
std::string extName; std::string extName;
u8 attr=0;
// list dir // list dir
{ {
@ -257,21 +238,20 @@ bool cMainList::enterDir( const std::string & dirName )
} }
else if(dir) else if(dir)
{ {
while(dirnext(dir,longFilename,&st)==0) while((entry=readdir(dir))!=NULL)
{ {
attr=st.st_spare1; std::string lfn( entry->d_name );
std::string lfn( longFilename );
// st.st_mode & S_IFDIR indicates a directory // entry->d_type == DT_DIR indicates a directory
size_t lastDotPos = lfn.find_last_of( '.' ); size_t lastDotPos = lfn.find_last_of( '.' );
if( lfn.npos != lastDotPos ) if( lfn.npos != lastDotPos )
extName = lfn.substr( lastDotPos ); extName = lfn.substr( lastDotPos );
else else
extName = ""; extName = "";
dbg_printf( "%s: %s %s\n", (st.st_mode & S_IFDIR ? " DIR" : "FILE"), longFilename, extName.c_str() ); dbg_printf( "%s: %s %s\n", (entry->d_type == DT_DIR ? " DIR" : "FILE"), entry->d_name, extName.c_str() );
bool showThis=(st.st_mode & S_IFDIR)?(strcmp(longFilename,".")&&strcmp(longFilename,"..")):extnameFilter( extNames, extName ); bool showThis=(entry->d_type == DT_DIR)?(strcmp(entry->d_name,".")&&strcmp(entry->d_name,"..")):extnameFilter( extNames, extName );
showThis=showThis&&(_showAllFiles||gs().showHiddenFiles||!(attr&ATTRIB_HID)); showThis=showThis&&(_showAllFiles||gs().showHiddenFiles||!(FAT_getAttr(entry->d_name) & ATTR_HIDDEN));
// 如果有后缀名或者是个目录就push进去 // 如果有后缀名或者是个目录就push进去
if(showThis) { 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( "" ); // make a space for internal name
a_row.push_back(dirName+lfn); //real 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[SHOWNAME_COLUMN] += "/";
a_row[REALNAME_COLUMN] += "/"; a_row[REALNAME_COLUMN] += "/";
} }
@ -297,7 +277,7 @@ bool cMainList::enterDir( const std::string & dirName )
_saves.push_back(dirName+lfn); _saves.push_back(dirName+lfn);
} }
} }
dirclose( dir ); closedir( dir );
} }
std::sort( _rows.begin(), _rows.end(), itemSortComp ); std::sort( _rows.begin(), _rows.end(), itemSortComp );
std::sort(_saves.begin(),_saves.end(),stringComp); std::sort(_saves.begin(),_saves.end(),stringComp);
@ -379,7 +359,7 @@ void cMainList::backParentDir()
return; return;
bool fat1=(SD_ROOT==_currentDir),favorites=("favorites:/"==_currentDir); bool fat1=(SD_ROOT==_currentDir),favorites=("favorites:/"==_currentDir);
if( "fat0:/" == _currentDir || fat1 || favorites || "/" == _currentDir ) { if( "fat:/" == _currentDir || fat1 || favorites || "/" == _currentDir ) {
enterDir( "..." ); enterDir( "..." );
if(fat1) selectRow(_topuSD); if(fat1) selectRow(_topuSD);
if(favorites) selectRow(_topFavorites); if(favorites) selectRow(_topFavorites);

View File

@ -29,11 +29,7 @@
#include "dsrom.h" #include "dsrom.h"
#include "zoomingicon.h" #include "zoomingicon.h"
#if defined(_STORAGE_rpg) #define SD_ROOT_0 "fat:"
#define SD_ROOT_0 "fat1:"
#else
#define SD_ROOT_0 "fat0:"
#endif
#define SD_ROOT SD_ROOT_0"/" #define SD_ROOT SD_ROOT_0"/"
// 显示游戏列表,文件列表等等 // 显示游戏列表,文件列表等等

View File

@ -24,7 +24,7 @@
#include "msgbox.h" #include "msgbox.h"
#include "systemfilenames.h" #include "systemfilenames.h"
#include "timer.h" #include "timer.h"
#include "../../share/timetool.h" #include "timetool.h"
#include "../../share/fifotool.h" #include "../../share/fifotool.h"
#include "testcases.h" #include "testcases.h"
@ -32,7 +32,6 @@
#include "romloader.h" #include "romloader.h"
#include "progresswnd.h" #include "progresswnd.h"
#include "files.h"
#include "inifile.h" #include "inifile.h"
#include "language.h" #include "language.h"
#include "testcases.h" #include "testcases.h"
@ -41,15 +40,11 @@
#include "expwnd.h" #include "expwnd.h"
#include "gbaloader.h" #include "gbaloader.h"
#include "romlauncher.h" #include "romlauncher.h"
#include "sdidentify.h"
#include "favorites.h" #include "favorites.h"
#ifdef DEBUG #include <dirent.h>
#include "iocmn.h"
#endif
#include <sys/iosupport.h> #include <sys/iosupport.h>
#include <elm.h> #include <fat.h>
using namespace akui; using namespace akui;
@ -96,7 +91,7 @@ void cMainWnd::init()
_mainList->selectedRowHeadClicked.connect( this, &cMainWnd::onMainListSelItemHeadClicked ); _mainList->selectedRowHeadClicked.connect( this, &cMainWnd::onMainListSelItemHeadClicked );
_mainList->directoryChanged.connect( this, &cMainWnd::onFolderChanged ); _mainList->directoryChanged.connect( this, &cMainWnd::onFolderChanged );
_mainList->animateIcons.connect( this, &cMainWnd::onAnimation ); _mainList->animateIcons.connect( this, &cMainWnd::onAnimation );
//_mainList->enterDir( "fat0:/" ); //_mainList->enterDir( "fat:/" );
addChildWindow( _mainList ); addChildWindow( _mainList );
dbg_printf( "mainlist %08x\n", _mainList ); dbg_printf( "mainlist %08x\n", _mainList );
@ -200,64 +195,7 @@ void cMainWnd::startMenuItemClicked( s16 i )
dbg_printf( "start menu item %d\n", 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 ); //messageBox( this, "Power Off", "Are you sure you want to turn off ds?", MB_YES | MB_NO );
if( START_MENU_ITEM_COPY == i ) { if( START_MENU_ITEM_SETTING == 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 ) {
showSettings(); showSettings();
} }
@ -389,18 +327,7 @@ bool cMainWnd::processKeyMessage( const cKeyMessage & msg )
} }
else 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:/" ); _mainList->enterDir( "favorites:/" );
#endif
} }
ret = true; ret = true;
break; break;
@ -463,12 +390,6 @@ bool cMainWnd::processTouchMessage( const cTouchMessage & msg )
void cMainWnd::onKeyYPressed() void cMainWnd::onKeyYPressed()
{ {
if(gs().safeMode) return; if(gs().safeMode) return;
#ifdef DEBUG
// hardware version check
{
dbg_printf("HW: %02x\n",ioVersion());
}
#endif//#ifdef DEBUG
showFileInfo(); showFileInfo();
} }
@ -517,26 +438,6 @@ void cMainWnd::launchSelected()
std::string title,text; bool show=true; std::string title,text; bool show=true;
switch(launchRom(fullPath,rominfo,rominfo.isHomebrew()&&"akmenu4.nds"==_mainList->getSelectedShowName())) 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: case ELaunchNoFreeSpace:
title=LANG("no free space","title"); title=LANG("no free space","title");
text=LANG("no free space","text"); text=LANG("no free space","text");
@ -564,17 +465,16 @@ void cMainWnd::setParam(void)
//user interface style //user interface style
_values.clear(); _values.clear();
std::vector<std::string> uiNames; std::vector<std::string> uiNames;
DIR_ITER* dir=diropen(SFN_UI_DIRECTORY); DIR* dir=opendir(SFN_UI_DIRECTORY);
struct dirent *entry;
if(NULL!=dir) if(NULL!=dir)
{ {
struct stat st; while((entry=readdir(dir))!=NULL)
char longFilename[MAX_FILENAME_LENGTH];
while(dirnext(dir,longFilename,&st)==0)
{ {
std::string lfn(longFilename); std::string lfn(entry->d_name);
if(lfn!=".."&&lfn!=".") _values.push_back(lfn); if(lfn!=".."&&lfn!=".") _values.push_back(lfn);
} }
dirclose(dir); closedir(dir);
dir=NULL; dir=NULL;
} }
else else
@ -584,7 +484,7 @@ void cMainWnd::setParam(void)
std::sort(_values.begin(),_values.end()); std::sort(_values.begin(),_values.end());
for(size_t ii=0;ii<_values.size();++ii) 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; uiNames=_values;
settingWnd.addSettingItem(LANG("ui style","text"),_values,uiIndex); settingWnd.addSettingItem(LANG("ui style","text"),_values,uiIndex);
@ -592,17 +492,15 @@ void cMainWnd::setParam(void)
//language //language
_values.clear(); _values.clear();
std::vector<std::string> langNames; std::vector<std::string> langNames;
dir=diropen(SFN_LANGUAGE_DIRECTORY); dir=opendir(SFN_LANGUAGE_DIRECTORY);
if(NULL!=dir ) if(NULL!=dir )
{ {
struct stat st; while ((entry=readdir(dir))!=NULL)
char longFilename[MAX_FILENAME_LENGTH];
while(dirnext(dir,longFilename,&st)==0)
{ {
std::string lfn(longFilename); std::string lfn(entry->d_name);
if(lfn!=".."&&lfn!=".") _values.push_back(lfn); if(lfn!=".."&&lfn!=".") _values.push_back(lfn);
} }
dirclose(dir); closedir(dir);
dir=NULL; dir=NULL;
} }
else else
@ -612,7 +510,7 @@ void cMainWnd::setParam(void)
std::sort(_values.begin(),_values.end()); std::sort(_values.begin(),_values.end());
for(size_t ii=0;ii<_values.size();++ii) 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; langNames=_values;
settingWnd.addSettingItem(LANG("language","text"),_values,langIndex); 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","cheating system"),_values,gs().cheats);
settingWnd.addSettingItem(LANG("patches","reset in game"),_values,gs().softreset); settingWnd.addSettingItem(LANG("patches","reset in game"),_values,gs().softreset);
settingWnd.addSettingItem(LANG("patches","homebrew reset"),_values,gs().homebrewreset); 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 //page 5: gba
settingWnd.addSettingTab(LANG("gba settings","title")); settingWnd.addSettingTab(LANG("gba settings","title"));
@ -737,12 +629,6 @@ void cMainWnd::setParam(void)
gs().cheats=settingWnd.getItemSelection(3,0); gs().cheats=settingWnd.getItemSelection(3,0);
gs().softreset=settingWnd.getItemSelection(3,1); gs().softreset=settingWnd.getItemSelection(3,1);
gs().homebrewreset=settingWnd.getItemSelection(3,2); 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 //page 5: gba
gs().gbaSleepHack=settingWnd.getItemSelection(4,0); gs().gbaSleepHack=settingWnd.getItemSelection(4,0);
@ -758,16 +644,7 @@ void cMainWnd::setParam(void)
gs().uiName = uiNames[uiIndexAfter]; gs().uiName = uiNames[uiIndexAfter];
gs().langDirectory = langNames[langIndexAfter]; gs().langDirectory = langNames[langIndexAfter];
gs().saveSettings(); gs().saveSettings();
#if defined(_STORAGE_rpg) loadRom( "fat:/akmenu4.nds", "", 0, 0, 0 );
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
} }
} }
@ -781,15 +658,7 @@ void cMainWnd::setParam(void)
{ {
gs().langDirectory = langNames[langIndexAfter]; gs().langDirectory = langNames[langIndexAfter];
gs().saveSettings(); gs().saveSettings();
#if defined(_STORAGE_rpg) loadRom( "fat:/akmenu4.nds", "", 0, 0, 0 );
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
} }
} }
@ -840,11 +709,6 @@ void cMainWnd::onFolderChanged()
{ {
resetInputIdle(); resetInputIdle();
std::string dirShowName = _mainList->getCurrentDir(); 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 ) if( dirShowName.substr( 0, 5 ) == SD_ROOT_0 )
dirShowName.replace( 0, 4, "SD" ); dirShowName.replace( 0, 4, "SD" );
else if( "favorites:/" != dirShowName && "slot2:/" == _mainList->getSelectedFullPath() ) else if( "favorites:/" != dirShowName && "slot2:/" == _mainList->getSelectedFullPath() )
@ -878,11 +742,7 @@ void cMainWnd::onFolderChanged()
} }
if(mode==cGlobalSettings::ESlot2Nds) 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); loadRom("slot2:/","",0,0,0);
#endif
} }
else else
{ {

View File

@ -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

View File

@ -27,7 +27,6 @@
#include "uisettings.h" #include "uisettings.h"
#include "language.h" #include "language.h"
#include "unicode.h" #include "unicode.h"
#include "files.h"
#include "gbaloader.h" #include "gbaloader.h"
#include "cheatwnd.h" #include "cheatwnd.h"
#include "ui/binaryfind.h" #include "ui/binaryfind.h"
@ -229,21 +228,6 @@ static std::string getFriendlyFileSizeString( u64 size )
return fileSize+sizeUnit; 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 ) void cRomInfoWnd::setFileInfo( const std::string & fullName, const std::string & showName )
{ {
_fullName=fullName; _fullName=fullName;
@ -258,8 +242,7 @@ void cRomInfoWnd::setFileInfo( const std::string & fullName, const std::string &
return; return;
} }
if( "fat0:/" == fullName || "fat1:/" == fullName ) { if( "fat:/" == fullName ) {
setDiskInfo();
return; return;
} }
@ -339,21 +322,6 @@ void cRomInfoWnd::onShow()
centerScreen(); 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_SAVETYPE 0,0
#define ITEM_LINKAGE 0,1 #define ITEM_LINKAGE 0,1
#define ITEM_RUMBLE 0,2 #define ITEM_RUMBLE 0,2
@ -363,20 +331,6 @@ void cRomInfoWnd::onShow()
#define ITEM_SAVESLOT 1,2 #define ITEM_SAVESLOT 1,2
#define ITEM_ICON 1,3 #define ITEM_ICON 1,3
#define ITEM_LANGUAGE 1,4 #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) void cRomInfoWnd::pressSaveType(void)
{ {
@ -398,25 +352,9 @@ void cRomInfoWnd::pressSaveType(void)
_values.push_back( LANG("save type", "64M" ) ); _values.push_back( LANG("save type", "64M" ) );
settingWnd.addSettingItem( LANG("save type", "text" ), _values, cSaveManager::SaveTypeToDisplaySaveType((SAVE_TYPE)_romInfo.saveInfo().saveType) ); settingWnd.addSettingItem( LANG("save type", "text" ), _values, cSaveManager::SaveTypeToDisplaySaveType((SAVE_TYPE)_romInfo.saveInfo().saveType) );
#if defined(_STORAGE_rpg) || defined(_STORAGE_ak2i)
_values.clear(); _values.clear();
_values.push_back( LANG("switches", "Disable" ) ); _values.push_back( LANG("switches", "Disable" ) );
_values.push_back( LANG("switches", "Enable" ) ); _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() ); settingWnd.addSettingItem( LANG("patches", "linkage" ), _values, _romInfo.saveInfo().getLinkage() );
_values.clear(); _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())); _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() ); 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(); _values.clear();
std::string slotValue; std::string slotValue;
for(size_t ii=0;ii<4;++ii) 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.addSettingItem( LANG("language", "text" ), _values, _romInfo.saveInfo().getLanguage() );
_settingWnd = &settingWnd; _settingWnd = &settingWnd;
settingWnd.addYButton(LANG("rom info","copy slot"),this,&cRomInfoWnd::pressCopySlot);
u32 ret = settingWnd.doModal(); u32 ret = settingWnd.doModal();
_settingWnd = NULL; _settingWnd = NULL;
@ -494,70 +423,21 @@ void cRomInfoWnd::pressSaveType(void)
_romInfo.saveInfo().setFlags _romInfo.saveInfo().setFlags
( (
settingWnd.getItemSelection(ITEM_RUMBLE), settingWnd.getItemSelection(ITEM_RUMBLE),
#if defined(_STORAGE_rpg) || defined(_STORAGE_ak2i)
settingWnd.getItemSelection(ITEM_DOWNLOADPLAY),
#elif defined(_STORAGE_r4) || defined(_STORAGE_r4idsn)
0, 0,
#endif
settingWnd.getItemSelection(ITEM_SOFTRESET), settingWnd.getItemSelection(ITEM_SOFTRESET),
settingWnd.getItemSelection(ITEM_CHEATS), settingWnd.getItemSelection(ITEM_CHEATS),
settingWnd.getItemSelection(ITEM_SAVESLOT), 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, 2,
0, 0,
#endif
settingWnd.getItemSelection(ITEM_LINKAGE), settingWnd.getItemSelection(ITEM_LINKAGE),
settingWnd.getItemSelection(ITEM_ICON), settingWnd.getItemSelection(ITEM_ICON),
#if defined(_STORAGE_rpg)
settingWnd.getItemSelection(ITEM_SDSAVE),
#elif defined(_STORAGE_r4) || defined(_STORAGE_ak2i) || defined(_STORAGE_r4idsn)
2, 2,
#endif
settingWnd.getItemSelection(ITEM_LANGUAGE) settingWnd.getItemSelection(ITEM_LANGUAGE)
); );
saveManager().updateCustomSaveList( _romInfo.saveInfo() ); 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) void cRomInfoWnd::pressFlash(void)
{ {
if(_romInfo.isGbaRom()) if(_romInfo.isGbaRom())

View File

@ -59,8 +59,6 @@ public:
protected: protected:
void setDiskInfo(void);
void pressFlash(void); void pressFlash(void);
void pressSaveType(void); void pressSaveType(void);
@ -69,8 +67,6 @@ protected:
void pressCheats(void); void pressCheats(void);
void pressCopySlot(void);
bool processKeyMessage( const akui::cKeyMessage & msg ); bool processKeyMessage( const akui::cKeyMessage & msg );
void onOK(); void onOK();

View File

@ -16,38 +16,13 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "iocmn.h"
#include "romlauncher.h" #include "romlauncher.h"
#include "../../share/flags.h" #include "flags.h"
#include "language.h" #include "language.h"
#include "save64m.h"
#include "exptools.h" #include "exptools.h"
#include "romloader.h" #include "romloader.h"
#include "sdidentify.h"
#include "cheatwnd.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) static SAVE_TYPE PrefillGame(u32 aGameCode)
{ {
if(0x45444759==aGameCode) //YGDE: 2209 - Diary Girl (USA) 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) case 0x385959: //YY8*: 2436 - Kakushi E Mystery - Riku to Yohan - Kieta 2-mai no E (Japan)
return ST_64K; return ST_64K;
#if defined(_STORAGE_r4) || defined(_STORAGE_ak2i) || defined(_STORAGE_r4idsn)
case 0x533243: //C2S*: Pokemon Mystery Dungeon - Explorers of Sky case 0x533243: //C2S*: Pokemon Mystery Dungeon - Explorers of Sky
return ST_1M; return ST_1M;
#endif
case 0x593241: //A2Y*: Ganbaru Watashi no Kakei Diary case 0x593241: //A2Y*: Ganbaru Watashi no Kakei Diary
case 0x4c5a41: //AZL*: Nintendo Presents - Style Boutique case 0x4c5a41: //AZL*: Nintendo Presents - Style Boutique
case 0x494b42: //BKI*: Legend of Zelda, The - Spirit Tracks 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; u32 flags=0;
long cheatOffset=0; size_t cheatSize=0; long cheatOffset=0; size_t cheatSize=0;
#if defined(_STORAGE_r4) || defined(_STORAGE_ak2i) || defined(_STORAGE_r4idsn)
std::string saveName; std::string saveName;
#endif
if(!aRomInfo.isHomebrew()) if(!aRomInfo.isHomebrew())
{ {
u32 gameCode; u32 gameCode;
@ -188,42 +159,10 @@ TLaunchResult launchRom(const std::string& aFullPath,DSRomInfo& aRomInfo,bool aM
// reading speed setting // reading speed setting
std::string disk=aFullPath.substr(0,5); std::string disk=aFullPath.substr(0,5);
bool dma=false,protection=aRomInfo.saveInfo().isProtection(); u32 speed=0; 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; if(protection) speed=0x1fff;
mount=ioSD();
dma=aRomInfo.saveInfo().isDMA(); dma=aRomInfo.saveInfo().isDMA();
#if defined(_STORAGE_rpg) || defined(_STORAGE_ak2i)
if(dma)
#endif
{
flags|=PATCH_DMA; 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
/* /*
if((gameCode&0xffffff)==0x425841) //2385 - Daigassou! Band-Brothers DX (Japan) 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()); saveName=cSaveManager::generateSaveName(aFullPath,aRomInfo.saveInfo().getSlot());
#endif
if(isBigSave) if(isBigSave)
{ {
isBigSave=cSaveManager::initializeSaveFile(aFullPath,aRomInfo.saveInfo().getSlot(),bigSaveSize); isBigSave=cSaveManager::initializeSaveFile(aFullPath,aRomInfo.saveInfo().getSlot(),bigSaveSize);
if(!isBigSave) return ELaunchNoFreeSpace; 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); 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); 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 else
{ {
@ -296,44 +210,16 @@ TLaunchResult launchRom(const std::string& aFullPath,DSRomInfo& aRomInfo,bool aM
saveManager().updateCustomSaveList(aRomInfo.saveInfo()); saveManager().updateCustomSaveList(aRomInfo.saveInfo());
} }
} }
#if defined(_STORAGE_rpg) if(cSaveManager::initializeSaveFile(aFullPath,aRomInfo.saveInfo().getSlot(),SaveSize(st)))
if(ioSD()==mount&&(aRomInfo.saveInfo().isSDSave()||OnlySDGame(gameCode)))
#endif
{
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); 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); saveManager().saveLastInfo(aFullPath);
#elif defined(_STORAGE_ak2i)
saveManager().saveLastInfo(aFullPath);
if(!dma) speed=0x1fff;
#endif
} }
else else
{ {
return ELaunchNoFreeSpace; return ELaunchNoFreeSpace;
} }
} }
#if defined(_STORAGE_rpg)
else
{
if(!saveManager().restoreSaveData(aFullPath.c_str(),st,aRomInfo.saveInfo().getSlot()))
{
return ELaunchRestoreFail;
}
}
#endif
}
__NDSHeader->cardControl13=0x00406000|speed; __NDSHeader->cardControl13=0x00406000|speed;
//3in1 support //3in1 support
if(gameCode==0x4a524255||gameCode==0x50524255) if(gameCode==0x4a524255||gameCode==0x50524255)
@ -367,16 +253,6 @@ TLaunchResult launchRom(const std::string& aFullPath,DSRomInfo& aRomInfo,bool aM
} }
if(aRomInfo.saveInfo().isSoftReset()) flags|=PATCH_SOFT_RESET; if(aRomInfo.saveInfo().isSoftReset()) flags|=PATCH_SOFT_RESET;
if(expansion().Rampage()==cExpansion::EPsramPage) flags|=PATCH_PSRAM; 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; if(aRomInfo.saveInfo().isLinkage()) flags|=PATCH_LINKAGE;
u8 language=aRomInfo.saveInfo().getLanguage(); u8 language=aRomInfo.saveInfo().getLanguage();
if(language) flags|=(language<<PATCH_LANGUAGE_SHIFT)&PATCH_LANGUAGE_MASK; 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(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); loadRom(aFullPath,saveName,flags,cheatOffset,cheatSize);
#endif
return ELaunchRomOk; return ELaunchRomOk;
} }

View File

@ -19,20 +19,30 @@
*/ */
#include <string.h> #include <string.h>
#include <limits.h>
#include <nds.h> #include <nds.h>
#include <elm.h> #include <fat.h>
#include "romloader.h" #include "romloader.h"
#include "dbgtool.h" #include "dbgtool.h"
#include "akloader_arm7_bin.h" //#include "akloader_arm7_bin.h"
#include "akloader_arm9_bin.h" //#include "akloader_arm9_bin.h"
#include "savechip.h"
#include "savemngr.h" #include "savemngr.h"
#include "../../share/fifotool.h" #include "../../share/fifotool.h"
#include "../../share/timetool.h" #include "timetool.h"
#include "globalsettings.h" #include "globalsettings.h"
#if defined(_STORAGE_rpg)
#include <iorpg.h> // FIFO_CHANNEL_BITS - number of bits used to specify the channel in a packet - default=4
#endif #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() static void resetAndLoop()
{ {
@ -55,49 +65,27 @@ static void resetAndLoop()
swiSoftReset(); 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 ) 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*)0x23fd900=flags;
*(u32*)0x23fd904=cheatOffset; *(u32*)0x23fd904=cheatOffset;
*(u32*)0x23fd908=cheatSize; *(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,filename.c_str());
strcpy((char*)(0x23fda00+MAX_FILENAME_LENGTH),savename.c_str()); strcpy((char*)(0x23fda00+PATH_MAX),savename.c_str());
#endif
dbg_printf( "load %s\n", filename.c_str() ); dbg_printf( "load %s\n", filename.c_str() );
// copy loader's arm7 code // copy loader's arm7 code
memcpy( (void *)0x023FA000, akloader_arm7_bin, akloader_arm7_bin_size ); // memcpy( (void *)0x023FA000, akloader_arm7_bin, akloader_arm7_bin_size );
__NDSHeader->arm7executeAddress = 0x023FA000; __NDSHeader->arm7executeAddress = (void*)0x023FA000;
// copy loader's arm9 code // copy loader's arm9 code
memcpy( (void *)0x023c0000, akloader_arm9_bin, akloader_arm9_bin_size ); // memcpy( (void *)0x023c0000, akloader_arm9_bin, akloader_arm9_bin_size );
__NDSHeader->arm9executeAddress = 0x023c0000; __NDSHeader->arm9executeAddress = (void*)0x023c0000;
dbg_printf( "load done\n" ); dbg_printf( "load done\n" );
ELM_Unmount();
resetAndLoop(); resetAndLoop();
return true; return true;
} }

View File

@ -21,12 +21,9 @@
#ifndef _ROMLOADER_H_ #ifndef _ROMLOADER_H_
#define _ROMLOADER_H_ #define _ROMLOADER_H_
#include <nds/ndstypes.h>
#include <string> #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 ); bool loadRom( const std::string & filename, const std::string & savename, u32 flags, long cheatOffset,size_t cheatSize );
#endif
#endif//_ROMLOADER_H_ #endif//_ROMLOADER_H_

View File

@ -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,&sectorsPerCluster))
{
u32 cluster=1;
while(true)
{
u32 sector;
cluster=ELM_GetFAT(aFileDes,cluster,&sector);
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

View File

@ -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

View File

@ -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

View File

@ -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_

View File

@ -26,14 +26,10 @@
#include "dbgtool.h" #include "dbgtool.h"
#include "systemfilenames.h" #include "systemfilenames.h"
#include "progresswnd.h" #include "progresswnd.h"
#if defined(_STORAGE_rpg)
#include "rpgprotocol.h"
#include "nanddriver.h"
#endif
#include "language.h" #include "language.h"
#include "datetime.h" #include "datetime.h"
#include "ui.h" #include "ui.h"
#include <elm.h> #include <fat.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
@ -41,89 +37,12 @@ using namespace akui;
cSaveManager::cSaveManager() cSaveManager::cSaveManager()
{ {
#if defined(_STORAGE_rpg)
lockSave();
for( size_t i = 0; i < 64; ++i ) {
_saveBlockTable[i] = 0xFFFFFFFF;
}
#endif
} }
cSaveManager::~cSaveManager() 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) static bool loadSaveList(const std::string& filename,std::vector<SAVE_INFO_EX>& buffer)
{ {
u8* data=NULL; 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(1!=fread(&header,sizeof(header),1,f)) break;
if(header.marker!=SAVE_INFO_EX_HEADER_MAGIC) break; if(header.marker!=SAVE_INFO_EX_HEADER_MAGIC) break;
data=new u8[header.itemSize*header.itemCount]; 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; if(header.itemCount!=fread(data,header.itemSize,header.itemCount,f)) break;
buffer.resize(header.itemCount); buffer.resize(header.itemCount);
for(u32 ii=0;ii<header.itemCount;ii++) 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) bool cSaveManager::exportCustomSaveList(const std::string& filename)
{ {
NandFast();
int f=open(filename.c_str(),O_WRONLY|O_CREAT|O_TRUNC); int f=open(filename.c_str(),O_WRONLY|O_CREAT|O_TRUNC);
if(f<0) if(f<0)
{ {
NandFlush();
dbg_printf("fopen %s fail\n",filename.c_str()); dbg_printf("fopen %s fail\n",filename.c_str());
return false; return false;
} }
@ -231,7 +148,6 @@ bool cSaveManager::exportCustomSaveList(const std::string& filename)
res=true; res=true;
} while(false); } while(false);
close(f); close(f);
NandFlush();
return res; return res;
} }
@ -286,538 +202,10 @@ bool cSaveManager::clearLastInfo()
return true; 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 cSaveManager::initializeSaveFile(const std::string& romFilename,u8 slot,u32 size)
{ {
bool res=false; bool res=false;
std::string saveFilename=generateSaveName(romFilename,slot); std::string saveFilename=generateSaveName(romFilename,slot);
NandFast();
int f=open(saveFilename.c_str(),O_WRONLY|O_CREAT); int f=open(saveFilename.c_str(),O_WRONLY|O_CREAT);
if(f>=0) if(f>=0)
{ {
@ -856,60 +244,9 @@ bool cSaveManager::initializeSaveFile(const std::string& romFilename,u8 slot,u32
} }
close(f); close(f);
} }
NandFlush();
return res; 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 cSaveManager::generateSaveName(const std::string& romFilename,u8 slot)
{ {
std::string saveFilename(romFilename); std::string saveFilename(romFilename);
@ -927,68 +264,6 @@ std::string cSaveManager::generateSaveName(const std::string& romFilename,u8 slo
return saveFilename; 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 ) SAVE_TYPE cSaveManager::getSaveTypeByFile( const std::string & romFilename )
{ {
return ST_UNKNOWN; return ST_UNKNOWN;

View File

@ -25,7 +25,6 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include "singleton.h" #include "singleton.h"
#include "savechip.h"
#include "globalsettings.h" #include "globalsettings.h"
typedef struct _SAVE_INFO_T typedef struct _SAVE_INFO_T
@ -186,17 +185,6 @@ typedef struct SAVE_INFO_EX_HEADER_T
u32 reserved; u32 reserved;
} SAVE_INFO_EX_HEADER; } 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 class cSaveManager
{ {
public: public:
@ -219,18 +207,8 @@ class cSaveManager
bool clearLastInfo(); 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); 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); static std::string generateSaveName(const std::string& romFilename,u8 slot);
SAVE_TYPE getSaveTypeByFile( const std::string & romFilename ); SAVE_TYPE getSaveTypeByFile( const std::string & romFilename );
@ -240,46 +218,7 @@ class cSaveManager
static DISPLAY_SAVE_TYPE SaveTypeToDisplaySaveType(SAVE_TYPE aSaveType); static DISPLAY_SAVE_TYPE SaveTypeToDisplaySaveType(SAVE_TYPE aSaveType);
static SAVE_TYPE DisplaySaveTypeToSaveType(DISPLAY_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: 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; std::vector<SAVE_INFO> _saveList;

View File

@ -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

View File

@ -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_

View File

@ -34,8 +34,8 @@ public:
{ {
create_instance(); create_instance();
//atexit( release_instance ); //atexit( release_instance );
// t_singleton 他自己是不会有实例的,无法利用析构函数来释放内存 // t_singleton 他自己是不会有实例的,无法利用析构函数来释放内存
// 所以利用 atexit 来在整个程序退出时释放内存 // 所以利用 atexit 来在整个程序退出时释放内存
} }
return *_instance; return *_instance;
} }

View File

@ -23,7 +23,7 @@
#include <string.h> #include <string.h>
#include "progresswnd.h" #include "progresswnd.h"
#include "language.h" #include "language.h"
#include <elm.h> #include <fat.h>
bool cSram::SaveFileName(const char* romName,char* saveName) bool cSram::SaveFileName(const char* romName,char* saveName)
{ {
@ -120,7 +120,6 @@ void cSram::SaveSramToFile(const char* romName,u16 aStartPage)
saveFile=NULL; saveFile=NULL;
} }
NormalizeSize(saveInfo); NormalizeSize(saveInfo);
NandFast();
saveFile=fopen(saveName,"wb"); saveFile=fopen(saveName,"wb");
if(saveFile) if(saveFile)
{ {
@ -138,7 +137,6 @@ void cSram::SaveSramToFile(const char* romName,u16 aStartPage)
progressWnd().hide(); progressWnd().hide();
fclose(saveFile); fclose(saveFile);
} }
NandFlush();
} }
u8* cSram::SaveSramToMemory(u16 aStartPage,sSaveInfo& aSaveInfo,bool aShowProgress) u8* cSram::SaveSramToMemory(u16 aStartPage,sSaveInfo& aSaveInfo,bool aShowProgress)
@ -179,14 +177,12 @@ void cSram::CreateDefaultFile(const char* romName,u32 size)
} }
else else
{ {
NandFast();
FILE* saveFile=fopen(saveName,"wb"); FILE* saveFile=fopen(saveName,"wb");
if(saveFile) if(saveFile)
{ {
fwrite(&saveInfo,sizeof(saveInfo),1,saveFile); fwrite(&saveInfo,sizeof(saveInfo),1,saveFile);
fclose(saveFile); fclose(saveFile);
} }
NandFlush();
} }
} }

View File

@ -29,10 +29,6 @@ using namespace akui;
void cStartMenu::init() 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_SETTING, LANG("start menu", "Setting") );
addItem( START_MENU_ITEM_INFO, LANG("start menu", "Info") ); addItem( START_MENU_ITEM_INFO, LANG("start menu", "Info") );
addItem( START_MENU_ITEM_HELP, LANG("start menu", "Help") ); addItem( START_MENU_ITEM_HELP, LANG("start menu", "Help") );

View File

@ -23,14 +23,10 @@
#include "popmenu.h" #include "popmenu.h"
#define START_MENU_ITEM_COPY 0 #define START_MENU_ITEM_SETTING 0
#define START_MENU_ITEM_CUT 1 #define START_MENU_ITEM_INFO 1
#define START_MENU_ITEM_DELETE 2 #define START_MENU_ITEM_HELP 2
#define START_MENU_ITEM_PASTE 3 #define START_MENU_ITEM_TOOLS 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
class cStartMenu : public akui::cPopMenu class cStartMenu : public akui::cPopMenu
{ {

View File

@ -21,7 +21,7 @@
#ifndef _SYSTEMFILENAMES_H_ #ifndef _SYSTEMFILENAMES_H_
#define _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_OFFICIAL_SAVELIST SFN_SYSTEM_DIR"savelist.bin"
#define SFN_CUSTOM_SAVELIST SFN_SYSTEM_DIR"gamedata.bin" #define SFN_CUSTOM_SAVELIST SFN_SYSTEM_DIR"gamedata.bin"
#define SFN_LAST_SAVEINFO SFN_SYSTEM_DIR"lastsave.ini" #define SFN_LAST_SAVEINFO SFN_SYSTEM_DIR"lastsave.ini"
@ -29,9 +29,7 @@
#define SFN_SDCARD_LIST SFN_SYSTEM_DIR"sdlist.ini" #define SFN_SDCARD_LIST SFN_SYSTEM_DIR"sdlist.ini"
#define SFN_GLOBAL_SETTINGS SFN_SYSTEM_DIR"globalsettings.ini" #define SFN_GLOBAL_SETTINGS SFN_SYSTEM_DIR"globalsettings.ini"
#define SFN_FAVORITES SFN_SYSTEM_DIR"favorites.ini" #define SFN_FAVORITES SFN_SYSTEM_DIR"favorites.ini"
#if defined(_STORAGE_r4)
#define SFN_BACKLIGHT SFN_SYSTEM_DIR"backlight.ini" #define SFN_BACKLIGHT SFN_SYSTEM_DIR"backlight.ini"
#endif
#define SFN_UI_DIRECTORY SFN_SYSTEM_DIR"ui/" #define SFN_UI_DIRECTORY SFN_SYSTEM_DIR"ui/"
#define SFN_UI_CURRENT_DIRECTORY SFN_UI_DIRECTORY + gs().uiName + "/" #define SFN_UI_CURRENT_DIRECTORY SFN_UI_DIRECTORY + gs().uiName + "/"

View File

@ -20,11 +20,8 @@
#include <nds.h> #include <nds.h>
#include <unistd.h> #include <unistd.h>
#include <elm.h> #include <fat.h>
#include <sys/iosupport.h> #include <sys/iosupport.h>
#if defined(_STORAGE_rpg)
#include <iorpg.h>
#endif
#include <string.h> #include <string.h>
#include "dbgtool.h" #include "dbgtool.h"
@ -38,7 +35,7 @@
void testIni() void testIni()
{ {
CIniFile ini; CIniFile ini;
ini.LoadIniFile( "fat0:/moonshl/moonshl.ini" ); ini.LoadIniFile( "fat:/moonshl/moonshl.ini" );
int bright = ini.GetInt( "System", "NDSLiteDefaultBrightness", 0 ); int bright = ini.GetInt( "System", "NDSLiteDefaultBrightness", 0 );
int WhenStandby= ini.GetInt( "BacklightTimeout", "WhenStandby", 0 ); int WhenStandby= ini.GetInt( "BacklightTimeout", "WhenStandby", 0 );
int WhenPicture = ini.GetInt( "BacklightTimeout", "WhenPicture", 0 ); int WhenPicture = ini.GetInt( "BacklightTimeout", "WhenPicture", 0 );
@ -103,18 +100,15 @@ void testUnicode()
void testCopy() void testCopy()
{ {
#define CONTINUOUS_COPY_SIZE 16384 #define CONTINUOUS_COPY_SIZE 16384
#if defined(_STORAGE_rpg)
ioRpgSetMapTableAddress( MTN_NAND_OFFSET1, 0 );
#endif
static ALIGN(4) u8 copyBuffer[CONTINUOUS_COPY_SIZE]; static ALIGN(4) u8 copyBuffer[CONTINUOUS_COPY_SIZE];
struct stat srcSt; struct stat srcSt;
if( 0 != stat( "fat0:/1Mdummy.nds", &srcSt ) ) { if( 0 != stat( "fat:/1Mdummy.nds", &srcSt ) ) {
printf( "copy file error\n" ); printf( "copy file error\n" );
return; return;
} }
FILE * rf = fopen( "fat0:/1Mdummy.nds", "rb" ); FILE * rf = fopen( "fat:/1Mdummy.nds", "rb" );
FILE * wf = fopen( "fat0:/__rpg/1Mdummy.nds", "wb" ); FILE * wf = fopen( "fat:/__rpg/1Mdummy.nds", "wb" );
u32 writeCount = srcSt.st_size / CONTINUOUS_COPY_SIZE; u32 writeCount = srcSt.st_size / CONTINUOUS_COPY_SIZE;
if( srcSt.st_size & (CONTINUOUS_COPY_SIZE - 1) ) if( srcSt.st_size & (CONTINUOUS_COPY_SIZE - 1) )
@ -148,12 +142,9 @@ void testCopy()
void testWrite() void testWrite()
{ {
#define CONTINUOUS_COPY_SIZE 16384 #define CONTINUOUS_COPY_SIZE 16384
#if defined(_STORAGE_rpg)
ioRpgSetMapTableAddress( MTN_NAND_OFFSET1, 0 );
#endif
static ALIGN(4) u8 copyBuffer[CONTINUOUS_COPY_SIZE]; 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; u32 writeCount = 1024 * 1024 / CONTINUOUS_COPY_SIZE;
@ -184,8 +175,8 @@ void testWrite()
void testWriteFile() void testWriteFile()
{ {
FILE * f = fopen( "fat0:/testWriteSpeed.bin", "wb" ); FILE * f = fopen( "fat:/testWriteSpeed.bin", "wb" );
//FILE * f = fopen( "fat0:/test_nand4.nds", "wb" ); //FILE * f = fopen( "fat:/test_nand4.nds", "wb" );
if( NULL == f ) if( NULL == f )
return; return;
#define SAVEDATA_BUFFER_SIZE (1024 * 1024) #define SAVEDATA_BUFFER_SIZE (1024 * 1024)
@ -205,43 +196,6 @@ void testWriteFile()
fclose( f ); 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() void testTextOut()
{ {
//char msg[32] = {}; //char msg[32] = {};
@ -280,289 +234,4 @@ void testLoadWithOutSave()
//loadRom( shortPath ); //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 #endif//DEBUG

View File

@ -39,10 +39,6 @@ void testViolenceEEP512Kauto( u32 count );
void testViolenceEEP8Mauto( u32 count ); void testViolenceEEP8Mauto( u32 count );
void testViolenceCopy();
void testEEPReadStatus(); void testEEPReadStatus();
void testGetDiskFreeSpace();
#endif//_TESTCASES_H_ #endif//_TESTCASES_H_

View File

@ -74,7 +74,7 @@ vu64 cTimer::getTick()
static vu64 lastTick = 0; static vu64 lastTick = 0;
vu64 tick = _overFlow + TIMER0_DATA; vu64 tick = _overFlow + TIMER0_DATA;
if( tick < lastTick ) if( tick < lastTick )
tick += 65536;// 有时候 TIMER0_DATA 已经归0但overflow 还没有加上这个时候需要加上65536 tick += 65536;// 有时候 TIMER0_DATA 已经归0但overflow 还没有加上这个时候需要加上65536
lastTick = tick; lastTick = tick;
irqEnable( IRQ_TIMER0 ); irqEnable( IRQ_TIMER0 );
return tick; return tick;

View File

@ -54,7 +54,7 @@ private:
double _lastTime; double _lastTime;
double _currentTime; double _currentTime;
static vu64 _overFlow; static vu64 _overFlow;
static const double _factor = 1.f/(33.514*1000000.f); const double _factor = 1.f/(33.514*1000000.f);
double _fps; double _fps;
u32 _fpsCounter; u32 _fpsCounter;
}; };

View File

@ -27,7 +27,7 @@
namespace akui { namespace akui {
// bitmap desc只负责画背景 // bitmap desc只负责画背景
enum BLTMODE enum BLTMODE
{ {
BM_BITBLT, BM_BITBLT,

View File

@ -175,7 +175,7 @@ void cButtonDesc::draw( const cRect & area, GRAPHICS_ENGINE engine ) const
_background.width(), height, _button->selectedEngine() ); _background.width(), height, _button->selectedEngine() );
} }
// 按半角字来算 // 按半角字来算
u32 textPixels = font().getStringScreenWidth( _button->text().c_str(), _button->text().size() ); 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; u32 textX = 0, textY = area.position().y + (( area.size().y - SYSTEM_FONT_HEIGHT ) >> 1 ) + 1;
switch(_button->alignment()) switch(_button->alignment())

View File

@ -110,7 +110,7 @@ protected:
}; };
// form desc只负责画背景 // form desc只负责画背景
class cButtonDesc : public cRenderDesc class cButtonDesc : public cRenderDesc
{ {
public: public:

View File

@ -21,7 +21,6 @@
#include "ui.h" #include "ui.h"
#include "form.h" #include "form.h"
#include "timer.h" #include "timer.h"
//#include "files.h"
//#include "dbgtool.h" //#include "dbgtool.h"
//#include "windowmanager.h" //#include "windowmanager.h"
@ -165,7 +164,7 @@ bool cForm::processKeyMessage( const cKeyMessage & msg )
cWindow* cForm::windowBelow(const cPoint& p) cWindow* cForm::windowBelow(const cPoint& p)
{ {
cWindow* ret = cWindow::windowBelow(p); // 先看自己在不在点下面 cWindow* ret = cWindow::windowBelow(p); // 先看自己在不在点下面
if(ret != 0) if(ret != 0)
{ {

View File

@ -27,9 +27,9 @@
namespace akui namespace akui
{ {
// 边框颜色b5c71f // 边框颜色b5c71f
// 23, 25, 4 // 23, 25, 4
// 框内背景色eeebae // 框内背景色eeebae
// 30, 29, 22 // 30, 29, 22
cFormDesc::cFormDesc() cFormDesc::cFormDesc()

View File

@ -18,12 +18,11 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
//à //<EFBFBD>
#include "ui.h" #include "ui.h"
#include "listview.h" #include "listview.h"
//#include "gdi.h" //#include "gdi.h"
//#include "files.h"
//#include "dbgtool.h" //#include "dbgtool.h"
namespace akui { namespace akui {
@ -99,7 +98,7 @@ bool cListView::insertRow( size_t index, const std::vector< std::string > & text
{ {
std::string itemText; std::string itemText;
if( col >= texts.size() ) if( col >= texts.size() )
itemText = "Empty"; // ĬÈÏ×Ö·û´® itemText = "Empty"; // 默认字符串
else else
itemText = texts[col]; itemText = texts[col];

View File

@ -109,10 +109,10 @@ cMessageBox::cMessageBox( s32 x, s32 y, u32 w, u32 h, cWindow * parent, const st
s16 nextButtonX = size().x; s16 nextButtonX = size().x;
s16 buttonPitch = 60; s16 buttonPitch = 60;
s16 buttonY = size().y - _buttonNO->size().y - 4; s16 buttonY = size().y - _buttonNO->size().y - 4;
// 下一个要画的按钮的位置 // 下一个要画的按钮的位置
if( _style & MB_NO ) { if( _style & MB_NO ) {
// 在nextButtonX位置画 NO 按钮 // 在nextButtonX位置画 NO 按钮
// nextButtonX -= 按钮宽度 + 空白区宽度 // nextButtonX -= 按钮宽度 + 空白区宽度
buttonPitch = _buttonNO->size().x + 8; buttonPitch = _buttonNO->size().x + 8;
nextButtonX -= buttonPitch; nextButtonX -= buttonPitch;
_buttonNO->setRelativePosition( cPoint(nextButtonX, buttonY) ); _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 ) { if( _style & MB_YES ) {
// 在nextButtonX位置画 YES 按钮 // 在nextButtonX位置画 YES 按钮
// nextButtonX -= 按钮宽度 + 空白区宽度 // nextButtonX -= 按钮宽度 + 空白区宽度
buttonPitch = _buttonYES->size().x + 8; buttonPitch = _buttonYES->size().x + 8;
nextButtonX -= buttonPitch; nextButtonX -= buttonPitch;
_buttonYES->setRelativePosition( cPoint(nextButtonX, buttonY) ); _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 ) { if( _style & MB_CANCEL ) {
// 在nextButtonX位置画 CANCEL 按钮 // 在nextButtonX位置画 CANCEL 按钮
// nextButtonX -= 按钮宽度 + 空白区宽度 // nextButtonX -= 按钮宽度 + 空白区宽度
buttonPitch = _buttonCANCEL->size().x + 8; buttonPitch = _buttonCANCEL->size().x + 8;
nextButtonX -= buttonPitch; nextButtonX -= buttonPitch;
_buttonCANCEL->setRelativePosition( cPoint(nextButtonX, buttonY) ); _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 ) { if( _style & MB_OK ) {
// 在nextButtonX位置画 OK 按钮 // 在nextButtonX位置画 OK 按钮
// nextButtonX -= 按钮宽度 + 空白区宽度 // nextButtonX -= 按钮宽度 + 空白区宽度
buttonPitch = _buttonOK->size().x + 8; buttonPitch = _buttonOK->size().x + 8;
nextButtonX -= buttonPitch; nextButtonX -= buttonPitch;
_buttonOK->setRelativePosition( cPoint(nextButtonX, buttonY) ); _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 ) 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( 12, 36, 232, 120, parent, title, msg, style );
//cMessageBox msgbox( 0, 0, 256, 192, parent, text, style ); //cMessageBox msgbox( 0, 0, 256, 192, parent, text, style );

View File

@ -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; } 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的左侧 //当前点是否在p的左侧
bool is_left(const t_point &p) const { return x<p.x; } // 是否在点的左边 bool is_left(const t_point &p) const { return x<p.x; } // 是否在点的左边
//当前点是否在p的右侧 //当前点是否在p的右侧
bool is_right(const t_point &p) const { return x>p.x; } // 是否在点的右边 bool is_right(const t_point &p) const { return x>p.x; } // 是否在点的右边
//当前点是否在p的上方 //当前点是否在p的上方
bool is_up(const t_point &p) const { return y<p.y; } // 是否在点的上边 bool is_up(const t_point &p) const { return y<p.y; } // 是否在点的上边
//当前点是否在p的下方 //当前点是否在p的下方
bool is_down(const t_point &p) const { return y>p.y; } // 是否在点的下边 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;} t_point& operator () (value_type x_,value_type y_){x=x_;y=y_;return *this;}
}; };

View File

@ -18,7 +18,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
//à //<EFBFBD>
#include "ui.h" #include "ui.h"
#include "popmenu.h" #include "popmenu.h"
@ -92,7 +92,7 @@ void cPopMenu::draw()
void cPopMenu::drawItems() void cPopMenu::drawItems()
{ {
// Ñ­»·»æÖÆitemÎÄ×Ö£¬Óö¼û selected ÎÄ×Ö¾ÍÏÈ»æÖÆÑ¡ÔñÌõ // 循环绘制item文字遇见 selected 文字就先绘制选择条
for( size_t i = 0; i < _items.size(); ++i ) for( size_t i = 0; i < _items.size(); ++i )
{ {
s16 itemX = _position.x + _itemTopLeftPoint.x; s16 itemX = _position.x + _itemTopLeftPoint.x;
@ -197,7 +197,7 @@ bool cPopMenu::processTouchMessage( const cTouchMessage & msg )
return ret; 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()); cPoint menuPos(position().x + _barLeft, position().y + _itemTopLeftPoint.y - 2); cSize menuSize(barWidth(), _itemHeight * _items.size());
cRect rect(menuPos, menuPos + menuSize); cRect rect(menuPos, menuPos + menuSize);

View File

@ -44,7 +44,7 @@ public:
bool process( const cMessage & msg ); bool process( const cMessage & msg );
// 返回选中的项 // 返回选中的项
void popup(); void popup();
void addItem( size_t index, const std::string & itemText ); void addItem( size_t index, const std::string & itemText );

File diff suppressed because it is too large Load Diff

View File

@ -22,12 +22,11 @@
#define _AKUI_H_ #define _AKUI_H_
#include <nds.h> #include <nds.h>
#include "files.h"
#include "gdi.h" #include "gdi.h"
#include "dbgtool.h" #include "dbgtool.h"
#include "../../share/memtool.h" #include "../../share/memtool.h"
#include "../../share/stringtool.h" #include "stringtool.h"
#include "../../share/timetool.h" #include "timetool.h"
#include "sigslot.h" #include "sigslot.h"

View File

@ -25,7 +25,7 @@
#include "inifile.h" #include "inifile.h"
#include "globalsettings.h" #include "globalsettings.h"
#include "unicode.h" #include "unicode.h"
#include "../../share/stringtool.h" #include "stringtool.h"
#include "../../share/memtool.h" #include "../../share/memtool.h"
using namespace akui; using namespace akui;

View File

@ -18,5 +18,5 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define AKMENU_VRESION_MAIN "1" #define AKMENU_VERSION_MAIN "1"
#define AKMENU_VRESION_SUB "25" #define AKMENU_VERSION_SUB "25"

View File

@ -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 . */
}

View File

@ -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

View File

Before

Width:  |  Height:  |  Size: 630 B

After

Width:  |  Height:  |  Size: 630 B