commit
2cd0a99e2b
28 changed files with 2617 additions and 13 deletions
3
AUTHORS
3
AUTHORS
|
@ -302,6 +302,9 @@ ScummVM Team
|
||||||
Frantisek Dufka - (retired)
|
Frantisek Dufka - (retired)
|
||||||
Tarek Soliman
|
Tarek Soliman
|
||||||
|
|
||||||
|
Nintendo 3DS:
|
||||||
|
Thomas Edvalson
|
||||||
|
|
||||||
Nintendo 64:
|
Nintendo 64:
|
||||||
Fabio Battaglia
|
Fabio Battaglia
|
||||||
|
|
||||||
|
|
64
backends/platform/3ds/3ds.mk
Normal file
64
backends/platform/3ds/3ds.mk
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
TARGET := scummvm
|
||||||
|
|
||||||
|
APP_TITLE := ScummVM
|
||||||
|
APP_DESCRIPTION := Point-and-click adventure game engines
|
||||||
|
APP_AUTHOR := ScummVM Team
|
||||||
|
APP_ICON := backends/platform/3ds/app/icon.png
|
||||||
|
|
||||||
|
APP_RSF := backends/platform/3ds/app/scummvm.rsf
|
||||||
|
APP_BANNER_IMAGE:= backends/platform/3ds/app/banner.png
|
||||||
|
APP_BANNER_AUDIO:= backends/platform/3ds/app/banner.wav
|
||||||
|
|
||||||
|
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft
|
||||||
|
CXXFLAGS += -std=gnu++11
|
||||||
|
ASFLAGS += -mfloat-abi=hard
|
||||||
|
LDFLAGS += -specs=3dsx.specs $(ARCH) -L$(DEVKITPRO)/libctru/lib -L$(DEVKITPRO)/portlibs/3ds/lib
|
||||||
|
|
||||||
|
.PHONY: clean_3ds
|
||||||
|
|
||||||
|
clean: clean_3ds
|
||||||
|
|
||||||
|
clean_3ds:
|
||||||
|
$(RM) $(TARGET).3dsx
|
||||||
|
$(RM) $(TARGET).cia
|
||||||
|
|
||||||
|
$(TARGET).smdh: $(APP_ICON)
|
||||||
|
@bannertool makesmdh -s "$(APP_TITLE)" -l "$(APP_DESCRIPTION)" -p "$(APP_AUTHOR)" -i $(APP_ICON) -o $@
|
||||||
|
@echo built ... $(notdir $@)
|
||||||
|
|
||||||
|
$(TARGET).3dsx: $(EXECUTABLE) $(TARGET).smdh
|
||||||
|
@3dsxtool $< $@ --smdh=$(TARGET).smdh
|
||||||
|
@echo built ... $(notdir $@)
|
||||||
|
|
||||||
|
$(TARGET).bnr: $(APP_BANNER_IMAGE) $(APP_BANNER_AUDIO)
|
||||||
|
@bannertool makebanner -o $@ -i $(APP_BANNER_IMAGE) -a $(APP_BANNER_AUDIO)
|
||||||
|
@echo built ... $(notdir $@)
|
||||||
|
|
||||||
|
$(TARGET).cia: $(EXECUTABLE) $(APP_RSF) $(TARGET).smdh $(TARGET).bnr
|
||||||
|
@makerom -f cia -target t -exefslogo -o $@ -elf $(EXECUTABLE) -rsf $(APP_RSF) -banner $(TARGET).bnr -icon $(TARGET).smdh
|
||||||
|
@echo built ... $(notdir $@)
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# rules for assembling GPU shaders
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
define shader-as
|
||||||
|
$(eval FILEPATH := $(patsubst %.shbin.o,%.shbin,$@))
|
||||||
|
$(eval FILE := $(patsubst %.shbin.o,%.shbin,$(notdir $@)))
|
||||||
|
picasso -o $(FILEPATH) $1
|
||||||
|
bin2s $(FILEPATH) | $(AS) -o $@
|
||||||
|
echo "extern const u8" `(echo $(FILE) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(FILEPATH) | tr . _)`.h
|
||||||
|
echo "extern const u8" `(echo $(FILE) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(FILEPATH) | tr . _)`.h
|
||||||
|
echo "extern const u32" `(echo $(FILE) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(FILEPATH) | tr . _)`.h
|
||||||
|
endef
|
||||||
|
|
||||||
|
%.shbin.o : %.v.pica %.g.pica
|
||||||
|
@echo $(notdir $^)
|
||||||
|
@$(call shader-as,$^)
|
||||||
|
|
||||||
|
%.shbin.o : %.v.pica
|
||||||
|
@echo $(notdir $<)
|
||||||
|
@$(call shader-as,$<)
|
||||||
|
|
||||||
|
%.shbin.o : %.shlist
|
||||||
|
@echo $(notdir $<)
|
||||||
|
@$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)/$(file)))
|
185
backends/platform/3ds/README
Normal file
185
backends/platform/3ds/README
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
ScummVM 3DS README
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Table of Contents:
|
||||||
|
------------------
|
||||||
|
1.0) Installation
|
||||||
|
* 1.1 3DSX installation
|
||||||
|
* 1.2 CIA installation
|
||||||
|
2.0) Controls
|
||||||
|
* 2.1 Default key mappings
|
||||||
|
* 2.2 Hover mode
|
||||||
|
* 2.3 Drag mode
|
||||||
|
3.0) Supported Games
|
||||||
|
4.0) Compiling
|
||||||
|
* 4.1 Prerequisites
|
||||||
|
* * 4.1.1 Compiling third-party libraries
|
||||||
|
* 4.2 Compiling ScummVM
|
||||||
|
* 4.3 Warning for 3DSX build
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
1.0) Installation
|
||||||
|
-----------------
|
||||||
|
There are two possible formats to be used: 3DSX and CIA (recommended).
|
||||||
|
The 3DSX format is exclusively used by the Homebrew Launcher and its derivatives.
|
||||||
|
The CIA format can be installed directly to the 3DS home menu and can be launched
|
||||||
|
using any CFW (Custom Firmware) of your choice.
|
||||||
|
|
||||||
|
Installing the Homebrew Launcher or any CFW is beyond the scope of this README.
|
||||||
|
Look elsewhere to see how to install those if you do not already have them set up.
|
||||||
|
|
||||||
|
|
||||||
|
1.1) 3DSX installation
|
||||||
|
----------------
|
||||||
|
The CIA format is recommended for stability and maximum game support. If that is
|
||||||
|
not an option, you will need one of a collection of 3DS titles installed on your
|
||||||
|
system in order to properly launch ScummVM as a 3DSX. This is because the
|
||||||
|
Homebrew Launcher hijacks other processes to run 3DSX homebrew, and ScummVM is a
|
||||||
|
particularly large homebrew that can't be launched with the resources provided
|
||||||
|
by standard system applications.
|
||||||
|
|
||||||
|
You will need one of the following (installed or physically in cart slot):
|
||||||
|
|
||||||
|
- Youtube
|
||||||
|
- Monster Hunter 4 Ultimate Special Demo
|
||||||
|
- Monster Hunter 4 Ultimate
|
||||||
|
- Monster Hunter 4G
|
||||||
|
- Super Smash Bros. for Nintendo 3DS Demo
|
||||||
|
- Super Smash Bros. for Nintendo 3DS Special Demo
|
||||||
|
- Super Smash Bros. for Nintendo 3DS
|
||||||
|
|
||||||
|
Once you have one of the above, you need to merely extract all ScummVM 3DS files
|
||||||
|
to the root of your SD card so that all files reside in the /3ds/scummvm/ directory.
|
||||||
|
|
||||||
|
|
||||||
|
1.2) CIA installation
|
||||||
|
---------------------
|
||||||
|
The CIA format requires a DSP binary dump saved on your SD card as /3ds/dspfirm.cdc
|
||||||
|
for proper audio support. You can search online to find software to dump this.
|
||||||
|
Not having this file will cause many problems with games that need audio, sometimes
|
||||||
|
even crashing, so this is NOT considered optional.
|
||||||
|
|
||||||
|
Using any CIA installation software (search elsewhere for that), you need to install
|
||||||
|
the scummvm.cia file. Then, just like what is done with the 3DSX installation, you
|
||||||
|
need to extract all ScummVM 3DS files (scummvm.cia excluded) to the root of your SD
|
||||||
|
card so that all files reside in the /3ds/scummvm/ directory.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2.0) Controls
|
||||||
|
-------------
|
||||||
|
|
||||||
|
2.1) Default key mappings
|
||||||
|
-------------------------
|
||||||
|
The D-Pad and A/B/X/Y buttons have mirrored usage. So they do the same things
|
||||||
|
depending on if you're right or left-handed.
|
||||||
|
|
||||||
|
| Buttons | Function |
|
||||||
|
|------------|--------------------------------|
|
||||||
|
| A / D-left | Left-click |
|
||||||
|
| X / D-up | Right-click |
|
||||||
|
| B / D-down | ESC (skips cutscenes and such) |
|
||||||
|
| L | Use virtual keyboard |
|
||||||
|
| R | Toggle hover/drag modes |
|
||||||
|
| Start | Open game menu |
|
||||||
|
| Select | Open 3DS config menu |
|
||||||
|
| Circle Pad | Move the cursor |
|
||||||
|
|
||||||
|
|
||||||
|
2.2) Hover mode
|
||||||
|
---------------
|
||||||
|
When you use the touchscreen, you are simulating the mere moving of the mouse. You
|
||||||
|
can click only with taps, meaning it is impossible to drag stuff or hold down a
|
||||||
|
mouse button without using buttons mapped to right/left-click.
|
||||||
|
|
||||||
|
|
||||||
|
2.3) Drag mode
|
||||||
|
--------------
|
||||||
|
Every time you touch and release the touchscreen, you are simulating the click and
|
||||||
|
release of the mouse buttons. At the moment, this is only a left-click.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.0) Supported Games
|
||||||
|
--------------------
|
||||||
|
The full game engine compatibility list can be found here:
|
||||||
|
http://scummvm.org/compatibility/
|
||||||
|
|
||||||
|
While all the above games should run on the 3DS (report if they do not), there are
|
||||||
|
many games which are unplayable due to the lack of CPU speed on the 3DS. So if
|
||||||
|
you play any games that run really slow, this is not considered a bug, but rather
|
||||||
|
a hardware limitation. Though possible GPU optimizations are always in the works.
|
||||||
|
The New 3DS console has much better performance, but there are still many newer and
|
||||||
|
high-resolution games that cannot be played. A list of these unplayable games and
|
||||||
|
game engines will eventually be listed here.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
4.0) Compiling
|
||||||
|
--------------
|
||||||
|
|
||||||
|
4.1) Prerequisites
|
||||||
|
------------------
|
||||||
|
- devkitARM (presumably with libctru, picasso and such)
|
||||||
|
- citro3d
|
||||||
|
- Optional: You should compile third-party libraries for the 3ds (commonly referred
|
||||||
|
to as portlibs in the devkitPRO community). Some games requires these to operate
|
||||||
|
properly.
|
||||||
|
|
||||||
|
|
||||||
|
4.1.1) Compiling third-party libraries
|
||||||
|
--------------------------------------
|
||||||
|
Most libraries used can be compiled with same commands and configuration flags.
|
||||||
|
|
||||||
|
It is assumed that you have these environment variables defined:
|
||||||
|
- DEVKITPRO Your root devkitPro directory
|
||||||
|
- DEVKITARM Your root devkitARM directory (probably same as $DEVKITPRO/devkitARM)
|
||||||
|
- CTRULIB Your root libctru directory (probably same as $DEVKITPRO/libctru)
|
||||||
|
|
||||||
|
In the source directory of the library:
|
||||||
|
- $ export PORTLIBS=$DEVKITPRO/portlibs/armv6k
|
||||||
|
- $ export PATH=$DEVKITARM/bin:$PATH
|
||||||
|
- $ export PKG_CONFIG_PATH=$PORTLIBS/lib/pkgconfig
|
||||||
|
- $ export CFLAGS="-g -march=armv6k -mtune=mpcore -mfloat-abi=hard -O2
|
||||||
|
-mword-relocations -ffunction-sections -fdata-sections"
|
||||||
|
- $ export CPPFLAGS="-I$PORTLIBS/include -I$CTRULIB/include"
|
||||||
|
- $ export LDFLAGS="-L$PORTLIBS/lib"
|
||||||
|
- $ mkdir -p $PORTLIBS
|
||||||
|
- $ ./configure --prefix=$PORTLIBS --host=arm-none-eabi --disable-shared
|
||||||
|
--enable-static
|
||||||
|
- $ make
|
||||||
|
- $ make install
|
||||||
|
|
||||||
|
Useful libraries (and special config flags needed):
|
||||||
|
- zlib
|
||||||
|
- libpng
|
||||||
|
- libjpeg
|
||||||
|
- freetype2 --without-bzip2 --without-harfbuzz
|
||||||
|
- libmad
|
||||||
|
- tremor
|
||||||
|
- flac --disable-cpplibs --without-flac
|
||||||
|
- faad
|
||||||
|
|
||||||
|
|
||||||
|
4.2) Compiling ScummVM
|
||||||
|
----------------------
|
||||||
|
- $ ./configure --host=3ds
|
||||||
|
- $ make
|
||||||
|
|
||||||
|
Additionally compile to specific formats to be used on the 3ds:
|
||||||
|
- $ make scummvm.3dsx
|
||||||
|
- $ make scummvm.cia
|
||||||
|
|
||||||
|
|
||||||
|
4.3) Warning for 3DSX build
|
||||||
|
---------------------------
|
||||||
|
The above configuration command will include all game engines by default and will
|
||||||
|
likely be too massive to run using the 3DSX format. Until dynamic modules are figured
|
||||||
|
out, you should configure engines like this for 3DSX builds:
|
||||||
|
|
||||||
|
- $ ./configure --host=3ds --disable-all-engines--enable-engine=scumm-7-8,myst,riven,
|
||||||
|
sword1,sword2,sword25,sci,lure,sky,agi,agos
|
||||||
|
|
||||||
|
Choose whatever engines you want, but if the ELF's .text section exceeds ~10MB, it
|
||||||
|
won't be playable unless it's a CIA.
|
BIN
backends/platform/3ds/app/banner.png
Normal file
BIN
backends/platform/3ds/app/banner.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
BIN
backends/platform/3ds/app/banner.wav
Normal file
BIN
backends/platform/3ds/app/banner.wav
Normal file
Binary file not shown.
BIN
backends/platform/3ds/app/icon.png
Normal file
BIN
backends/platform/3ds/app/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.7 KiB |
219
backends/platform/3ds/app/scummvm.rsf
Normal file
219
backends/platform/3ds/app/scummvm.rsf
Normal file
|
@ -0,0 +1,219 @@
|
||||||
|
BasicInfo:
|
||||||
|
Title : ScummVM
|
||||||
|
ProductCode : ScummVM
|
||||||
|
Logo : Nintendo # Nintendo / Licensed / Distributed / iQue / iQueForSystem
|
||||||
|
|
||||||
|
TitleInfo:
|
||||||
|
Category : Application
|
||||||
|
UniqueId : 0xFF321
|
||||||
|
|
||||||
|
Option:
|
||||||
|
UseOnSD : true # true if App is to be installed to SD
|
||||||
|
FreeProductCode : true # Removes limitations on ProductCode
|
||||||
|
MediaFootPadding : false # If true CCI files are created with padding
|
||||||
|
EnableCrypt : false # Enables encryption for NCCH and CIA
|
||||||
|
EnableCompress : false # Compresses where applicable (currently only exefs:/.code)
|
||||||
|
|
||||||
|
AccessControlInfo:
|
||||||
|
CoreVersion : 2
|
||||||
|
|
||||||
|
# Exheader Format Version
|
||||||
|
DescVersion : 2
|
||||||
|
|
||||||
|
# Minimum Required Kernel Version (below is for 4.5.0)
|
||||||
|
ReleaseKernelMajor : "02"
|
||||||
|
ReleaseKernelMinor : "33"
|
||||||
|
|
||||||
|
# ExtData
|
||||||
|
UseExtSaveData : false # enables ExtData
|
||||||
|
#ExtSaveDataId : 0x300 # only set this when the ID is different to the UniqueId
|
||||||
|
|
||||||
|
# FS:USER Archive Access Permissions
|
||||||
|
# Uncomment as required
|
||||||
|
FileSystemAccess:
|
||||||
|
#- CategorySystemApplication
|
||||||
|
#- CategoryHardwareCheck
|
||||||
|
#- CategoryFileSystemTool
|
||||||
|
#- Debug
|
||||||
|
#- TwlCardBackup
|
||||||
|
#- TwlNandData
|
||||||
|
#- Boss
|
||||||
|
- DirectSdmc
|
||||||
|
#- Core
|
||||||
|
#- CtrNandRo
|
||||||
|
#- CtrNandRw
|
||||||
|
#- CtrNandRoWrite
|
||||||
|
#- CategorySystemSettings
|
||||||
|
#- CardBoard
|
||||||
|
#- ExportImportIvs
|
||||||
|
#- DirectSdmcWrite
|
||||||
|
#- SwitchCleanup
|
||||||
|
#- SaveDataMove
|
||||||
|
#- Shop
|
||||||
|
#- Shell
|
||||||
|
#- CategoryHomeMenu
|
||||||
|
|
||||||
|
# Process Settings
|
||||||
|
MemoryType : Application # Application/System/Base
|
||||||
|
SystemMode : 64MB # 64MB(Default)/96MB/80MB/72MB/32MB
|
||||||
|
IdealProcessor : 0
|
||||||
|
AffinityMask : 1
|
||||||
|
Priority : 16
|
||||||
|
MaxCpu : 0 # Let system decide
|
||||||
|
HandleTableSize : 0x200
|
||||||
|
DisableDebug : false
|
||||||
|
EnableForceDebug : false
|
||||||
|
CanWriteSharedPage : true
|
||||||
|
CanUsePrivilegedPriority : false
|
||||||
|
CanUseNonAlphabetAndNumber : true
|
||||||
|
PermitMainFunctionArgument : true
|
||||||
|
CanShareDeviceMemory : true
|
||||||
|
RunnableOnSleep : false
|
||||||
|
SpecialMemoryArrange : true
|
||||||
|
|
||||||
|
# New3DS Exclusive Process Settings
|
||||||
|
SystemModeExt : 124MB # Legacy(Default)/124MB/178MB Legacy:Use Old3DS SystemMode
|
||||||
|
CpuSpeed : 804MHz # 268MHz(Default)/804MHz
|
||||||
|
EnableL2Cache : true # false(default)/true
|
||||||
|
CanAccessCore2 : true
|
||||||
|
|
||||||
|
# Virtual Address Mappings
|
||||||
|
IORegisterMapping:
|
||||||
|
- 1ff00000-1ff7ffff # DSP memory
|
||||||
|
MemoryMapping:
|
||||||
|
- 1f000000-1f5fffff:r # VRAM
|
||||||
|
|
||||||
|
# Accessible SVCs, <Name>:<ID>
|
||||||
|
SystemCallAccess:
|
||||||
|
ArbitrateAddress: 34
|
||||||
|
Break: 60
|
||||||
|
CancelTimer: 28
|
||||||
|
ClearEvent: 25
|
||||||
|
ClearTimer: 29
|
||||||
|
CloseHandle: 35
|
||||||
|
ConnectToPort: 45
|
||||||
|
ControlMemory: 1
|
||||||
|
CreateAddressArbiter: 33
|
||||||
|
CreateEvent: 23
|
||||||
|
CreateMemoryBlock: 30
|
||||||
|
CreateMutex: 19
|
||||||
|
CreateSemaphore: 21
|
||||||
|
CreateThread: 8
|
||||||
|
CreateTimer: 26
|
||||||
|
DuplicateHandle: 39
|
||||||
|
ExitProcess: 3
|
||||||
|
ExitThread: 9
|
||||||
|
GetCurrentProcessorNumber: 17
|
||||||
|
GetHandleInfo: 41
|
||||||
|
GetProcessId: 53
|
||||||
|
GetProcessIdOfThread: 54
|
||||||
|
GetProcessIdealProcessor: 6
|
||||||
|
GetProcessInfo: 43
|
||||||
|
GetResourceLimit: 56
|
||||||
|
GetResourceLimitCurrentValues: 58
|
||||||
|
GetResourceLimitLimitValues: 57
|
||||||
|
GetSystemInfo: 42
|
||||||
|
GetSystemTick: 40
|
||||||
|
GetThreadContext: 59
|
||||||
|
GetThreadId: 55
|
||||||
|
GetThreadIdealProcessor: 15
|
||||||
|
GetThreadInfo: 44
|
||||||
|
GetThreadPriority: 11
|
||||||
|
MapMemoryBlock: 31
|
||||||
|
OutputDebugString: 61
|
||||||
|
QueryMemory: 2
|
||||||
|
ReleaseMutex: 20
|
||||||
|
ReleaseSemaphore: 22
|
||||||
|
SendSyncRequest1: 46
|
||||||
|
SendSyncRequest2: 47
|
||||||
|
SendSyncRequest3: 48
|
||||||
|
SendSyncRequest4: 49
|
||||||
|
SendSyncRequest: 50
|
||||||
|
SetThreadPriority: 12
|
||||||
|
SetTimer: 27
|
||||||
|
SignalEvent: 24
|
||||||
|
SleepThread: 10
|
||||||
|
UnmapMemoryBlock: 32
|
||||||
|
WaitSynchronization1: 36
|
||||||
|
WaitSynchronizationN: 37
|
||||||
|
Backdoor: 123
|
||||||
|
|
||||||
|
# Service List
|
||||||
|
# Maximum 34 services (32 if firmware is prior to 9.3.0)
|
||||||
|
ServiceAccessControl:
|
||||||
|
- cfg:u
|
||||||
|
- fs:USER
|
||||||
|
- gsp::Gpu
|
||||||
|
- hid:USER
|
||||||
|
- ndm:u
|
||||||
|
- pxi:dev
|
||||||
|
- APT:U
|
||||||
|
- ac:u
|
||||||
|
- act:u
|
||||||
|
- am:net
|
||||||
|
- boss:U
|
||||||
|
- cam:u
|
||||||
|
- cecd:u
|
||||||
|
- dsp::DSP
|
||||||
|
- frd:u
|
||||||
|
- http:C
|
||||||
|
- ir:USER
|
||||||
|
- ir:u
|
||||||
|
- ir:rst
|
||||||
|
- ldr:ro
|
||||||
|
- mic:u
|
||||||
|
- news:u
|
||||||
|
- nim:aoc
|
||||||
|
- nwm::UDS
|
||||||
|
- ptm:u
|
||||||
|
- qtm:u
|
||||||
|
- soc:U
|
||||||
|
- ssl:C
|
||||||
|
- y2r:u
|
||||||
|
- gsp::Lcd
|
||||||
|
|
||||||
|
|
||||||
|
SystemControlInfo:
|
||||||
|
SaveDataSize: 0K
|
||||||
|
RemasterVersion: 0
|
||||||
|
StackSize: 0x40000
|
||||||
|
|
||||||
|
# Modules that run services listed above should be included below
|
||||||
|
# Maximum 48 dependencies
|
||||||
|
# If a module is listed that isn't present on the 3DS, the title will get stuck at the logo (3ds waves)
|
||||||
|
# So act, nfc and qtm are commented for 4.x support. Uncomment if you need these.
|
||||||
|
# <module name>:<module titleid>
|
||||||
|
Dependency:
|
||||||
|
ac: 0x0004013000002402
|
||||||
|
#act: 0x0004013000003802
|
||||||
|
am: 0x0004013000001502
|
||||||
|
boss: 0x0004013000003402
|
||||||
|
camera: 0x0004013000001602
|
||||||
|
cecd: 0x0004013000002602
|
||||||
|
cfg: 0x0004013000001702
|
||||||
|
codec: 0x0004013000001802
|
||||||
|
csnd: 0x0004013000002702
|
||||||
|
dlp: 0x0004013000002802
|
||||||
|
dsp: 0x0004013000001a02
|
||||||
|
friends: 0x0004013000003202
|
||||||
|
gpio: 0x0004013000001b02
|
||||||
|
gsp: 0x0004013000001c02
|
||||||
|
hid: 0x0004013000001d02
|
||||||
|
http: 0x0004013000002902
|
||||||
|
i2c: 0x0004013000001e02
|
||||||
|
ir: 0x0004013000003302
|
||||||
|
mcu: 0x0004013000001f02
|
||||||
|
mic: 0x0004013000002002
|
||||||
|
ndm: 0x0004013000002b02
|
||||||
|
news: 0x0004013000003502
|
||||||
|
#nfc: 0x0004013000004002
|
||||||
|
nim: 0x0004013000002c02
|
||||||
|
nwm: 0x0004013000002d02
|
||||||
|
pdn: 0x0004013000002102
|
||||||
|
ps: 0x0004013000003102
|
||||||
|
ptm: 0x0004013000002202
|
||||||
|
#qtm: 0x0004013020004202
|
||||||
|
ro: 0x0004013000003702
|
||||||
|
socket: 0x0004013000002e02
|
||||||
|
spi: 0x0004013000002302
|
||||||
|
ssl: 0x0004013000002f02
|
87
backends/platform/3ds/config.cpp
Normal file
87
backends/platform/3ds/config.cpp
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* 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 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "osystem.h"
|
||||||
|
#include "options-dialog.h"
|
||||||
|
#include "common/config-manager.h"
|
||||||
|
#include <3ds.h>
|
||||||
|
|
||||||
|
namespace _3DS {
|
||||||
|
|
||||||
|
Config config;
|
||||||
|
static Common::String prefix = "3ds_";
|
||||||
|
|
||||||
|
static bool confGetBool(Common::String key, bool defaultVal) {
|
||||||
|
if (ConfMan.hasKey(prefix + key))
|
||||||
|
return ConfMan.getBool(prefix + key);
|
||||||
|
return defaultVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void confSetBool(Common::String key, bool val) {
|
||||||
|
ConfMan.setBool(prefix + key, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int confGetInt(Common::String key, int defaultVal) {
|
||||||
|
if (ConfMan.hasKey(prefix + key))
|
||||||
|
return ConfMan.getInt(prefix + key);
|
||||||
|
return defaultVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void confSetInt(Common::String key, int val) {
|
||||||
|
ConfMan.setInt(prefix + key, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadConfig() {
|
||||||
|
config.showCursor = confGetBool("showcursor", true);
|
||||||
|
config.snapToBorder = confGetBool("snaptoborder", true);
|
||||||
|
config.stretchToFit = confGetBool("stretchtofit", false);
|
||||||
|
config.sensitivity = confGetInt("sensitivity", -5);
|
||||||
|
config.screen = confGetInt("screen", kScreenBoth);
|
||||||
|
|
||||||
|
// Turn off the backlight of any screen not used
|
||||||
|
if (R_SUCCEEDED(gspLcdInit())) {
|
||||||
|
if (config.screen == kScreenTop) {
|
||||||
|
GSPLCD_PowerOnBacklight(GSPLCD_SCREEN_TOP);
|
||||||
|
GSPLCD_PowerOffBacklight(GSPLCD_SCREEN_BOTTOM);
|
||||||
|
} else if (config.screen == kScreenBottom) {
|
||||||
|
GSPLCD_PowerOnBacklight(GSPLCD_SCREEN_BOTTOM);
|
||||||
|
GSPLCD_PowerOffBacklight(GSPLCD_SCREEN_TOP);
|
||||||
|
} else
|
||||||
|
GSPLCD_PowerOnBacklight(GSPLCD_SCREEN_BOTH);
|
||||||
|
gspLcdExit();
|
||||||
|
}
|
||||||
|
|
||||||
|
OSystem_3DS *osys = (OSystem_3DS *)g_system;
|
||||||
|
osys->updateConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveConfig() {
|
||||||
|
confSetBool("showcursor", config.showCursor);
|
||||||
|
confSetBool("snaptoborder", config.snapToBorder);
|
||||||
|
confSetBool("stretchtofit", config.stretchToFit);
|
||||||
|
confSetInt("sensitivity", config.sensitivity);
|
||||||
|
confSetInt("screen", config.screen);
|
||||||
|
ConfMan.flushToDisk();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace _3DS
|
45
backends/platform/3ds/config.h
Normal file
45
backends/platform/3ds/config.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* 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 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CONFIG_3DS_H
|
||||||
|
#define CONFIG_3DS_H
|
||||||
|
|
||||||
|
#include "common/str.h"
|
||||||
|
|
||||||
|
namespace _3DS {
|
||||||
|
|
||||||
|
struct Config {
|
||||||
|
bool showCursor;
|
||||||
|
bool snapToBorder;
|
||||||
|
bool stretchToFit;
|
||||||
|
int sensitivity;
|
||||||
|
int screen;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern Config config;
|
||||||
|
|
||||||
|
void loadConfig();
|
||||||
|
void saveConfig();
|
||||||
|
|
||||||
|
} // namespace _3DS
|
||||||
|
|
||||||
|
#endif // CONFIG_3DS_H
|
46
backends/platform/3ds/gui.cpp
Normal file
46
backends/platform/3ds/gui.cpp
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* 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 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "backends/platform/3ds/gui.h"
|
||||||
|
#include "common/system.h"
|
||||||
|
|
||||||
|
StatusMessageDialog* StatusMessageDialog::_opened = 0;
|
||||||
|
|
||||||
|
StatusMessageDialog::StatusMessageDialog(const Common::String &message, uint32 duration)
|
||||||
|
: MessageDialog(message, 0, 0) {
|
||||||
|
_timer = g_system->getMillis() + duration;
|
||||||
|
if (_opened)
|
||||||
|
_opened->close();
|
||||||
|
_opened = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatusMessageDialog::handleTickle() {
|
||||||
|
MessageDialog::handleTickle();
|
||||||
|
if (g_system->getMillis() > _timer)
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatusMessageDialog::close() {
|
||||||
|
GUI::Dialog::close();
|
||||||
|
if (_opened)
|
||||||
|
_opened = 0;
|
||||||
|
}
|
41
backends/platform/3ds/gui.h
Normal file
41
backends/platform/3ds/gui.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* 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 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GUI_3DS_H
|
||||||
|
#define GUI_3DS_H
|
||||||
|
|
||||||
|
#include "gui/message.h"
|
||||||
|
|
||||||
|
class StatusMessageDialog : public GUI::MessageDialog {
|
||||||
|
public:
|
||||||
|
StatusMessageDialog(const Common::String &message, uint32 duration);
|
||||||
|
|
||||||
|
void handleTickle();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void close();
|
||||||
|
|
||||||
|
uint32 _timer;
|
||||||
|
static StatusMessageDialog* _opened;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // GUI_3DS_H
|
54
backends/platform/3ds/main.cpp
Normal file
54
backends/platform/3ds/main.cpp
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* 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 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "osystem.h"
|
||||||
|
#include <3ds.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
// Initialize basic libctru stuff
|
||||||
|
gfxInitDefault();
|
||||||
|
cfguInit();
|
||||||
|
osSetSpeedupEnable(true);
|
||||||
|
// consoleInit(GFX_TOP, NULL);
|
||||||
|
|
||||||
|
g_system = new _3DS::OSystem_3DS();
|
||||||
|
assert(g_system);
|
||||||
|
|
||||||
|
// Invoke the actual ScummVM main entry point
|
||||||
|
// if (argc > 2)
|
||||||
|
// res = scummvm_main(argc-2, &argv[2]);
|
||||||
|
// else
|
||||||
|
// res = scummvm_main(argc, argv);
|
||||||
|
scummvm_main(0, nullptr);
|
||||||
|
|
||||||
|
delete dynamic_cast<_3DS::OSystem_3DS*>(g_system);
|
||||||
|
|
||||||
|
// Turn on both screen backlights before exiting.
|
||||||
|
if (R_SUCCEEDED(gspLcdInit())) {
|
||||||
|
GSPLCD_PowerOnBacklight(GSPLCD_SCREEN_BOTH);
|
||||||
|
gspLcdExit();
|
||||||
|
}
|
||||||
|
|
||||||
|
cfguExit();
|
||||||
|
gfxExit();
|
||||||
|
return 0;
|
||||||
|
}
|
18
backends/platform/3ds/module.mk
Normal file
18
backends/platform/3ds/module.mk
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
MODULE := backends/platform/3ds
|
||||||
|
|
||||||
|
MODULE_OBJS := \
|
||||||
|
main.o \
|
||||||
|
shader.shbin.o \
|
||||||
|
sprite.o \
|
||||||
|
gui.o \
|
||||||
|
config.o \
|
||||||
|
options-dialog.o \
|
||||||
|
osystem.o \
|
||||||
|
osystem-graphics.o \
|
||||||
|
osystem-audio.o \
|
||||||
|
osystem-events.o
|
||||||
|
|
||||||
|
# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS.
|
||||||
|
MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS))
|
||||||
|
OBJS := $(MODULE_OBJS) $(OBJS)
|
||||||
|
MODULE_DIRS += $(sort $(dir $(MODULE_OBJS)))
|
98
backends/platform/3ds/options-dialog.cpp
Normal file
98
backends/platform/3ds/options-dialog.cpp
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* 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 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "options-dialog.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "gui/dialog.h"
|
||||||
|
#include "gui/gui-manager.h"
|
||||||
|
#include "gui/widgets/list.h"
|
||||||
|
#include "gui/widgets/tab.h"
|
||||||
|
#include "osystem.h"
|
||||||
|
#include "engines/scumm/scumm.h"
|
||||||
|
#include "gui/widgets/popup.h"
|
||||||
|
|
||||||
|
#include "common/translation.h"
|
||||||
|
|
||||||
|
namespace _3DS {
|
||||||
|
|
||||||
|
bool optionMenuOpened = false;
|
||||||
|
|
||||||
|
OptionsDialog::OptionsDialog() : GUI::Dialog(20, 20, 280, 200) {
|
||||||
|
|
||||||
|
optionMenuOpened = true;
|
||||||
|
|
||||||
|
new GUI::ButtonWidget(this, 120, 180, 72, 16, _("~C~lose"), 0, GUI::kCloseCmd);
|
||||||
|
new GUI::ButtonWidget(this, 200, 180, 72, 16, _("~S~ave"), 0, GUI::kOKCmd);
|
||||||
|
|
||||||
|
_showCursorCheckbox = new GUI::CheckboxWidget(this, 5, 5, 130, 20, _("Show mouse cursor"), 0, 0, 'T');
|
||||||
|
_showCursorCheckbox->setState(config.showCursor);
|
||||||
|
|
||||||
|
_snapToBorderCheckbox = new GUI::CheckboxWidget(this, 5, 22, 130, 20, _("Snap to edges"), 0, 0, 'T');
|
||||||
|
_snapToBorderCheckbox->setState(config.snapToBorder);
|
||||||
|
|
||||||
|
_stretchToFitCheckbox = new GUI::CheckboxWidget(this, 140, 5, 130, 20, _("Stretch to fit"), 0, 0, 'T');
|
||||||
|
_stretchToFitCheckbox->setState(config.stretchToFit);
|
||||||
|
|
||||||
|
new GUI::StaticTextWidget(this, 0, 60, 110, 15, _("Use Screen:"), Graphics::kTextAlignRight);
|
||||||
|
_screenRadioGroup = new GUI::RadiobuttonGroup(this, kScreenRadioGroup);
|
||||||
|
_screenTopRadioWidget = new GUI::RadiobuttonWidget(this, 120, 50, 60, 20, _screenRadioGroup, kScreenTop, _("Top"));
|
||||||
|
_screenBottomRadioWidget = new GUI::RadiobuttonWidget(this, 190, 50, 80, 20, _screenRadioGroup, kScreenBottom, _("Bottom"));
|
||||||
|
_screenBothRadioWidget = new GUI::RadiobuttonWidget(this, 155, 70, 80, 20, _screenRadioGroup, kScreenBoth, _("Both"));
|
||||||
|
_screenRadioGroup->setValue(config.screen);
|
||||||
|
|
||||||
|
new GUI::StaticTextWidget(this, 0, 100, 110, 15, _("C-Pad Sensitivity:"), Graphics::kTextAlignRight);
|
||||||
|
_sensitivity = new GUI::SliderWidget(this, 115, 100, 160, 15, "TODO: Add tooltip", 1);
|
||||||
|
_sensitivity->setMinValue(-15);
|
||||||
|
_sensitivity->setMaxValue(30);
|
||||||
|
_sensitivity->setValue(config.sensitivity);
|
||||||
|
_sensitivity->setFlags(GUI::WIDGET_CLEARBG);
|
||||||
|
}
|
||||||
|
|
||||||
|
OptionsDialog::~OptionsDialog() {
|
||||||
|
optionMenuOpened = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OptionsDialog::updateConfigManager() {
|
||||||
|
config.showCursor = _showCursorCheckbox->getState();
|
||||||
|
config.snapToBorder = _snapToBorderCheckbox->getState();
|
||||||
|
config.stretchToFit = _stretchToFitCheckbox->getState();
|
||||||
|
config.sensitivity = _sensitivity->getValue();
|
||||||
|
config.screen = _screenRadioGroup->getValue();
|
||||||
|
saveConfig();
|
||||||
|
loadConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OptionsDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) {
|
||||||
|
switch(cmd) {
|
||||||
|
case GUI::kOKCmd:
|
||||||
|
updateConfigManager();
|
||||||
|
// Fall through
|
||||||
|
case GUI::kCloseCmd:
|
||||||
|
close();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Dialog::handleCommand(sender, cmd, data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace _3DS
|
70
backends/platform/3ds/options-dialog.h
Normal file
70
backends/platform/3ds/options-dialog.h
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* 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 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OPTIONS_DIALOG_3DS_H
|
||||||
|
#define OPTIONS_DIALOG_3DS_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "common/scummsys.h"
|
||||||
|
#include "common/str.h"
|
||||||
|
#include "gui/object.h"
|
||||||
|
#include "gui/widget.h"
|
||||||
|
#include "gui/dialog.h"
|
||||||
|
#include "gui/widgets/tab.h"
|
||||||
|
#include "scumm/dialogs.h"
|
||||||
|
|
||||||
|
namespace _3DS {
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kSave = 0x10000000,
|
||||||
|
kScreenRadioGroup,
|
||||||
|
kScreenTop,
|
||||||
|
kScreenBottom,
|
||||||
|
kScreenBoth,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern bool optionMenuOpened;
|
||||||
|
|
||||||
|
class OptionsDialog : public GUI::Dialog {
|
||||||
|
|
||||||
|
public:
|
||||||
|
OptionsDialog();
|
||||||
|
~OptionsDialog();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
|
||||||
|
void updateConfigManager();
|
||||||
|
|
||||||
|
GUI::SliderWidget *_sensitivity;
|
||||||
|
GUI::CheckboxWidget *_showCursorCheckbox;
|
||||||
|
GUI::CheckboxWidget *_snapToBorderCheckbox;
|
||||||
|
GUI::CheckboxWidget *_stretchToFitCheckbox;
|
||||||
|
|
||||||
|
GUI::RadiobuttonGroup *_screenRadioGroup;
|
||||||
|
GUI::RadiobuttonWidget *_screenTopRadioWidget;
|
||||||
|
GUI::RadiobuttonWidget *_screenBottomRadioWidget;
|
||||||
|
GUI::RadiobuttonWidget *_screenBothRadioWidget;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace _3DS
|
||||||
|
|
||||||
|
#endif // OPTIONS_DIALOG_3DS_H
|
110
backends/platform/3ds/osystem-audio.cpp
Normal file
110
backends/platform/3ds/osystem-audio.cpp
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* 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 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "osystem.h"
|
||||||
|
#include "audio/mixer.h"
|
||||||
|
|
||||||
|
namespace _3DS {
|
||||||
|
|
||||||
|
static bool hasAudio = false;
|
||||||
|
|
||||||
|
static void audioThreadFunc(void *arg) {
|
||||||
|
Audio::MixerImpl *mixer = (Audio::MixerImpl *)arg;
|
||||||
|
OSystem_3DS *osys = (OSystem_3DS *)g_system;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
const int channel = 0;
|
||||||
|
int bufferIndex = 0;
|
||||||
|
const int bufferCount = 3;
|
||||||
|
const int bufferSize = 80000; // Can't be too small, based on delayMillis duration
|
||||||
|
const int sampleRate = mixer->getOutputRate();
|
||||||
|
int sampleLen = 0;
|
||||||
|
uint32 lastTime = osys->getMillis(true);
|
||||||
|
uint32 time = lastTime;
|
||||||
|
ndspWaveBuf buffers[bufferCount];
|
||||||
|
|
||||||
|
for (i = 0; i < bufferCount; ++i) {
|
||||||
|
memset(&buffers[i], 0, sizeof(ndspWaveBuf));
|
||||||
|
buffers[i].data_vaddr = linearAlloc(bufferSize);
|
||||||
|
buffers[i].looping = false;
|
||||||
|
buffers[i].status = NDSP_WBUF_FREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ndspChnReset(channel);
|
||||||
|
ndspChnSetInterp(channel, NDSP_INTERP_LINEAR);
|
||||||
|
ndspChnSetRate(channel, sampleRate);
|
||||||
|
ndspChnSetFormat(channel, NDSP_FORMAT_STEREO_PCM16);
|
||||||
|
|
||||||
|
while (!osys->exiting) {
|
||||||
|
osys->delayMillis(100); // Note: Increasing the delay requires a bigger buffer
|
||||||
|
|
||||||
|
time = osys->getMillis(true);
|
||||||
|
sampleLen = (time - lastTime) * 22 * 4; // sampleRate / 1000 * channelCount * sizeof(int16);
|
||||||
|
lastTime = time;
|
||||||
|
|
||||||
|
if (!osys->sleeping && sampleLen > 0) {
|
||||||
|
bufferIndex++;
|
||||||
|
bufferIndex %= bufferCount;
|
||||||
|
ndspWaveBuf *buf = &buffers[bufferIndex];
|
||||||
|
|
||||||
|
buf->nsamples = mixer->mixCallback(buf->data_adpcm, sampleLen);
|
||||||
|
if (buf->nsamples > 0) {
|
||||||
|
DSP_FlushDataCache(buf->data_vaddr, bufferSize);
|
||||||
|
ndspChnWaveBufAdd(channel, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < bufferCount; ++i)
|
||||||
|
linearFree(buffers[i].data_pcm8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::initAudio() {
|
||||||
|
_mixer = new Audio::MixerImpl(this, 22050);
|
||||||
|
|
||||||
|
hasAudio = R_SUCCEEDED(ndspInit());
|
||||||
|
_mixer->setReady(false);
|
||||||
|
|
||||||
|
if (hasAudio) {
|
||||||
|
s32 prio = 0;
|
||||||
|
svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
|
||||||
|
audioThread = threadCreate(&audioThreadFunc, _mixer, 32 * 1048, prio - 1, -2, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::destroyAudio() {
|
||||||
|
if (hasAudio) {
|
||||||
|
threadJoin(audioThread, U64_MAX);
|
||||||
|
threadFree(audioThread);
|
||||||
|
ndspExit();
|
||||||
|
}
|
||||||
|
|
||||||
|
delete _mixer;
|
||||||
|
_mixer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Audio::Mixer *OSystem_3DS::getMixer() {
|
||||||
|
assert(_mixer);
|
||||||
|
return _mixer;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace _3DS
|
302
backends/platform/3ds/osystem-events.cpp
Normal file
302
backends/platform/3ds/osystem-events.cpp
Normal file
|
@ -0,0 +1,302 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* 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 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "backends/timer/default/default-timer.h"
|
||||||
|
#include "engines/engine.h"
|
||||||
|
#include "gui.h"
|
||||||
|
#include "options-dialog.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "osystem.h"
|
||||||
|
|
||||||
|
namespace _3DS {
|
||||||
|
|
||||||
|
static Common::Mutex *eventMutex;
|
||||||
|
static InputMode inputMode = MODE_DRAG;
|
||||||
|
static aptHookCookie cookie;
|
||||||
|
static bool optionMenuOpening = false;
|
||||||
|
static Common::String messageOSD;
|
||||||
|
static bool showMessageOSD = false;
|
||||||
|
|
||||||
|
static void pushEventQueue(Common::Queue<Common::Event> *queue, Common::Event &event) {
|
||||||
|
Common::StackLock lock(*eventMutex);
|
||||||
|
queue->push(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void eventThreadFunc(void *arg) {
|
||||||
|
OSystem_3DS *osys = (OSystem_3DS *)g_system;
|
||||||
|
auto eventQueue = (Common::Queue<Common::Event> *)arg;
|
||||||
|
|
||||||
|
uint32 touchStartTime = osys->getMillis();
|
||||||
|
touchPosition lastTouch = {0, 0};
|
||||||
|
bool isRightClick = false;
|
||||||
|
float cursorX = 0;
|
||||||
|
float cursorY = 0;
|
||||||
|
float cursorDeltaX = 0;
|
||||||
|
float cursorDeltaY = 0;
|
||||||
|
int circleDeadzone = 20;
|
||||||
|
int borderSnapZone = 6;
|
||||||
|
Common::Event event;
|
||||||
|
|
||||||
|
while (!osys->exiting) {
|
||||||
|
do {
|
||||||
|
osys->delayMillis(10);
|
||||||
|
} while (osys->sleeping && !osys->exiting);
|
||||||
|
|
||||||
|
hidScanInput();
|
||||||
|
touchPosition touch;
|
||||||
|
circlePosition circle;
|
||||||
|
u32 held = hidKeysHeld();
|
||||||
|
u32 keysPressed = hidKeysDown();
|
||||||
|
u32 keysReleased = hidKeysUp();
|
||||||
|
|
||||||
|
// C-Pad used to control the cursor
|
||||||
|
hidCircleRead(&circle);
|
||||||
|
if (circle.dx < circleDeadzone && circle.dx > -circleDeadzone)
|
||||||
|
circle.dx = 0;
|
||||||
|
if (circle.dy < circleDeadzone && circle.dy > -circleDeadzone)
|
||||||
|
circle.dy = 0;
|
||||||
|
cursorDeltaX = (0.0002f + config.sensitivity / 100000.f) * circle.dx * abs(circle.dx);
|
||||||
|
cursorDeltaY = (0.0002f + config.sensitivity / 100000.f) * circle.dy * abs(circle.dy);
|
||||||
|
|
||||||
|
// Touch screen events
|
||||||
|
if (held & KEY_TOUCH) {
|
||||||
|
hidTouchRead(&touch);
|
||||||
|
if (config.snapToBorder) {
|
||||||
|
if (touch.px < borderSnapZone)
|
||||||
|
touch.px = 0;
|
||||||
|
if (touch.px > 319 - borderSnapZone)
|
||||||
|
touch.px = 319;
|
||||||
|
if (touch.py < borderSnapZone)
|
||||||
|
touch.py = 0;
|
||||||
|
if (touch.py > 239 - borderSnapZone)
|
||||||
|
touch.py = 239;
|
||||||
|
}
|
||||||
|
cursorX = touch.px;
|
||||||
|
cursorY = touch.py;
|
||||||
|
osys->transformPoint(touch);
|
||||||
|
|
||||||
|
osys->warpMouse(touch.px, touch.py);
|
||||||
|
event.mouse.x = touch.px;
|
||||||
|
event.mouse.y = touch.py;
|
||||||
|
|
||||||
|
if (keysPressed & KEY_TOUCH) {
|
||||||
|
touchStartTime = osys->getMillis();
|
||||||
|
isRightClick = (held & KEY_X || held & KEY_DUP);
|
||||||
|
if (inputMode == MODE_DRAG) {
|
||||||
|
event.type = isRightClick ? Common::EVENT_RBUTTONDOWN : Common::EVENT_LBUTTONDOWN;
|
||||||
|
pushEventQueue(eventQueue, event);
|
||||||
|
}
|
||||||
|
} else if (touch.px != lastTouch.px || touch.py != lastTouch.py) {
|
||||||
|
event.type = Common::EVENT_MOUSEMOVE;
|
||||||
|
pushEventQueue(eventQueue, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
lastTouch = touch;
|
||||||
|
} else if (keysReleased & KEY_TOUCH) {
|
||||||
|
event.mouse.x = lastTouch.px;
|
||||||
|
event.mouse.y = lastTouch.py;
|
||||||
|
if (inputMode == MODE_DRAG) {
|
||||||
|
event.type = isRightClick ? Common::EVENT_RBUTTONUP : Common::EVENT_LBUTTONUP;
|
||||||
|
pushEventQueue(eventQueue, event);
|
||||||
|
} else if (osys->getMillis() - touchStartTime < 200) {
|
||||||
|
// Process click in MODE_HOVER
|
||||||
|
event.type = Common::EVENT_MOUSEMOVE;
|
||||||
|
pushEventQueue(eventQueue, event);
|
||||||
|
event.type = isRightClick ? Common::EVENT_RBUTTONDOWN : Common::EVENT_LBUTTONDOWN;
|
||||||
|
pushEventQueue(eventQueue, event);
|
||||||
|
event.type = isRightClick ? Common::EVENT_RBUTTONUP : Common::EVENT_LBUTTONUP;
|
||||||
|
pushEventQueue(eventQueue, event);
|
||||||
|
}
|
||||||
|
} else if (cursorDeltaX != 0 || cursorDeltaY != 0) {
|
||||||
|
cursorX += cursorDeltaX;
|
||||||
|
cursorY -= cursorDeltaY;
|
||||||
|
if (cursorX < 0) cursorX = 0;
|
||||||
|
if (cursorY < 0) cursorY = 0;
|
||||||
|
if (cursorX > 320) cursorX = 320;
|
||||||
|
if (cursorY > 240) cursorY = 240;
|
||||||
|
lastTouch.px = cursorX;
|
||||||
|
lastTouch.py = cursorY;
|
||||||
|
osys->transformPoint(lastTouch);
|
||||||
|
osys->warpMouse(lastTouch.px, lastTouch.py);
|
||||||
|
event.mouse.x = lastTouch.px;
|
||||||
|
event.mouse.y = lastTouch.py;
|
||||||
|
event.type = Common::EVENT_MOUSEMOVE;
|
||||||
|
pushEventQueue(eventQueue, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Button events
|
||||||
|
if (keysPressed & KEY_R) {
|
||||||
|
if (inputMode == MODE_DRAG) {
|
||||||
|
inputMode = MODE_HOVER;
|
||||||
|
osys->displayMessageOnOSD("Hover Mode");
|
||||||
|
} else {
|
||||||
|
inputMode = MODE_DRAG;
|
||||||
|
osys->displayMessageOnOSD("Drag Mode");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (keysPressed & KEY_A || keysPressed & KEY_DLEFT || keysReleased & KEY_A || keysReleased & KEY_DLEFT) {
|
||||||
|
// SIMULATE LEFT CLICK
|
||||||
|
event.mouse.x = lastTouch.px;
|
||||||
|
event.mouse.y = lastTouch.py;
|
||||||
|
if (keysPressed & KEY_A || keysPressed & KEY_DLEFT)
|
||||||
|
event.type = Common::EVENT_LBUTTONDOWN;
|
||||||
|
else
|
||||||
|
event.type = Common::EVENT_LBUTTONUP;
|
||||||
|
pushEventQueue(eventQueue, event);
|
||||||
|
}
|
||||||
|
if (keysPressed & KEY_X || keysPressed & KEY_DUP || keysReleased & KEY_X || keysReleased & KEY_DUP) {
|
||||||
|
// SIMULATE RIGHT CLICK
|
||||||
|
event.mouse.x = lastTouch.px;
|
||||||
|
event.mouse.y = lastTouch.py;
|
||||||
|
if (keysPressed & KEY_X || keysPressed & KEY_DUP)
|
||||||
|
event.type = Common::EVENT_RBUTTONDOWN;
|
||||||
|
else
|
||||||
|
event.type = Common::EVENT_RBUTTONUP;
|
||||||
|
pushEventQueue(eventQueue, event);
|
||||||
|
}
|
||||||
|
if (keysPressed & KEY_L) {
|
||||||
|
event.type = Common::EVENT_VIRTUAL_KEYBOARD;
|
||||||
|
pushEventQueue(eventQueue, event);
|
||||||
|
}
|
||||||
|
if (keysPressed & KEY_START) {
|
||||||
|
event.type = Common::EVENT_MAINMENU;
|
||||||
|
pushEventQueue(eventQueue, event);
|
||||||
|
}
|
||||||
|
if (keysPressed & KEY_SELECT) {
|
||||||
|
if (!optionMenuOpened)
|
||||||
|
optionMenuOpening = true;
|
||||||
|
}
|
||||||
|
if (keysPressed & KEY_B || keysReleased & KEY_B || keysPressed & KEY_DDOWN || keysReleased & KEY_DDOWN) {
|
||||||
|
if (keysPressed & KEY_B || keysPressed & KEY_DDOWN)
|
||||||
|
event.type = Common::EVENT_KEYDOWN;
|
||||||
|
else
|
||||||
|
event.type = Common::EVENT_KEYUP;
|
||||||
|
event.kbd.keycode = Common::KEYCODE_ESCAPE;
|
||||||
|
event.kbd.ascii = Common::ASCII_ESCAPE;
|
||||||
|
event.kbd.flags = 0;
|
||||||
|
pushEventQueue(eventQueue, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: EVENT_PREDICTIVE_DIALOG
|
||||||
|
// EVENT_SCREEN_CHANGED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void aptHookFunc(APT_HookType hookType, void *param) {
|
||||||
|
OSystem_3DS *osys = (OSystem_3DS *)g_system;
|
||||||
|
|
||||||
|
switch (hookType) {
|
||||||
|
case APTHOOK_ONSUSPEND:
|
||||||
|
case APTHOOK_ONSLEEP:
|
||||||
|
if (g_engine)
|
||||||
|
g_engine->pauseEngine(true);
|
||||||
|
osys->sleeping = true;
|
||||||
|
if (R_SUCCEEDED(gspLcdInit())) {
|
||||||
|
GSPLCD_PowerOnBacklight(GSPLCD_SCREEN_BOTH);
|
||||||
|
gspLcdExit();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case APTHOOK_ONRESTORE:
|
||||||
|
case APTHOOK_ONWAKEUP:
|
||||||
|
if (g_engine)
|
||||||
|
g_engine->pauseEngine(false);
|
||||||
|
osys->sleeping = false;
|
||||||
|
loadConfig();
|
||||||
|
break;
|
||||||
|
default: {
|
||||||
|
Common::StackLock lock(*eventMutex);
|
||||||
|
Common::Event event;
|
||||||
|
event.type = Common::EVENT_QUIT;
|
||||||
|
g_system->getEventManager()->pushEvent(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void timerThreadFunc(void *arg) {
|
||||||
|
OSystem_3DS *osys = (OSystem_3DS *)arg;
|
||||||
|
DefaultTimerManager *tm = (DefaultTimerManager *)osys->getTimerManager();
|
||||||
|
while (!osys->exiting) {
|
||||||
|
g_system->delayMillis(10);
|
||||||
|
tm->handler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::initEvents() {
|
||||||
|
eventMutex = new Common::Mutex();
|
||||||
|
s32 prio = 0;
|
||||||
|
svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
|
||||||
|
_timerThread = threadCreate(&timerThreadFunc, this, 32 * 1024, prio - 1, -2, false);
|
||||||
|
_eventThread = threadCreate(&eventThreadFunc, &_eventQueue, 32 * 1024, prio - 1, -2, false);
|
||||||
|
|
||||||
|
aptHook(&cookie, aptHookFunc, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::destroyEvents() {
|
||||||
|
threadJoin(_timerThread, U64_MAX);
|
||||||
|
threadFree(_timerThread);
|
||||||
|
|
||||||
|
threadJoin(_eventThread, U64_MAX);
|
||||||
|
threadFree(_eventThread);
|
||||||
|
delete eventMutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::transformPoint(touchPosition &point) {
|
||||||
|
if (!_overlayVisible) {
|
||||||
|
point.px = static_cast<float>(point.px) / _gameBottomTexture.getScaleX() - _gameBottomX;
|
||||||
|
point.py = static_cast<float>(point.py) / _gameBottomTexture.getScaleY() - _gameBottomY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::displayMessageOnOSD(const char *msg) {
|
||||||
|
messageOSD = msg;
|
||||||
|
showMessageOSD = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OSystem_3DS::pollEvent(Common::Event &event) {
|
||||||
|
if (showMessageOSD) {
|
||||||
|
showMessageOSD = false;
|
||||||
|
StatusMessageDialog dialog(messageOSD, 800);
|
||||||
|
dialog.runModal();
|
||||||
|
}
|
||||||
|
|
||||||
|
aptMainLoop(); // Call apt hook when necessary
|
||||||
|
|
||||||
|
if (optionMenuOpening) {
|
||||||
|
optionMenuOpening = false;
|
||||||
|
OptionsDialog dialog;
|
||||||
|
if (g_engine)
|
||||||
|
g_engine->pauseEngine(true);
|
||||||
|
dialog.runModal();
|
||||||
|
if (g_engine)
|
||||||
|
g_engine->pauseEngine(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Common::StackLock lock(*eventMutex);
|
||||||
|
|
||||||
|
if (_eventQueue.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
event = _eventQueue.pop();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace _3DS
|
517
backends/platform/3ds/osystem-graphics.cpp
Normal file
517
backends/platform/3ds/osystem-graphics.cpp
Normal file
|
@ -0,0 +1,517 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* 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 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "backends/platform/3ds/osystem.h"
|
||||||
|
#include "backends/platform/3ds/shader_shbin.h"
|
||||||
|
#include "common/rect.h"
|
||||||
|
#include "options-dialog.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
// Used to transfer the final rendered display to the framebuffer
|
||||||
|
#define DISPLAY_TRANSFER_FLAGS \
|
||||||
|
(GX_TRANSFER_FLIP_VERT(0) | GX_TRANSFER_OUT_TILED(0) | \
|
||||||
|
GX_TRANSFER_RAW_COPY(0) | GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | \
|
||||||
|
GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) | \
|
||||||
|
GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO))
|
||||||
|
|
||||||
|
namespace _3DS {
|
||||||
|
|
||||||
|
void OSystem_3DS::initGraphics() {
|
||||||
|
_pfGame = Graphics::PixelFormat::createFormatCLUT8();
|
||||||
|
_pfGameTexture = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
|
||||||
|
|
||||||
|
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
|
||||||
|
|
||||||
|
// Initialize the render targets
|
||||||
|
_renderTargetTop =
|
||||||
|
C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
|
||||||
|
C3D_RenderTargetSetClear(_renderTargetTop, C3D_CLEAR_ALL, 0x0000000, 0);
|
||||||
|
C3D_RenderTargetSetOutput(_renderTargetTop, GFX_TOP, GFX_LEFT,
|
||||||
|
DISPLAY_TRANSFER_FLAGS);
|
||||||
|
|
||||||
|
_renderTargetBottom =
|
||||||
|
C3D_RenderTargetCreate(240, 320, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
|
||||||
|
C3D_RenderTargetSetClear(_renderTargetBottom, C3D_CLEAR_ALL, 0x00000000, 0);
|
||||||
|
C3D_RenderTargetSetOutput(_renderTargetBottom, GFX_BOTTOM, GFX_LEFT,
|
||||||
|
DISPLAY_TRANSFER_FLAGS);
|
||||||
|
|
||||||
|
// Load and bind simple default shader (shader.v.pica)
|
||||||
|
_dvlb = DVLB_ParseFile((u32*)shader_shbin, shader_shbin_size);
|
||||||
|
shaderProgramInit(&_program);
|
||||||
|
shaderProgramSetVsh(&_program, &_dvlb->DVLE[0]);
|
||||||
|
C3D_BindProgram(&_program);
|
||||||
|
|
||||||
|
_projectionLocation = shaderInstanceGetUniformLocation(_program.vertexShader, "projection");
|
||||||
|
_modelviewLocation = shaderInstanceGetUniformLocation(_program.vertexShader, "modelView");
|
||||||
|
|
||||||
|
C3D_AttrInfo *attrInfo = C3D_GetAttrInfo();
|
||||||
|
AttrInfo_Init(attrInfo);
|
||||||
|
AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3); // v0=position
|
||||||
|
AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2); // v1=texcoord
|
||||||
|
|
||||||
|
Mtx_OrthoTilt(&_projectionTop, 0.0, 400.0, 240.0, 0.0, 0.0, 1.0);
|
||||||
|
Mtx_OrthoTilt(&_projectionBottom, 0.0, 320.0, 240.0, 0.0, 0.0, 1.0);
|
||||||
|
|
||||||
|
C3D_TexEnv *env = C3D_GetTexEnv(0);
|
||||||
|
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, 0, 0);
|
||||||
|
C3D_TexEnvOp(env, C3D_Both, 0, 0, 0);
|
||||||
|
C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE);
|
||||||
|
|
||||||
|
C3D_DepthTest(false, GPU_GEQUAL, GPU_WRITE_ALL);
|
||||||
|
C3D_CullFace(GPU_CULL_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::destroyGraphics() {
|
||||||
|
_gameScreen.free();
|
||||||
|
_gameTopTexture.free();
|
||||||
|
_gameBottomTexture.free();
|
||||||
|
_overlay.free();
|
||||||
|
|
||||||
|
shaderProgramFree(&_program);
|
||||||
|
DVLB_Free(_dvlb);
|
||||||
|
|
||||||
|
C3D_RenderTargetDelete(_renderTargetTop);
|
||||||
|
C3D_RenderTargetDelete(_renderTargetBottom);
|
||||||
|
|
||||||
|
C3D_Fini();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OSystem_3DS::hasFeature(OSystem::Feature f) {
|
||||||
|
return (f == OSystem::kFeatureCursorPalette ||
|
||||||
|
f == OSystem::kFeatureOverlaySupportsAlpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::setFeatureState(OSystem::Feature f, bool enable) {
|
||||||
|
switch (f) {
|
||||||
|
case OSystem::kFeatureCursorPalette:
|
||||||
|
_cursorPaletteEnabled = enable;
|
||||||
|
flushCursor();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OSystem_3DS::getFeatureState(OSystem::Feature f) {
|
||||||
|
switch (f) {
|
||||||
|
case OSystem::kFeatureCursorPalette:
|
||||||
|
return _cursorPaletteEnabled;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const OSystem::GraphicsMode *
|
||||||
|
OSystem_3DS::getSupportedGraphicsModes() const {
|
||||||
|
return s_graphicsModes;
|
||||||
|
}
|
||||||
|
|
||||||
|
int OSystem_3DS::getDefaultGraphicsMode() const {
|
||||||
|
return GFX_LINEAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OSystem_3DS::setGraphicsMode(int mode) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::resetGraphicsScale() {
|
||||||
|
debug("resetGraphicsScale");
|
||||||
|
}
|
||||||
|
|
||||||
|
int OSystem_3DS::getGraphicsMode() const {
|
||||||
|
return GFX_LINEAR;
|
||||||
|
}
|
||||||
|
void OSystem_3DS::initSize(uint width, uint height,
|
||||||
|
const Graphics::PixelFormat *format) {
|
||||||
|
debug("3ds initsize w:%d h:%d", width, height);
|
||||||
|
_gameWidth = width;
|
||||||
|
_gameHeight = height;
|
||||||
|
_gameTopTexture.create(width, height, _pfGameTexture);
|
||||||
|
_overlay.create(getOverlayWidth(), getOverlayHeight(), _pfGameTexture);
|
||||||
|
|
||||||
|
if (format) {
|
||||||
|
debug("pixelformat: %d %d %d %d %d", format->bytesPerPixel, format->rBits(), format->gBits(), format->bBits(), format->aBits());;
|
||||||
|
_pfGame = *format;
|
||||||
|
}
|
||||||
|
|
||||||
|
_gameScreen.create(width, height, _pfGame);
|
||||||
|
|
||||||
|
_focusDirty = true;
|
||||||
|
_focusRect = Common::Rect(_gameWidth, _gameHeight);
|
||||||
|
|
||||||
|
updateSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::updateSize() {
|
||||||
|
if (config.stretchToFit) {
|
||||||
|
_gameTopX = _gameTopY = _gameBottomX = _gameBottomY = 0;
|
||||||
|
_gameTopTexture.setScale(400.f / _gameWidth, 240.f / _gameHeight);
|
||||||
|
_gameBottomTexture.setScale(320.f / _gameWidth, 240.f / _gameHeight);
|
||||||
|
} else {
|
||||||
|
float ratio = static_cast<float>(_gameWidth) / _gameHeight;
|
||||||
|
|
||||||
|
if (ratio > 400.f / 240.f) {
|
||||||
|
float r = 400.f / _gameWidth;
|
||||||
|
_gameTopTexture.setScale(r, r);
|
||||||
|
_gameTopX = 0;
|
||||||
|
_gameTopY = (240.f - r * _gameHeight) / 2.f;
|
||||||
|
} else {
|
||||||
|
float r = 240.f / _gameHeight;
|
||||||
|
_gameTopTexture.setScale(r, r);
|
||||||
|
_gameTopY = 0;
|
||||||
|
_gameTopX = (400.f - r * _gameWidth) / 2.f;
|
||||||
|
}
|
||||||
|
if (ratio > 320.f / 240.f) {
|
||||||
|
float r = 320.f / _gameWidth;
|
||||||
|
_gameBottomTexture.setScale(r, r);
|
||||||
|
_gameBottomX = 0;
|
||||||
|
_gameBottomY = (240.f - r * _gameHeight) / 2.f;
|
||||||
|
} else {
|
||||||
|
float r = 240.f / _gameHeight;
|
||||||
|
_gameBottomTexture.setScale(r, r);
|
||||||
|
_gameBottomY = 0;
|
||||||
|
_gameBottomX = (320.f - r * _gameWidth) / 2.f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_gameTopTexture.setPosition(_gameTopX, _gameTopY);
|
||||||
|
_gameBottomTexture.setPosition(_gameBottomX, _gameBottomY);
|
||||||
|
if (_overlayVisible)
|
||||||
|
_cursorTexture.setScale(1.f, 1.f);
|
||||||
|
else if (config.screen == kScreenTop)
|
||||||
|
_cursorTexture.setScale(_gameTopTexture.getScaleX(), _gameTopTexture.getScaleY());
|
||||||
|
else
|
||||||
|
_cursorTexture.setScale(_gameBottomTexture.getScaleX(), _gameBottomTexture.getScaleY());
|
||||||
|
}
|
||||||
|
|
||||||
|
Common::List<Graphics::PixelFormat> OSystem_3DS::getSupportedFormats() const {
|
||||||
|
Common::List<Graphics::PixelFormat> list;
|
||||||
|
list.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)); // GPU_RGBA8
|
||||||
|
list.push_back(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)); // GPU_RGB565
|
||||||
|
// list.push_back(Graphics::PixelFormat(3, 0, 0, 0, 8, 0, 8, 16, 0)); // GPU_RGB8
|
||||||
|
list.push_back(Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0)); // RGB555 (needed for FMTOWNS?)
|
||||||
|
list.push_back(Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0)); // GPU_RGBA5551
|
||||||
|
list.push_back(Graphics::PixelFormat::createFormatCLUT8());
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::beginGFXTransaction() {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
OSystem::TransactionError OSystem_3DS::endGFXTransaction() {
|
||||||
|
return OSystem::kTransactionSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::setPalette(const byte *colors, uint start, uint num) {
|
||||||
|
assert(start + num <= 256);
|
||||||
|
memcpy(_palette + 3 * start, colors, 3 * num);
|
||||||
|
|
||||||
|
// Manually update all color that were changed
|
||||||
|
if (_gameScreen.format.bytesPerPixel == 1) {
|
||||||
|
flushGameScreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void OSystem_3DS::grabPalette(byte *colors, uint start, uint num) {
|
||||||
|
assert(start + num <= 256);
|
||||||
|
memcpy(colors, _palette + 3 * start, 3 * num);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::copyRectToScreen(const void *buf, int pitch, int x,
|
||||||
|
int y, int w, int h) {
|
||||||
|
Common::Rect rect(x, y, x+w, y+h);
|
||||||
|
_gameScreen.copyRectToSurface(buf, pitch, x, y, w, h);
|
||||||
|
Graphics::Surface subSurface = _gameScreen.getSubArea(rect);
|
||||||
|
|
||||||
|
Graphics::Surface *convertedSubSurface = subSurface.convertTo(_pfGameTexture, _palette);
|
||||||
|
_gameTopTexture.copyRectToSurface(*convertedSubSurface, x, y, Common::Rect(w, h));
|
||||||
|
|
||||||
|
convertedSubSurface->free();
|
||||||
|
delete convertedSubSurface;
|
||||||
|
_gameTopTexture.markDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::flushGameScreen() {
|
||||||
|
Graphics::Surface *converted = _gameScreen.convertTo(_pfGameTexture, _palette);
|
||||||
|
_gameTopTexture.copyRectToSurface(*converted, 0, 0, Common::Rect(converted->w, converted->h));
|
||||||
|
_gameTopTexture.markDirty();
|
||||||
|
converted->free();
|
||||||
|
delete converted;
|
||||||
|
}
|
||||||
|
|
||||||
|
Graphics::Surface *OSystem_3DS::lockScreen() {
|
||||||
|
return &_gameScreen;
|
||||||
|
}
|
||||||
|
void OSystem_3DS::unlockScreen() {
|
||||||
|
flushGameScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::updateScreen() {
|
||||||
|
|
||||||
|
if (sleeping || exiting)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// updateFocus();
|
||||||
|
|
||||||
|
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
|
||||||
|
// Render top screen
|
||||||
|
C3D_FrameDrawOn(_renderTargetTop);
|
||||||
|
if (config.screen == kScreenTop || config.screen == kScreenBoth) {
|
||||||
|
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, _projectionLocation, &_projectionTop);
|
||||||
|
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, _modelviewLocation, _gameTopTexture.getMatrix());
|
||||||
|
_gameTopTexture.render();
|
||||||
|
_gameTopTexture.render();
|
||||||
|
if (_overlayVisible && config.screen == kScreenTop) {
|
||||||
|
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, _modelviewLocation, _overlay.getMatrix());
|
||||||
|
_overlay.render();
|
||||||
|
}
|
||||||
|
if (_cursorVisible && config.showCursor && config.screen == kScreenTop) {
|
||||||
|
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, _modelviewLocation, _cursorTexture.getMatrix());
|
||||||
|
_cursorTexture.render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render bottom screen
|
||||||
|
C3D_FrameDrawOn(_renderTargetBottom);
|
||||||
|
if (config.screen == kScreenBottom || config.screen == kScreenBoth) {
|
||||||
|
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, _projectionLocation, &_projectionBottom);
|
||||||
|
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, _modelviewLocation, _gameBottomTexture.getMatrix());
|
||||||
|
_gameTopTexture.render();
|
||||||
|
_gameTopTexture.render();
|
||||||
|
if (_overlayVisible) {
|
||||||
|
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, _modelviewLocation, _overlay.getMatrix());
|
||||||
|
_overlay.render();
|
||||||
|
}
|
||||||
|
if (_cursorVisible && config.showCursor) {
|
||||||
|
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, _modelviewLocation, _cursorTexture.getMatrix());
|
||||||
|
_cursorTexture.render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
C3D_FrameEnd(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::setShakePos(int shakeOffset) {
|
||||||
|
// TODO: implement this in overlay, top screen, and mouse too
|
||||||
|
_screenShakeOffset = shakeOffset;
|
||||||
|
_gameTopTexture.setPosition(_gameTopX, _gameTopY + _gameTopTexture.getScaleY() * shakeOffset);
|
||||||
|
_gameBottomTexture.setPosition(_gameBottomX, _gameBottomY + _gameBottomTexture.getScaleY() * shakeOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::setFocusRectangle(const Common::Rect &rect) {
|
||||||
|
debug("setfocus: %d %d %d %d", rect.left, rect.top, rect.width(), rect.height());
|
||||||
|
_focusRect = rect;
|
||||||
|
_focusDirty = true;
|
||||||
|
_focusClearTime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::clearFocusRectangle() {
|
||||||
|
_focusClearTime = getMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::updateFocus() {
|
||||||
|
|
||||||
|
if (_focusClearTime && getMillis() - _focusClearTime > 5000) {
|
||||||
|
_focusClearTime = 0;
|
||||||
|
_focusDirty = true;
|
||||||
|
_focusRect = Common::Rect(_gameWidth, _gameHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_focusDirty) {
|
||||||
|
float duration = 1.f / 20.f; // Focus animation in frame duration
|
||||||
|
float w = 400.f;
|
||||||
|
float h = 240.f;
|
||||||
|
float ratio = _focusRect.width() / _focusRect.height();
|
||||||
|
if (ratio > w/h) {
|
||||||
|
_focusTargetScaleX = w / _focusRect.width();
|
||||||
|
float newHeight = (float)_focusRect.width() / w/h;
|
||||||
|
_focusTargetScaleY = h / newHeight;
|
||||||
|
_focusTargetPosX = _focusTargetScaleX * _focusRect.left;
|
||||||
|
_focusTargetPosY = _focusTargetScaleY * ((float)_focusRect.top - (newHeight - _focusRect.height())/2.f);
|
||||||
|
} else {
|
||||||
|
_focusTargetScaleY = h / _focusRect.height();
|
||||||
|
float newWidth = (float)_focusRect.height() * w/h;
|
||||||
|
_focusTargetScaleX = w / newWidth;
|
||||||
|
_focusTargetPosY = _focusTargetScaleY * _focusRect.top;
|
||||||
|
_focusTargetPosX = _focusTargetScaleX * ((float)_focusRect.left - (newWidth - _focusRect.width())/2.f);
|
||||||
|
}
|
||||||
|
if (_focusTargetPosX < 0 && _focusTargetScaleY != 240.f / _gameHeight)
|
||||||
|
_focusTargetPosX = 0;
|
||||||
|
if (_focusTargetPosY < 0 && _focusTargetScaleX != 400.f / _gameWidth)
|
||||||
|
_focusTargetPosY = 0;
|
||||||
|
_focusStepPosX = duration * (_focusTargetPosX - _focusPosX);
|
||||||
|
_focusStepPosY = duration * (_focusTargetPosY - _focusPosY);
|
||||||
|
_focusStepScaleX = duration * (_focusTargetScaleX - _focusScaleX);
|
||||||
|
_focusStepScaleY = duration * (_focusTargetScaleY - _focusScaleY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_focusDirty || _focusPosX != _focusTargetPosX || _focusPosY != _focusTargetPosY ||
|
||||||
|
_focusScaleX != _focusTargetScaleX || _focusScaleY != _focusTargetScaleY) {
|
||||||
|
_focusDirty = false;
|
||||||
|
|
||||||
|
if ((_focusStepPosX > 0 && _focusPosX > _focusTargetPosX) || (_focusStepPosX < 0 && _focusPosX < _focusTargetPosX))
|
||||||
|
_focusPosX = _focusTargetPosX;
|
||||||
|
else if (_focusPosX != _focusTargetPosX)
|
||||||
|
_focusPosX += _focusStepPosX;
|
||||||
|
|
||||||
|
if ((_focusStepPosY > 0 && _focusPosY > _focusTargetPosY) || (_focusStepPosY < 0 && _focusPosY < _focusTargetPosY))
|
||||||
|
_focusPosY = _focusTargetPosY;
|
||||||
|
else if (_focusPosY != _focusTargetPosY)
|
||||||
|
_focusPosY += _focusStepPosY;
|
||||||
|
|
||||||
|
if ((_focusStepScaleX > 0 && _focusScaleX > _focusTargetScaleX) || (_focusStepScaleX < 0 && _focusScaleX < _focusTargetScaleX))
|
||||||
|
_focusScaleX = _focusTargetScaleX;
|
||||||
|
else if (_focusScaleX != _focusTargetScaleX)
|
||||||
|
_focusScaleX += _focusStepScaleX;
|
||||||
|
|
||||||
|
if ((_focusStepScaleY > 0 && _focusScaleY > _focusTargetScaleY) || (_focusStepScaleY < 0 && _focusScaleY < _focusTargetScaleY))
|
||||||
|
_focusScaleY = _focusTargetScaleY;
|
||||||
|
else if (_focusScaleY != _focusTargetScaleY)
|
||||||
|
_focusScaleY += _focusStepScaleY;
|
||||||
|
|
||||||
|
Mtx_Identity(&_focusMatrix);
|
||||||
|
Mtx_Translate(&_focusMatrix, -_focusPosX, -_focusPosY, 0);
|
||||||
|
Mtx_Scale(&_focusMatrix, _focusScaleX, _focusScaleY, 1.f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::showOverlay() {
|
||||||
|
_overlayVisible = true;
|
||||||
|
updateSize();
|
||||||
|
updateScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::hideOverlay() {
|
||||||
|
_overlayVisible = false;
|
||||||
|
updateSize();
|
||||||
|
updateScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
Graphics::PixelFormat OSystem_3DS::getOverlayFormat() const {
|
||||||
|
return _pfGameTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::clearOverlay() {
|
||||||
|
_overlay.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::grabOverlay(void *buf, int pitch) {
|
||||||
|
for (int y = 0; y < getOverlayHeight(); ++y) {
|
||||||
|
memcpy(buf, _overlay.getBasePtr(0, y), pitch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::copyRectToOverlay(const void *buf, int pitch, int x,
|
||||||
|
int y, int w, int h) {
|
||||||
|
_overlay.copyRectToSurface(buf, pitch, x, y, w, h);
|
||||||
|
_overlay.markDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 OSystem_3DS::getOverlayHeight() {
|
||||||
|
return 240;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 OSystem_3DS::getOverlayWidth() {
|
||||||
|
return 320;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OSystem_3DS::showMouse(bool visible) {
|
||||||
|
_cursorVisible = visible;
|
||||||
|
flushCursor();
|
||||||
|
return !visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::warpMouse(int x, int y) {
|
||||||
|
_cursorX = x;
|
||||||
|
_cursorY = y;
|
||||||
|
warning("x:%d y:%d", x, y);
|
||||||
|
// TODO: adjust for _cursorScalable ?
|
||||||
|
int offsetx = 0;
|
||||||
|
int offsety = 0;
|
||||||
|
x -= _cursorHotspotX;
|
||||||
|
y -= _cursorHotspotY;
|
||||||
|
if (!_overlayVisible) {
|
||||||
|
offsetx += config.screen == kScreenTop ? _gameTopX : _gameBottomX;
|
||||||
|
offsety += config.screen == kScreenTop ? _gameTopY : _gameBottomY;
|
||||||
|
}
|
||||||
|
float scalex = config.screen == kScreenTop ? (float)_gameTopTexture.actualWidth / _gameWidth : 1.f;
|
||||||
|
float scaley = config.screen == kScreenTop ? (float)_gameTopTexture.actualHeight / _gameHeight : 1.f;
|
||||||
|
_cursorTexture.setPosition(scalex * x + offsetx,
|
||||||
|
scaley * y + offsety);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::setCursorDelta(float deltaX, float deltaY) {
|
||||||
|
_cursorDeltaX = deltaX;
|
||||||
|
_cursorDeltaY = deltaY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::setMouseCursor(const void *buf, uint w, uint h,
|
||||||
|
int hotspotX, int hotspotY,
|
||||||
|
uint32 keycolor, bool dontScale,
|
||||||
|
const Graphics::PixelFormat *format) {
|
||||||
|
_cursorScalable = !dontScale;
|
||||||
|
_cursorHotspotX = hotspotX;
|
||||||
|
_cursorHotspotY = hotspotY;
|
||||||
|
_cursorKeyColor = keycolor;
|
||||||
|
_pfCursor = !format ? Graphics::PixelFormat::createFormatCLUT8() : *format;
|
||||||
|
|
||||||
|
if (w != _cursor.w || h != _cursor.h || _cursor.format != _pfCursor) {
|
||||||
|
_cursor.create(w, h, _pfCursor);
|
||||||
|
_cursorTexture.create(w, h, _pfGameTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
_cursor.copyRectToSurface(buf, w, 0, 0, w, h);
|
||||||
|
flushCursor();
|
||||||
|
|
||||||
|
warpMouse(_cursorX, _cursorY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::setCursorPalette(const byte *colors, uint start, uint num) {
|
||||||
|
assert(start + num <= 256);
|
||||||
|
memcpy(_cursorPalette + 3 * start, colors, 3 * num);
|
||||||
|
_cursorPaletteEnabled = true;
|
||||||
|
flushCursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::flushCursor() {
|
||||||
|
if (_cursor.getPixels()) {
|
||||||
|
Graphics::Surface *converted = _cursor.convertTo(_pfGameTexture, _cursorPaletteEnabled ? _cursorPalette : _palette);
|
||||||
|
_cursorTexture.copyRectToSurface(*converted, 0, 0, Common::Rect(converted->w, converted->h));
|
||||||
|
_cursorTexture.markDirty();
|
||||||
|
converted->free();
|
||||||
|
delete converted;
|
||||||
|
|
||||||
|
if (_pfCursor.bytesPerPixel == 1) {
|
||||||
|
uint* dest = (uint*) _cursorTexture.getPixels();
|
||||||
|
byte* src = (byte*) _cursor.getPixels();
|
||||||
|
for (int y = 0; y < _cursor.h; ++y) {
|
||||||
|
for (int x = 0; x < _cursor.w; ++x) {
|
||||||
|
if (*src++ == _cursorKeyColor)
|
||||||
|
*dest++ = 0;
|
||||||
|
else
|
||||||
|
dest++;
|
||||||
|
}
|
||||||
|
dest += _cursorTexture.w - _cursorTexture.actualWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace _3DS
|
193
backends/platform/3ds/osystem.cpp
Normal file
193
backends/platform/3ds/osystem.cpp
Normal file
|
@ -0,0 +1,193 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* 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 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define FORBIDDEN_SYMBOL_EXCEPTION_printf
|
||||||
|
#define FORBIDDEN_SYMBOL_EXCEPTION_time_h
|
||||||
|
#define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h
|
||||||
|
|
||||||
|
#include "osystem.h"
|
||||||
|
|
||||||
|
#include "backends/saves/default/default-saves.h"
|
||||||
|
#include "backends/timer/default/default-timer.h"
|
||||||
|
#include "backends/events/default/default-events.h"
|
||||||
|
#include "audio/mixer_intern.h"
|
||||||
|
#include "common/scummsys.h"
|
||||||
|
#include "common/config-manager.h"
|
||||||
|
#include "common/str.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "backends/fs/posix/posix-fs-factory.h"
|
||||||
|
#include "backends/fs/posix/posix-fs.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
namespace _3DS {
|
||||||
|
|
||||||
|
OSystem_3DS::OSystem_3DS():
|
||||||
|
_focusDirty(true),
|
||||||
|
_focusRect(Common::Rect(1, 1)),
|
||||||
|
_focusPosX(0),
|
||||||
|
_focusPosY(0),
|
||||||
|
_focusTargetPosX(0),
|
||||||
|
_focusTargetPosY(0),
|
||||||
|
_focusStepPosX(0),
|
||||||
|
_focusStepPosY(0),
|
||||||
|
_focusScaleX(1.f),
|
||||||
|
_focusScaleY(1.f),
|
||||||
|
_focusTargetScaleX(1.f),
|
||||||
|
_focusTargetScaleY(1.f),
|
||||||
|
_focusStepScaleX(0.f),
|
||||||
|
_focusStepScaleY(0.f),
|
||||||
|
_focusClearTime(0),
|
||||||
|
_cursorPaletteEnabled(false),
|
||||||
|
_cursorVisible(false),
|
||||||
|
_cursorScalable(false),
|
||||||
|
_cursorX(0),
|
||||||
|
_cursorY(0),
|
||||||
|
_cursorHotspotX(0),
|
||||||
|
_cursorHotspotY(0),
|
||||||
|
_gameTopX(0),
|
||||||
|
_gameTopY(0),
|
||||||
|
_gameBottomX(0),
|
||||||
|
_gameBottomY(0),
|
||||||
|
_gameWidth(320),
|
||||||
|
_gameHeight(240),
|
||||||
|
_overlayVisible(false),
|
||||||
|
exiting(false),
|
||||||
|
sleeping(false)
|
||||||
|
{
|
||||||
|
chdir("sdmc:/");
|
||||||
|
_fsFactory = new POSIXFilesystemFactory();
|
||||||
|
Posix::assureDirectoryExists("/3ds/scummvm/saves/");
|
||||||
|
}
|
||||||
|
|
||||||
|
OSystem_3DS::~OSystem_3DS() {
|
||||||
|
exiting = true;
|
||||||
|
destroyEvents();
|
||||||
|
destroyAudio();
|
||||||
|
destroyGraphics();
|
||||||
|
|
||||||
|
delete _timerManager;
|
||||||
|
_timerManager = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::quit() {
|
||||||
|
printf("OSystem_3DS::quit()\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::initBackend() {
|
||||||
|
loadConfig();
|
||||||
|
ConfMan.registerDefault("fullscreen", true);
|
||||||
|
ConfMan.registerDefault("aspect_ratio", true);
|
||||||
|
if (!ConfMan.hasKey("vkeybd_pack_name"))
|
||||||
|
ConfMan.set("vkeybd_pack_name", "vkeybd_small");
|
||||||
|
if (!ConfMan.hasKey("vkeybdpath"))
|
||||||
|
ConfMan.set("vkeybdpath", "/3ds/scummvm/kb");
|
||||||
|
if (!ConfMan.hasKey("themepath"))
|
||||||
|
ConfMan.set("themepath", "/3ds/scummvm");
|
||||||
|
if (!ConfMan.hasKey("gui_theme"))
|
||||||
|
ConfMan.set("gui_theme", "builtin");
|
||||||
|
|
||||||
|
_timerManager = new DefaultTimerManager();
|
||||||
|
_savefileManager = new DefaultSaveFileManager("/3ds/scummvm/saves/");
|
||||||
|
|
||||||
|
initGraphics();
|
||||||
|
initAudio();
|
||||||
|
initEvents();
|
||||||
|
EventsBaseBackend::initBackend();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::updateConfig() {
|
||||||
|
if (_gameScreen.getPixels()) {
|
||||||
|
updateSize();
|
||||||
|
warpMouse(_cursorX, _cursorY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Common::String OSystem_3DS::getDefaultConfigFileName() {
|
||||||
|
return "/3ds/scummvm/scummvm.ini";
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 OSystem_3DS::getMillis(bool skipRecord) {
|
||||||
|
return svcGetSystemTick() / TICKS_PER_MSEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::delayMillis(uint msecs) {
|
||||||
|
svcSleepThread(msecs * 1000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::getTimeAndDate(TimeDate& td) const {
|
||||||
|
time_t curTime = time(0);
|
||||||
|
struct tm t = *localtime(&curTime);
|
||||||
|
td.tm_sec = t.tm_sec;
|
||||||
|
td.tm_min = t.tm_min;
|
||||||
|
td.tm_hour = t.tm_hour;
|
||||||
|
td.tm_mday = t.tm_mday;
|
||||||
|
td.tm_mon = t.tm_mon;
|
||||||
|
td.tm_year = t.tm_year;
|
||||||
|
td.tm_wday = t.tm_wday;
|
||||||
|
}
|
||||||
|
|
||||||
|
OSystem::MutexRef OSystem_3DS::createMutex() {
|
||||||
|
RecursiveLock *mutex = new RecursiveLock();
|
||||||
|
RecursiveLock_Init(mutex);
|
||||||
|
return (OSystem::MutexRef) mutex;
|
||||||
|
}
|
||||||
|
void OSystem_3DS::lockMutex(MutexRef mutex) {
|
||||||
|
RecursiveLock_Lock((RecursiveLock*)mutex);
|
||||||
|
}
|
||||||
|
void OSystem_3DS::unlockMutex(MutexRef mutex) {
|
||||||
|
RecursiveLock_Unlock((RecursiveLock*)mutex);
|
||||||
|
}
|
||||||
|
void OSystem_3DS::deleteMutex(MutexRef mutex) {
|
||||||
|
delete (RecursiveLock*)mutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
Common::String OSystem_3DS::getSystemLanguage() const {
|
||||||
|
u8 langcode;
|
||||||
|
CFGU_GetSystemLanguage(&langcode);
|
||||||
|
switch (langcode) {
|
||||||
|
case CFG_LANGUAGE_JP: return "ja_JP";
|
||||||
|
case CFG_LANGUAGE_EN: return "en_US";
|
||||||
|
case CFG_LANGUAGE_FR: return "fr_FR";
|
||||||
|
case CFG_LANGUAGE_DE: return "de_DE";
|
||||||
|
case CFG_LANGUAGE_IT: return "it_IT";
|
||||||
|
case CFG_LANGUAGE_ES: return "es_ES";
|
||||||
|
case CFG_LANGUAGE_ZH: return "zh_CN";
|
||||||
|
case CFG_LANGUAGE_KO: return "ko_KR";
|
||||||
|
case CFG_LANGUAGE_NL: return "nl_NL";
|
||||||
|
case CFG_LANGUAGE_PT: return "pt_BR";
|
||||||
|
case CFG_LANGUAGE_RU: return "ru_RU";
|
||||||
|
case CFG_LANGUAGE_TW: return "zh_HK";
|
||||||
|
default: return "en_US";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::fatalError() {
|
||||||
|
printf("FatalError!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSystem_3DS::logMessage(LogMessageType::Type type, const char *message) {
|
||||||
|
printf("3DS log: %s\n", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace _3DS
|
221
backends/platform/3ds/osystem.h
Normal file
221
backends/platform/3ds/osystem.h
Normal file
|
@ -0,0 +1,221 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* 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 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PLATFORM_3DS_H
|
||||||
|
#define PLATFORM_3DS_H
|
||||||
|
|
||||||
|
#include <citro3d.h>
|
||||||
|
#include "backends/mutex/mutex.h"
|
||||||
|
#include "backends/base-backend.h"
|
||||||
|
#include "graphics/palette.h"
|
||||||
|
#include "base/main.h"
|
||||||
|
#include "audio/mixer_intern.h"
|
||||||
|
#include "backends/graphics/graphics.h"
|
||||||
|
#include "backends/platform/3ds/sprite.h"
|
||||||
|
#include "common/rect.h"
|
||||||
|
#include "common/queue.h"
|
||||||
|
|
||||||
|
#define TICKS_PER_MSEC 268123
|
||||||
|
|
||||||
|
namespace _3DS {
|
||||||
|
|
||||||
|
enum {
|
||||||
|
GFX_LINEAR = 0,
|
||||||
|
GFX_NEAREST = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum InputMode {
|
||||||
|
MODE_HOVER,
|
||||||
|
MODE_DRAG,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const OSystem::GraphicsMode s_graphicsModes[] = {
|
||||||
|
{"default", "Default Test", GFX_LINEAR},
|
||||||
|
{ 0, 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
class OSystem_3DS : public EventsBaseBackend, public PaletteManager {
|
||||||
|
public:
|
||||||
|
OSystem_3DS();
|
||||||
|
virtual ~OSystem_3DS();
|
||||||
|
|
||||||
|
volatile bool exiting;
|
||||||
|
volatile bool sleeping;
|
||||||
|
|
||||||
|
virtual void initBackend();
|
||||||
|
|
||||||
|
virtual bool hasFeature(OSystem::Feature f);
|
||||||
|
virtual void setFeatureState(OSystem::Feature f, bool enable);
|
||||||
|
virtual bool getFeatureState(OSystem::Feature f);
|
||||||
|
|
||||||
|
virtual bool pollEvent(Common::Event &event);
|
||||||
|
|
||||||
|
virtual uint32 getMillis(bool skipRecord = false);
|
||||||
|
virtual void delayMillis(uint msecs);
|
||||||
|
virtual void getTimeAndDate(TimeDate &t) const;
|
||||||
|
|
||||||
|
virtual MutexRef createMutex();
|
||||||
|
virtual void lockMutex(MutexRef mutex);
|
||||||
|
virtual void unlockMutex(MutexRef mutex);
|
||||||
|
virtual void deleteMutex(MutexRef mutex);
|
||||||
|
|
||||||
|
virtual void logMessage(LogMessageType::Type type, const char *message);
|
||||||
|
|
||||||
|
virtual Audio::Mixer *getMixer();
|
||||||
|
virtual PaletteManager *getPaletteManager() { return this; }
|
||||||
|
virtual Common::String getSystemLanguage() const;
|
||||||
|
virtual void fatalError();
|
||||||
|
virtual void quit();
|
||||||
|
|
||||||
|
virtual Common::String getDefaultConfigFileName();
|
||||||
|
|
||||||
|
// Graphics
|
||||||
|
virtual const OSystem::GraphicsMode *getSupportedGraphicsModes() const;
|
||||||
|
int getDefaultGraphicsMode() const;
|
||||||
|
bool setGraphicsMode(int mode);
|
||||||
|
void resetGraphicsScale();
|
||||||
|
int getGraphicsMode() const;
|
||||||
|
inline Graphics::PixelFormat getScreenFormat() const { return _pfGame; }
|
||||||
|
virtual Common::List<Graphics::PixelFormat> getSupportedFormats() const;
|
||||||
|
void initSize(uint width, uint height,
|
||||||
|
const Graphics::PixelFormat *format = NULL);
|
||||||
|
virtual int getScreenChangeID() const { return 0; };
|
||||||
|
|
||||||
|
void beginGFXTransaction();
|
||||||
|
OSystem::TransactionError endGFXTransaction();
|
||||||
|
int16 getHeight(){ return _gameHeight; }
|
||||||
|
int16 getWidth(){ return _gameWidth; }
|
||||||
|
void setPalette(const byte *colors, uint start, uint num);
|
||||||
|
void grabPalette(byte *colors, uint start, uint num);
|
||||||
|
void copyRectToScreen(const void *buf, int pitch, int x, int y, int w,
|
||||||
|
int h);
|
||||||
|
Graphics::Surface *lockScreen();
|
||||||
|
void unlockScreen();
|
||||||
|
void updateScreen();
|
||||||
|
void setShakePos(int shakeOffset);
|
||||||
|
void setFocusRectangle(const Common::Rect &rect);
|
||||||
|
void clearFocusRectangle();
|
||||||
|
void showOverlay();
|
||||||
|
void hideOverlay();
|
||||||
|
Graphics::PixelFormat getOverlayFormat() const;
|
||||||
|
void clearOverlay();
|
||||||
|
void grabOverlay(void *buf, int pitch);
|
||||||
|
void copyRectToOverlay(const void *buf, int pitch, int x, int y, int w,
|
||||||
|
int h);
|
||||||
|
virtual int16 getOverlayHeight();
|
||||||
|
virtual int16 getOverlayWidth();
|
||||||
|
virtual void displayMessageOnOSD(const char *msg);
|
||||||
|
|
||||||
|
bool showMouse(bool visible);
|
||||||
|
void warpMouse(int x, int y);
|
||||||
|
void setMouseCursor(const void *buf, uint w, uint h, int hotspotX,
|
||||||
|
int hotspotY, uint32 keycolor, bool dontScale = false,
|
||||||
|
const Graphics::PixelFormat *format = NULL);
|
||||||
|
void setCursorPalette(const byte *colors, uint start, uint num);
|
||||||
|
|
||||||
|
// Transform point from touchscreen coords into gamescreen coords
|
||||||
|
void transformPoint(touchPosition &point);
|
||||||
|
|
||||||
|
void setCursorDelta(float deltaX, float deltaY);
|
||||||
|
|
||||||
|
void updateFocus();
|
||||||
|
void updateConfig();
|
||||||
|
void updateSize();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initGraphics();
|
||||||
|
void destroyGraphics();
|
||||||
|
void initAudio();
|
||||||
|
void destroyAudio();
|
||||||
|
void initEvents();
|
||||||
|
void destroyEvents();
|
||||||
|
|
||||||
|
void flushGameScreen();
|
||||||
|
void flushCursor();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Audio::MixerImpl *_mixer;
|
||||||
|
|
||||||
|
private:
|
||||||
|
u16 _gameWidth, _gameHeight;
|
||||||
|
u16 _gameTopX, _gameTopY;
|
||||||
|
u16 _gameBottomX, _gameBottomY;
|
||||||
|
|
||||||
|
// Audio
|
||||||
|
Thread audioThread;
|
||||||
|
|
||||||
|
// Graphics
|
||||||
|
Graphics::PixelFormat _pfGame;
|
||||||
|
Graphics::PixelFormat _pfGameTexture;
|
||||||
|
Graphics::PixelFormat _pfCursor;
|
||||||
|
byte _palette[3 * 256];
|
||||||
|
byte _cursorPalette[3 * 256];
|
||||||
|
|
||||||
|
Graphics::Surface _gameScreen;
|
||||||
|
Sprite _gameTopTexture;
|
||||||
|
Sprite _gameBottomTexture;
|
||||||
|
Sprite _overlay;
|
||||||
|
|
||||||
|
int _screenShakeOffset;
|
||||||
|
bool _overlayVisible;
|
||||||
|
|
||||||
|
DVLB_s *_dvlb;
|
||||||
|
shaderProgram_s _program;
|
||||||
|
int _projectionLocation;
|
||||||
|
int _modelviewLocation;
|
||||||
|
C3D_Mtx _projectionTop;
|
||||||
|
C3D_Mtx _projectionBottom;
|
||||||
|
C3D_RenderTarget* _renderTargetTop;
|
||||||
|
C3D_RenderTarget* _renderTargetBottom;
|
||||||
|
|
||||||
|
// Focus
|
||||||
|
Common::Rect _focusRect;
|
||||||
|
bool _focusDirty;
|
||||||
|
C3D_Mtx _focusMatrix;
|
||||||
|
int _focusPosX, _focusPosY;
|
||||||
|
int _focusTargetPosX, _focusTargetPosY;
|
||||||
|
float _focusStepPosX, _focusStepPosY;
|
||||||
|
float _focusScaleX, _focusScaleY;
|
||||||
|
float _focusTargetScaleX, _focusTargetScaleY;
|
||||||
|
float _focusStepScaleX, _focusStepScaleY;
|
||||||
|
uint32 _focusClearTime;
|
||||||
|
|
||||||
|
// Events
|
||||||
|
Thread _eventThread;
|
||||||
|
Thread _timerThread;
|
||||||
|
Common::Queue<Common::Event> _eventQueue;
|
||||||
|
|
||||||
|
// Cursor
|
||||||
|
Graphics::Surface _cursor;
|
||||||
|
Sprite _cursorTexture;
|
||||||
|
bool _cursorPaletteEnabled;
|
||||||
|
bool _cursorVisible;
|
||||||
|
bool _cursorScalable;
|
||||||
|
float _cursorX, _cursorY;
|
||||||
|
float _cursorDeltaX, _cursorDeltaY;
|
||||||
|
int _cursorHotspotX, _cursorHotspotY;
|
||||||
|
uint32 _cursorKeyColor;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace _3DS
|
||||||
|
|
||||||
|
#endif
|
59
backends/platform/3ds/shader.v.pica
Normal file
59
backends/platform/3ds/shader.v.pica
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
;* ScummVM - Graphic Adventure Engine
|
||||||
|
;*
|
||||||
|
;* ScummVM is the legal property of its developers, whose names
|
||||||
|
;* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
;* file distributed with this source distribution.
|
||||||
|
;*
|
||||||
|
;* 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 2
|
||||||
|
;* 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, write to the Free Software
|
||||||
|
;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
;*
|
||||||
|
|
||||||
|
; Uniforms
|
||||||
|
.fvec projection[4], modelView[4]
|
||||||
|
|
||||||
|
; Constants
|
||||||
|
.constf myconst(0.0, 1.0, -1.0, 0.1)
|
||||||
|
.alias zeros myconst.xxxx ; Vector full of zeros
|
||||||
|
.alias ones myconst.yyyy ; Vector full of ones
|
||||||
|
|
||||||
|
; Outputs
|
||||||
|
.out outpos position
|
||||||
|
.out outtex texcoord0
|
||||||
|
|
||||||
|
; Inputs (defined as aliases for convenience)
|
||||||
|
.alias inpos v0
|
||||||
|
.alias intex v1
|
||||||
|
|
||||||
|
.proc main
|
||||||
|
; Force the w component of inpos to be 1.0
|
||||||
|
mov r0.xyz, inpos
|
||||||
|
mov r0.w, ones
|
||||||
|
|
||||||
|
; r1 = modelView * inpos
|
||||||
|
dp4 r1.x, modelView[0], r0
|
||||||
|
dp4 r1.y, modelView[1], r0
|
||||||
|
dp4 r1.z, modelView[2], r0
|
||||||
|
dp4 r1.w, modelView[3], r0
|
||||||
|
|
||||||
|
; outpos = projection * r1
|
||||||
|
dp4 outpos.x, projection[0], r1
|
||||||
|
dp4 outpos.y, projection[1], r1
|
||||||
|
dp4 outpos.z, projection[2], r1
|
||||||
|
dp4 outpos.w, projection[3], r1
|
||||||
|
|
||||||
|
mov outtex, intex
|
||||||
|
|
||||||
|
end
|
||||||
|
.end
|
||||||
|
|
144
backends/platform/3ds/sprite.cpp
Normal file
144
backends/platform/3ds/sprite.cpp
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* 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 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "backends/platform/3ds/sprite.h"
|
||||||
|
#include "common/util.h"
|
||||||
|
#include <3ds.h>
|
||||||
|
|
||||||
|
static uint nextHigher2(uint v) {
|
||||||
|
if (v == 0)
|
||||||
|
return 1;
|
||||||
|
v--;
|
||||||
|
v |= v >> 1;
|
||||||
|
v |= v >> 2;
|
||||||
|
v |= v >> 4;
|
||||||
|
v |= v >> 8;
|
||||||
|
v |= v >> 16;
|
||||||
|
return ++v;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sprite::Sprite()
|
||||||
|
: dirtyPixels(true)
|
||||||
|
, dirtyMatrix(true)
|
||||||
|
, actualWidth(0)
|
||||||
|
, actualHeight(0)
|
||||||
|
, posX(0)
|
||||||
|
, posY(0)
|
||||||
|
, scaleX(1.f)
|
||||||
|
, scaleY(1.f)
|
||||||
|
{
|
||||||
|
Mtx_Identity(&modelview);
|
||||||
|
|
||||||
|
vertices = (vertex *)linearAlloc(sizeof(vertex) * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
Sprite::~Sprite() {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sprite::create(uint16 width, uint16 height, const Graphics::PixelFormat &f) {
|
||||||
|
free();
|
||||||
|
|
||||||
|
actualWidth = width;
|
||||||
|
actualHeight = height;
|
||||||
|
format = f;
|
||||||
|
w = MAX(nextHigher2(width), 64u);
|
||||||
|
h = MAX(nextHigher2(height), 64u);;
|
||||||
|
pitch = w * format.bytesPerPixel;
|
||||||
|
dirtyPixels = true;
|
||||||
|
|
||||||
|
if (width && height) {
|
||||||
|
pixels = linearAlloc(h * pitch);
|
||||||
|
C3D_TexInit(&texture, w, h, GPU_RGBA8);
|
||||||
|
C3D_TexSetFilter(&texture, GPU_LINEAR, GPU_LINEAR);
|
||||||
|
assert(pixels && texture.data);
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
float x = 0.f, y = 0.f;
|
||||||
|
float u = (float)width/w;
|
||||||
|
float v = (float)height/h;
|
||||||
|
vertex tmp[4] = {
|
||||||
|
{{x, y, 0.5f}, {0, 0}},
|
||||||
|
{{x+width, y, 0.5f}, {u, 0}},
|
||||||
|
{{x, y+height, 0.5f}, {0, v}},
|
||||||
|
{{x+width, y+height, 0.5f}, {u, v}},
|
||||||
|
};
|
||||||
|
memcpy(vertices, tmp, sizeof(vertex) * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Sprite::free() {
|
||||||
|
linearFree(vertices);
|
||||||
|
linearFree(pixels);
|
||||||
|
C3D_TexDelete(&texture);
|
||||||
|
pixels = 0;
|
||||||
|
w = h = pitch = 0;
|
||||||
|
actualWidth = actualHeight = 0;
|
||||||
|
format = Graphics::PixelFormat();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sprite::convertToInPlace(const Graphics::PixelFormat &dstFormat, const byte *palette) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sprite::render() {
|
||||||
|
if (dirtyPixels) {
|
||||||
|
dirtyPixels = false;
|
||||||
|
GSPGPU_FlushDataCache(pixels, w * h * format.bytesPerPixel);
|
||||||
|
C3D_SafeDisplayTransfer((u32*)pixels, GX_BUFFER_DIM(w, h), (u32*)texture.data, GX_BUFFER_DIM(w, h), TEXTURE_TRANSFER_FLAGS);
|
||||||
|
gspWaitForPPF();
|
||||||
|
}
|
||||||
|
C3D_TexBind(0, &texture);
|
||||||
|
|
||||||
|
C3D_BufInfo *bufInfo = C3D_GetBufInfo();
|
||||||
|
BufInfo_Init(bufInfo);
|
||||||
|
BufInfo_Add(bufInfo, vertices, sizeof(vertex), 2, 0x10);
|
||||||
|
C3D_DrawArrays(GPU_TRIANGLE_STRIP, 0, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sprite::clear(uint32 color) {
|
||||||
|
dirtyPixels = true;
|
||||||
|
memset(pixels, color, w * h * format.bytesPerPixel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sprite::setScale (float x, float y) {
|
||||||
|
scaleX = x;
|
||||||
|
scaleY = y;
|
||||||
|
dirtyMatrix = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sprite::setPosition(int x, int y) {
|
||||||
|
posX = x;
|
||||||
|
posY = y;
|
||||||
|
dirtyMatrix = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
C3D_Mtx* Sprite::getMatrix() {
|
||||||
|
if (dirtyMatrix) {
|
||||||
|
dirtyMatrix = false;
|
||||||
|
Mtx_Identity(&modelview);
|
||||||
|
Mtx_Scale(&modelview, scaleX, scaleY, 1.f);
|
||||||
|
Mtx_Translate(&modelview, posX, posY, 0);
|
||||||
|
}
|
||||||
|
return &modelview;
|
||||||
|
}
|
71
backends/platform/3ds/sprite.h
Normal file
71
backends/platform/3ds/sprite.h
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* 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 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GRAPHICS_SPRITE_3DS_H
|
||||||
|
#define GRAPHICS_SPRITE_3DS_H
|
||||||
|
|
||||||
|
#include <citro3d.h>
|
||||||
|
#include "graphics/surface.h"
|
||||||
|
|
||||||
|
#define TEXTURE_TRANSFER_FLAGS \
|
||||||
|
(GX_TRANSFER_FLIP_VERT(1) | GX_TRANSFER_OUT_TILED(1) | GX_TRANSFER_RAW_COPY(0) | \
|
||||||
|
GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGBA8) | \
|
||||||
|
GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO))
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float position[3];
|
||||||
|
float texcoord[2];
|
||||||
|
} vertex;
|
||||||
|
|
||||||
|
class Sprite : public Graphics::Surface {
|
||||||
|
public:
|
||||||
|
Sprite();
|
||||||
|
~Sprite();
|
||||||
|
void create(uint16 width, uint16 height, const Graphics::PixelFormat &format);
|
||||||
|
void free();
|
||||||
|
void convertToInPlace(const Graphics::PixelFormat &dstFormat, const byte *palette = 0);
|
||||||
|
void render();
|
||||||
|
void clear(uint32 color = 0);
|
||||||
|
void markDirty(){ dirtyPixels = true; }
|
||||||
|
|
||||||
|
void setPosition(int x, int y);
|
||||||
|
void setScale(float x, float y);
|
||||||
|
float getScaleX(){ return scaleX; }
|
||||||
|
float getScaleY(){ return scaleY; }
|
||||||
|
C3D_Mtx* getMatrix();
|
||||||
|
|
||||||
|
uint16 actualWidth;
|
||||||
|
uint16 actualHeight;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool dirtyPixels;
|
||||||
|
bool dirtyMatrix;
|
||||||
|
C3D_Mtx modelview;
|
||||||
|
C3D_Tex texture;
|
||||||
|
vertex* vertices;
|
||||||
|
int posX;
|
||||||
|
int posY;
|
||||||
|
float scaleX;
|
||||||
|
float scaleY;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -57,7 +57,7 @@ static const char USAGE_STRING[] =
|
||||||
;
|
;
|
||||||
|
|
||||||
// DONT FIXME: DO NOT ORDER ALPHABETICALLY, THIS IS ORDERED BY IMPORTANCE/CATEGORY! :)
|
// DONT FIXME: DO NOT ORDER ALPHABETICALLY, THIS IS ORDERED BY IMPORTANCE/CATEGORY! :)
|
||||||
#if defined(__SYMBIAN32__) || defined(__GP32__) || defined(ANDROID) || defined(__DS__)
|
#if defined(__SYMBIAN32__) || defined(__GP32__) || defined(ANDROID) || defined(__DS__) || defined(__3DS__)
|
||||||
static const char HELP_STRING[] = "NoUsageString"; // save more data segment space
|
static const char HELP_STRING[] = "NoUsageString"; // save more data segment space
|
||||||
#else
|
#else
|
||||||
static const char HELP_STRING[] =
|
static const char HELP_STRING[] =
|
||||||
|
|
|
@ -251,6 +251,7 @@
|
||||||
|
|
||||||
#if defined(__DC__) || \
|
#if defined(__DC__) || \
|
||||||
defined(__DS__) || \
|
defined(__DS__) || \
|
||||||
|
defined(__3DS__) || \
|
||||||
defined(__GP32__) || \
|
defined(__GP32__) || \
|
||||||
defined(IPHONE) || \
|
defined(IPHONE) || \
|
||||||
defined(__PLAYSTATION2__) || \
|
defined(__PLAYSTATION2__) || \
|
||||||
|
@ -367,7 +368,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef STRINGBUFLEN
|
#ifndef STRINGBUFLEN
|
||||||
#if defined(__N64__) || defined(__DS__)
|
#if defined(__N64__) || defined(__DS__) || defined(__3DS__)
|
||||||
#define STRINGBUFLEN 256
|
#define STRINGBUFLEN 256
|
||||||
#else
|
#else
|
||||||
#define STRINGBUFLEN 1024
|
#define STRINGBUFLEN 1024
|
||||||
|
|
71
configure
vendored
71
configure
vendored
|
@ -440,7 +440,7 @@ get_system_exe_extension() {
|
||||||
arm-riscos)
|
arm-riscos)
|
||||||
_exeext=",ff8"
|
_exeext=",ff8"
|
||||||
;;
|
;;
|
||||||
dreamcast | ds | gamecube | n64 | ps2 | psp | wii)
|
3ds | dreamcast | ds | gamecube | n64 | ps2 | psp | wii)
|
||||||
_exeext=".elf"
|
_exeext=".elf"
|
||||||
;;
|
;;
|
||||||
gph-linux)
|
gph-linux)
|
||||||
|
@ -843,9 +843,9 @@ Usage: $0 [OPTIONS]...
|
||||||
|
|
||||||
Configuration:
|
Configuration:
|
||||||
-h, --help display this help and exit
|
-h, --help display this help and exit
|
||||||
--backend=BACKEND backend to build (android, tizen, dc, dingux, ds, gcw0,
|
--backend=BACKEND backend to build (3ds, android, dc, dingux, ds, gcw0,
|
||||||
gph, iphone, ios7, linuxmoto, maemo, n64, null, openpandora,
|
gph, iphone, ios7, linuxmoto, maemo, n64, null, openpandora,
|
||||||
ps2, psp, samsungtv, sdl, webos, wii, wince) [sdl]
|
ps2, psp, samsungtv, sdl, tizen, webos, wii, wince) [sdl]
|
||||||
|
|
||||||
Installation directories:
|
Installation directories:
|
||||||
--prefix=PREFIX install architecture-independent files in PREFIX
|
--prefix=PREFIX install architecture-independent files in PREFIX
|
||||||
|
@ -871,10 +871,10 @@ Fine tuning of the installation directories:
|
||||||
|
|
||||||
Special configuration feature:
|
Special configuration feature:
|
||||||
--host=HOST cross-compile to target HOST (arm-linux, ...)
|
--host=HOST cross-compile to target HOST (arm-linux, ...)
|
||||||
special targets: android-arm for Android ARM
|
special targets: 3ds for Nintendo 3DS
|
||||||
|
android-arm for Android ARM
|
||||||
android-mips for Android MIPS
|
android-mips for Android MIPS
|
||||||
android-x86 for Android x86
|
android-x86 for Android x86
|
||||||
tizen for Samsung Tizen
|
|
||||||
caanoo for Caanoo
|
caanoo for Caanoo
|
||||||
dingux for Dingux
|
dingux for Dingux
|
||||||
raspberrypi for Raspberry Pi
|
raspberrypi for Raspberry Pi
|
||||||
|
@ -897,6 +897,7 @@ Special configuration feature:
|
||||||
ps3 for PlayStation 3
|
ps3 for PlayStation 3
|
||||||
psp for PlayStation Portable
|
psp for PlayStation Portable
|
||||||
samsungtv for Samsung TV
|
samsungtv for Samsung TV
|
||||||
|
tizen for Samsung Tizen
|
||||||
webos for HP Palm WebOS
|
webos for HP Palm WebOS
|
||||||
wii for Nintendo Wii
|
wii for Nintendo Wii
|
||||||
wince for Windows CE
|
wince for Windows CE
|
||||||
|
@ -1309,6 +1310,11 @@ get_system_exe_extension $guessed_host
|
||||||
NATIVEEXEEXT=$_exeext
|
NATIVEEXEEXT=$_exeext
|
||||||
|
|
||||||
case $_host in
|
case $_host in
|
||||||
|
3ds)
|
||||||
|
_host_os=3ds
|
||||||
|
_host_cpu=arm
|
||||||
|
_host_alias=arm-none-eabi
|
||||||
|
;;
|
||||||
android | android-arm | android-v7a | android-arm-v7a | ouya)
|
android | android-arm | android-v7a | android-arm-v7a | ouya)
|
||||||
_host_os=android
|
_host_os=android
|
||||||
_host_cpu=arm
|
_host_cpu=arm
|
||||||
|
@ -1590,7 +1596,7 @@ android)
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
ds | gamecube | wii)
|
3ds | ds | gamecube | wii)
|
||||||
if test -z "$DEVKITPRO"; then
|
if test -z "$DEVKITPRO"; then
|
||||||
echo "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to devkitPRO>"
|
echo "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to devkitPRO>"
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -1846,7 +1852,7 @@ if test "$have_gcc" = yes ; then
|
||||||
case $_host_os in
|
case $_host_os in
|
||||||
# newlib-based system include files suppress non-C89 function
|
# newlib-based system include files suppress non-C89 function
|
||||||
# declarations under __STRICT_ANSI__
|
# declarations under __STRICT_ANSI__
|
||||||
amigaos* | android | dreamcast | ds | gamecube | mingw* | n64 | psp | ps2 | ps3 | tizen | wii | wince )
|
3ds | amigaos* | android | dreamcast | ds | gamecube | mingw* | n64 | psp | ps2 | ps3 | tizen | wii | wince )
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
append_var CXXFLAGS "-ansi"
|
append_var CXXFLAGS "-ansi"
|
||||||
|
@ -2146,6 +2152,27 @@ esac
|
||||||
echo_n "Checking hosttype... "
|
echo_n "Checking hosttype... "
|
||||||
echo $_host_os
|
echo $_host_os
|
||||||
case $_host_os in
|
case $_host_os in
|
||||||
|
3ds)
|
||||||
|
_optimization_level=-O2
|
||||||
|
append_var DEFINES "-D__3DS__"
|
||||||
|
append_var DEFINES "-DARM"
|
||||||
|
append_var DEFINES "-DARM11"
|
||||||
|
append_var CXXFLAGS "-march=armv6k"
|
||||||
|
append_var CXXFLAGS "-mtune=mpcore"
|
||||||
|
append_var CXXFLAGS "-mword-relocations"
|
||||||
|
append_var CXXFLAGS "-mfloat-abi=hard"
|
||||||
|
append_var CXXFLAGS "-ffunction-sections"
|
||||||
|
append_var CXXFLAGS "-fomit-frame-pointer"
|
||||||
|
append_var CXXFLAGS "-I$DEVKITPRO/libctru/include"
|
||||||
|
append_var CXXFLAGS "-I$DEVKITPRO/portlibs/3ds/include"
|
||||||
|
if test "$_dynamic_modules" = no ; then
|
||||||
|
append_var LDFLAGS "-Wl,--gc-sections"
|
||||||
|
else
|
||||||
|
append_var LDFLAGS "-Wl,--no-gc-sections"
|
||||||
|
fi
|
||||||
|
append_var LDFLAGS "-L$DEVKITPRO/portlibs/3ds/lib"
|
||||||
|
append_var LIBS "-lcitro3d -lctru"
|
||||||
|
;;
|
||||||
amigaos*)
|
amigaos*)
|
||||||
append_var LDFLAGS "-Wl,--export-dynamic"
|
append_var LDFLAGS "-Wl,--export-dynamic"
|
||||||
append_var LDFLAGS "-L/sdk/local/newlib/lib"
|
append_var LDFLAGS "-L/sdk/local/newlib/lib"
|
||||||
|
@ -2583,6 +2610,18 @@ if test -n "$_host"; then
|
||||||
# Cross-compiling mode - add your target here if needed
|
# Cross-compiling mode - add your target here if needed
|
||||||
echo "Cross-compiling to $_host"
|
echo "Cross-compiling to $_host"
|
||||||
case "$_host" in
|
case "$_host" in
|
||||||
|
3ds)
|
||||||
|
append_var DEFINES "-DDISABLE_FANCY_THEMES"
|
||||||
|
append_var DEFINES "-DDISABLE_SID"
|
||||||
|
append_var DEFINES "-DDISABLE_NES_APU"
|
||||||
|
_backend="3ds"
|
||||||
|
_build_scalers=no
|
||||||
|
_vkeybd=yes
|
||||||
|
_mt32emu=no
|
||||||
|
# Should use Tremor instead of Vorbis
|
||||||
|
_vorbis=no
|
||||||
|
_port_mk="backends/platform/3ds/3ds.mk"
|
||||||
|
;;
|
||||||
android | android-arm | android-v7a | android-arm-v7a | android-mips | android-x86 | ouya)
|
android | android-arm | android-v7a | android-arm-v7a | android-mips | android-x86 | ouya)
|
||||||
# we link a .so as default
|
# we link a .so as default
|
||||||
append_var LDFLAGS "-shared"
|
append_var LDFLAGS "-shared"
|
||||||
|
@ -3042,6 +3081,8 @@ fi
|
||||||
# Backend related stuff
|
# Backend related stuff
|
||||||
#
|
#
|
||||||
case $_backend in
|
case $_backend in
|
||||||
|
3ds)
|
||||||
|
;;
|
||||||
android)
|
android)
|
||||||
append_var DEFINES "-DREDUCE_MEMORY_USAGE"
|
append_var DEFINES "-DREDUCE_MEMORY_USAGE"
|
||||||
append_var CXXFLAGS "-Wa,--noexecstack"
|
append_var CXXFLAGS "-Wa,--noexecstack"
|
||||||
|
@ -3144,6 +3185,8 @@ case $_backend in
|
||||||
append_var LDFLAGS "-shared"
|
append_var LDFLAGS "-shared"
|
||||||
append_var LDFLAGS "-fpic"
|
append_var LDFLAGS "-fpic"
|
||||||
;;
|
;;
|
||||||
|
sdl)
|
||||||
|
;;
|
||||||
tizen)
|
tizen)
|
||||||
# dirent.h not available. NONSTANDARD_PORT==ensure portdefs.h is included
|
# dirent.h not available. NONSTANDARD_PORT==ensure portdefs.h is included
|
||||||
append_var DEFINES "-DTIZEN -DDISABLE_STDIO_FILESTREAM -DNONSTANDARD_PORT"
|
append_var DEFINES "-DTIZEN -DDISABLE_STDIO_FILESTREAM -DNONSTANDARD_PORT"
|
||||||
|
@ -3192,8 +3235,6 @@ case $_backend in
|
||||||
append_var DEFINES "-DSDL_BACKEND"
|
append_var DEFINES "-DSDL_BACKEND"
|
||||||
add_line_to_config_mk "SDL_BACKEND = 1"
|
add_line_to_config_mk "SDL_BACKEND = 1"
|
||||||
;;
|
;;
|
||||||
sdl)
|
|
||||||
;;
|
|
||||||
*)
|
*)
|
||||||
echo "support for $_backend backend not implemented in configure script yet"
|
echo "support for $_backend backend not implemented in configure script yet"
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -3228,7 +3269,7 @@ esac
|
||||||
# Enable 16bit support only for backends which support it
|
# Enable 16bit support only for backends which support it
|
||||||
#
|
#
|
||||||
case $_backend in
|
case $_backend in
|
||||||
android | dingux | dc | gph | iphone | ios7 | maemo | openpandora | psp | samsungtv | sdl | tizen | webos | wii)
|
3ds | android | dingux | dc | gph | iphone | ios7 | maemo | openpandora | psp | samsungtv | sdl | tizen | webos | wii)
|
||||||
if test "$_16bit" = auto ; then
|
if test "$_16bit" = auto ; then
|
||||||
_16bit=yes
|
_16bit=yes
|
||||||
else
|
else
|
||||||
|
@ -3307,7 +3348,7 @@ case $_host_os in
|
||||||
amigaos* | cygwin* | dreamcast | ds | gamecube | mingw* | n64 | ps2 | ps3 | psp | wii | wince)
|
amigaos* | cygwin* | dreamcast | ds | gamecube | mingw* | n64 | ps2 | ps3 | psp | wii | wince)
|
||||||
_posix=no
|
_posix=no
|
||||||
;;
|
;;
|
||||||
android | beos* | bsd* | darwin* | freebsd* | gnu* | gph-linux | haiku* | hpux* | iphone | ios7 | irix*| k*bsd*-gnu* | linux* | maemo | mint* | netbsd* | openbsd* | solaris* | sunos* | uclinux* | webos)
|
3ds | android | beos* | bsd* | darwin* | freebsd* | gnu* | gph-linux | haiku* | hpux* | iphone | ios7 | irix*| k*bsd*-gnu* | linux* | maemo | mint* | netbsd* | openbsd* | solaris* | sunos* | uclinux* | webos)
|
||||||
_posix=yes
|
_posix=yes
|
||||||
;;
|
;;
|
||||||
os2-emx*)
|
os2-emx*)
|
||||||
|
@ -4561,6 +4602,14 @@ fi
|
||||||
# after all of CXXFLAGS, LDFLAGS, LIBS etc. have been setup
|
# after all of CXXFLAGS, LDFLAGS, LIBS etc. have been setup
|
||||||
#
|
#
|
||||||
case $_backend in
|
case $_backend in
|
||||||
|
3ds)
|
||||||
|
if test "$_freetype2" = yes -a "$_png" = yes; then
|
||||||
|
append_var LIBS "-lpng"
|
||||||
|
fi
|
||||||
|
if test "$_tremor" = yes -o "$_flac" = yes; then
|
||||||
|
append_var LIBS "-logg"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
android)
|
android)
|
||||||
# ssp at this point so the cxxtests link
|
# ssp at this point so the cxxtests link
|
||||||
if test "$_debug_build" = yes; then
|
if test "$_debug_build" = yes; then
|
||||||
|
|
|
@ -844,6 +844,10 @@ begin_credits("Credits");
|
||||||
add_person("Frantisek Dufka", "fanoush", "(retired)");
|
add_person("Frantisek Dufka", "fanoush", "(retired)");
|
||||||
add_person("Tarek Soliman", "tsoliman", "");
|
add_person("Tarek Soliman", "tsoliman", "");
|
||||||
end_section();
|
end_section();
|
||||||
|
|
||||||
|
begin_section("Nintendo 3DS");
|
||||||
|
add_person("Thomas Edvalson", "Cruel", "");
|
||||||
|
end_section();
|
||||||
|
|
||||||
begin_section("Nintendo 64");
|
begin_section("Nintendo 64");
|
||||||
add_person("Fabio Battaglia", "Hkz", "");
|
add_person("Fabio Battaglia", "Hkz", "");
|
||||||
|
|
|
@ -366,6 +366,9 @@ static const char *credits[] = {
|
||||||
"C2""(retired)",
|
"C2""(retired)",
|
||||||
"C0""Tarek Soliman",
|
"C0""Tarek Soliman",
|
||||||
"",
|
"",
|
||||||
|
"C1""Nintendo 3DS",
|
||||||
|
"C0""Thomas Edvalson",
|
||||||
|
"",
|
||||||
"C1""Nintendo 64",
|
"C1""Nintendo 64",
|
||||||
"C0""Fabio Battaglia",
|
"C0""Fabio Battaglia",
|
||||||
"",
|
"",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue