aboutsummaryrefslogtreecommitdiff
path: root/backends/platform/ds/arm9
diff options
context:
space:
mode:
authorMax Horn2008-09-15 22:43:20 +0000
committerMax Horn2008-09-15 22:43:20 +0000
commit05d78c26b442bccc1d1e773591900ad0d2087278 (patch)
tree8c44d59eef4897d8409ab216a5e9760ab4160038 /backends/platform/ds/arm9
parent880bc085b160c642e360332546fe90f47a5ea852 (diff)
downloadscummvm-rg350-05d78c26b442bccc1d1e773591900ad0d2087278.tar.gz
scummvm-rg350-05d78c26b442bccc1d1e773591900ad0d2087278.tar.bz2
scummvm-rg350-05d78c26b442bccc1d1e773591900ad0d2087278.zip
DS: Backported 0.12 changes to trunk
svn-id: r34568
Diffstat (limited to 'backends/platform/ds/arm9')
-rw-r--r--backends/platform/ds/arm9/dist/readme_ds.txt840
-rw-r--r--backends/platform/ds/arm9/makefile52
-rw-r--r--backends/platform/ds/arm9/source/cdaudio.h2
-rw-r--r--backends/platform/ds/arm9/source/dsmain.cpp706
-rw-r--r--backends/platform/ds/arm9/source/dsmain.h13
-rw-r--r--backends/platform/ds/arm9/source/dsoptions.cpp283
-rw-r--r--backends/platform/ds/arm9/source/dsoptions.h13
-rw-r--r--backends/platform/ds/arm9/source/gbampsave.cpp4
-rw-r--r--backends/platform/ds/arm9/source/osystem_ds.cpp232
-rw-r--r--backends/platform/ds/arm9/source/osystem_ds.h26
-rw-r--r--backends/platform/ds/arm9/source/portdefs.h5
-rw-r--r--backends/platform/ds/arm9/source/ramsave.cpp10
-rw-r--r--backends/platform/ds/arm9/source/ramsave.h4
-rw-r--r--backends/platform/ds/arm9/source/touchkeyboard.cpp30
-rw-r--r--backends/platform/ds/arm9/source/touchkeyboard.h1
15 files changed, 1913 insertions, 308 deletions
diff --git a/backends/platform/ds/arm9/dist/readme_ds.txt b/backends/platform/ds/arm9/dist/readme_ds.txt
new file mode 100644
index 0000000000..f77da418c9
--- /dev/null
+++ b/backends/platform/ds/arm9/dist/readme_ds.txt
@@ -0,0 +1,840 @@
+
+
+
+ The official port of ScummVM
+ to the Nintendo DS handheld console
+ by Neil Millstone (agentq)
+ http://scummvm.drunkencoders.com
+------------------------------------------------------------------------
+Visit the main ScummVM website <http://www.scummvm.org>
+
+
+
+
+ Contents
+ ------------------------------------------------------------------------
+
+
+
+ * What's New?
+ * What is ScummVM DS?
+ * Features
+ * Screenshots
+ * How to Get ScummVM DS Onto Your DS - Simple Explanation
+ o Using a CF/SD/Mini SD/Micro SD card reader and a DLDI driver
+ o Instructions for specific card readers
+ * What to do if saving doesn't work or your card gets corruped -
+ force SRAM saves
+ * How to use ScummVM DS
+ * Game Specific Controls
+ * DS Options Screen
+ * Which games are compatible with ScummVM DS
+ * Predictive dictionary for Sierra AGI games
+ * Converting your CD audio
+ * Converting speech to MP3 format
+ * Frequently Asked Questions
+ * Downloads
+ * Contributors
+ * Donations and Getting Help
+ * Building from Sources
+
+
+
+ What's New?
+ ------------------------------------------------------------------------
+
+ScummVM DS 0.12.0
+
+ * New games supported: Lure of the Temptress, Nippon Safes, Lost in Time.
+ * New laptop-style trackpad input method. Uses relative movement when you
+ drag on the touch screen.
+ * New option which allows you to drag to hover, tap the touch screen to
+ click, and double tap the screen to right click.
+ * Reorganised DS Options screen into three tabs for clearer navigation
+ * New top screen scaling options let you choose the scaling factor used
+ on startup.
+ * The usual round of bug fixes.
+
+
+ScummVM DS 0.11.1
+
+ * Bugfix release - No new DS port features
+
+
+ScummVM DS 0.11.0
+
+ * New games supported: Elvira 1 and 2, Waxworks (Amiga version)
+ * Software scaler for improved image quality. Turn it on using the DS options
+ screen (press select during the game). Thanks to Tramboi and Robin Watts for
+ this feature!
+ * Function keys added to virtual keyboard (used in AGI games)
+ * Plenty of bug fixes
+
+ What is ScummVM DS?
+ ------------------------------------------------------------------------
+
+ScummVM DS is a part of the ScummVM project. The ScummVM project is an
+attempt to re-engineer many classic point and click adventure games of the
+80s and 90s to run on modern computer hardware. Technology has changed a
+lot since these games were written, and so ScummVM attempts to replicate the
+gameplay of the original games in exacting details, without any of the original
+code that the game ran on. ScummVM needs a copy of the original game, in order
+to take the graphics, sound, and scripts that made the game work.
+
+ScummVM is written in such a way that it can be 'ported' from one type of
+machine to another, and ScummVM DS is a port of ScummVM to the Nintendo DS
+handheld games console.
+
+
+ Features
+ ------------------------------------------------------------------------
+
+ * Runs nearly all of Lucasarts' SCUMM games up to and including Sam
+ & Max Hit the Road
+ * Runs many non-Lucasarts point-and-click adventures too
+ * Supports sound
+ * Provides a GUI to change settings and choose games
+ * Supports using the DS touch screen for controls
+ * Suports saving games to compatible flash cards
+ * All games run at pretty much full speed
+
+
+
+
+
+ How to Get ScummVM DS Onto Your DS - Simple Explanation
+ ------------------------------------------------------------------------
+
+Nintendo don't want you to run ScummVM on your DS. They control
+which companies can make games on the DS, and there is an expensive
+process to go through in order to be licenced. Having to pay for
+this would prevent me from giving away ScummVM for free.
+
+So, the result is that to run ScummVM on your DS you'll need an
+unofficial card reader. There are many of these, and all are different.
+Popular models at the time of writing are the R4DS and the M3DS Real,
+but many different models work. You need to buy one of these, and at
+MicroSD card to go with it.
+
+There are also slot-2 card readers which fit into the bottom slot on
+your DS, usually used for Game Boy Advance games. These are less common
+these days, and although they have certain advantages, the details of
+these are beyond the scope of this website. Information on these is
+quite easy to find by searching.
+
+Once you have your card reader and a MicroSD card, you will also need
+a copy of the game you want to run. ScummVM can run a large variety
+of games, but you must own a real boxed copy of the game. These games
+are still under copyright, and it is illegal to copy them from a friend
+or download them from the Internet without paying. The exception to
+this are the three Revolution Software games. These are 'Beneath a
+Steel Sky', 'Lure of the Temptress' and 'Flight of the Amazon Queen'.
+Revolution have kindly allowed us to give these games away for free.
+You can download them from the main ScummVM site at
+<http://www.scummvm.org/downloads.php>
+
+NOTE: Previous version of ScummVM DS supported a method which used a
+zip file to run games on unsupported flash card readers. This method
+is no longer supported.
+
+
+ How to Get ScummVM DS Onto Your DS - Using a CF/SD/Mini SD/Micro
+ SD card reader and a DLDI driver
+ ------------------------------------------------------------------------
+
+ScummVM DS needs something called a DLDI driver to run on each make
+and model of card reader. Many modern card readers (R4DS, M3 DS Real)
+handle this autmatically and for those, you don't have to do anything.
+Just running ScummVM on the card will handle this step for you.
+For others, you will need to follow the steps in this section before
+ScummVM DS will work.
+
+All DS card readers are different in the way that they work. In order to
+support many different card readers, ScummVM DS uses a DLDI driver installed
+into the ScummVM DS code. This is done using a program called DLDITool
+which you can download and run on your computer. Each DLDI driver is
+designed to tell ScummVM DS how to use a specific type of card reader.
+These drivers can be used with any homebrew program which supports the
+DLDI interface.
+
+While each card reader should work with these instructions, there are
+some exceptions. Please read the card reader notes
+section to see if there is any specific information about your card reader.
+
+Here is what you need to do:
+
+ * Visit the DLDI page <http://dldi.drunkencoders.com/> and
+ download the executable for DLDITool for your operating system
+ (versions are available for Windows, Linux, and MacOS)
+ * Download the DLDI for your card reader. This is the big table at
+ the top of the page. The first column marked DLDI is the one you
+ want. You should get a single file with a .dldi extension.
+ * Extract DLDITool into a folder, and put the DLDI of your choice in
+ the same folder.
+ * If you're using the command line version of DLDITool enter the
+ following at a command prompt:
+
+ dlditool <dldiname> <scummvm nds name>
+
+
+ If you're using the Windows GUI version, double click on
+ dlditool32.exe, select your card reader from the box, drag your
+ ScummVM binaries (either the .nds, or the .ds.gba version
+ depending on your card reader. I think only Supercards use the
+ .ds.gba files) into the lower box, then click patch.
+
+ Either way, you should see 'Patched Successfully'. If you don't,
+ you're doing something wrong.
+
+ You need to patch one of the builds labeled A - F depending on
+ which game you want to run. See the table on the ScummVM DS
+ website to see which games are supported by which build.
+
+ * Put the patched .nds or .ds.gba files on your flash card. If
+ you're using the Supercard, you will need to use the .ds.gba
+ files, but rename them to .nds.
+ * Put your game data in any folder on the card. Do NOT use a zip file.
+ * Boot up your DS and run ScummVM.
+ * Click 'Add Game', browse to the folder with your game data, click
+ 'Choose', then 'OK'. Click 'Start' to run the game.
+
+If your copy of ScummVM DS has been successfully patched, you will get a
+message on the top screen that looks like this:
+
+ DLDI Device:
+ GBA Movie Player (Compact Flash)
+
+The message should show the name of your card reader. If it is wrong,
+you have used the wrong DLDI file.
+
+If you haven't patched your .nds file, you will get the following message
+
+ DLDI Driver not patched!
+ DLDI Initialise failed.
+
+In this case, you've made a mistake following the above instructions, or
+have patched the wrong file.
+
+You may also see the following message:
+
+ DLDI Device:
+ GBA Movie Player (Compact Flash)
+ DLDI Initialise failed.
+
+In this case, the driver did not start up correctly. The driver is
+probably broken, or you've used the wrong one for your card reader.
+
+In the case of the Supercard, M3 Lite and DS Link, there are several
+drivers available. You might want to try one of the others.
+
+This version of ScummVM DS will run on any card reader that has a DLDI
+driver available. If yours doesn't, you need to pressure your card
+reader manufacturer to release one.
+
+DO NOT EMAIL ME TO ASK ME TO CREATE A DRIVER FOR YOUR CARD READER, I
+CANNOT DO THIS.
+
+
+ How to Get ScummVM DS Onto Your DS - Instructions for specific
+ card readers
+ ------------------------------------------------------------------------
+
+ * *GBAMP CF:* You need to upload replacement firmware to your card
+ reader before it will work. You can download the firmware program
+ here <http://chishm.drunkencoders.com/NDSMP/index.html>. Name your
+ .nds file _BOOT_MP.nds.
+ * *M3 CF/SD:* Copy the .nds file to your card with the M3 Game
+ Manager in order to avoid an annoying message when you boot your
+ M3. Use the default options to copy the file. Be sure to press 'A'
+ in the M3 browser to start the .nds file, and not 'Start', or it
+ won't work.
+ * *M3 CF/SD:* Copy the .nds file to your card with the M3 Game
+ Manager in order to avoid an annoying message when you boot your
+ M3. Use the default options to copy the file. Be sure to press 'A'
+ in the M3 browser to start the .nds file, and not 'Start', or it
+ won't work.
+ * *Supercard CF/SD (slot-2):* Use the .ds.gba files to run ScummVM
+ on the Supercard. Other than that, just follow the instructions as
+ normal.
+ * *Supercard Lite (slot-2):* It has been reported that only the
+ standard Supercard driver and the Moonshell version work with
+ ScummVM DS.
+ * *Datel Max Media Dock: * If you haven't already, upgrade your
+ firmware to the latest version. The firmware that came with my Max
+ Media Dock was unable to run ScummVM DS at all. Click here to
+ visit Datel's support page and download the latest firmware
+ <http://us.codejunkies.com/mpds/support.htm>
+ * *NinjaDS*: There are firmware upgrades for this device, but for
+ me, ScummVM DS ran straight out of the box. Visit this page
+ <http://www.ninjads.com/news.html> to download the latest firmware
+ if you want. If you have installed FlashMe on your DS, it will
+ make your DS crash on boot when the NinjaDS is inserted. You can
+ hold the 'select' button during boot to disable FlashMe, which
+ will allow the NinjaDS to work. Due to this, it is not recommended
+ to install FlashMe if you use a NinjaDS.
+ * *EZ-Flash*: This card reader uses .ds.gba files from the ScummVM
+ archive. Rename them to .nds before patching them with the DLDI
+ patcher.
+ * *R4DS*: If you upgrade the firmware for your R4DS to version 1.10
+ or later, the card will autmatically DLDI patch the game, meaning
+ you don't have to use dlditool to patch the .NDS file. This makes
+ things a lot easier!
+ * *M3DS Real*: This card autmatically DLDI patches the game, meaning
+ that you do not need to do this yourself.
+
+
+
+ Which games are compatible with ScummVM DS?
+ ------------------------------------------------------------------------
+
+I'm glad you asked. Here is a list of the compatible games in version
+0.12.0. Demo versions of the games listed should work too.
+
+Flight of the Amazon Queen, Beneath a Steel Sky, and Lure of the
+Temptress have generously been released as freeware by the original
+authors, Revolution Software <http://www.revolution.co.uk/>. This is a
+great thing and we should support Revolution for being so kind to us.
+You can download the game data from the official ScummVM download page
+<http://www.scummvm.org/downloads.php>.
+
+The other games on this list are commercial, and still under copyright,
+which means downloading them without paying for it is illegal. You can
+probably find a second-hand copy on eBay. Please don't email me to ask
+for a copy, as I am unable to send it to you.
+
+Game Build Notes
+
+Manic Mansion A
+
+Zak McKracken and the Alien Mindbenders A
+
+Indiana Jones and the Last Crusade A
+
+Loom A
+
+Passport to Adventure A
+
+The Secret of Monkey Island A
+
+Monkey Island 2: LeChuck's Revenge A
+
+Indiana Jones and the Fate of Atlantis A
+
+Day of the Tentacle A
+
+Sam & Max Hit the Road A Some slowdown in a few scenes
+ when MP3 audio is enabled
+
+Bear Stormin' (DOS) A
+
+Fatty Bear's Birthday Surprise (DOS) A
+
+Fatty Bear's Fun Pack (DOS) A
+
+Putt-Putt's Fun Pack (DOS) A
+
+Putt-Putt Goes to the Moon (DOS) A
+
+Putt-Putt Joins the Parade (DOS) A Can sometimes crash due to low memory
+
+Beneath a Steel Sky B
+
+Flight of the Amazon Queen B
+
+Simon the Sorcerer 1 C Zoomed view does not follow the
+ speaking character
+Simon the Sorcerer 2 C Zoomed view does not follow the
+ speaking character
+Elvira 1 C
+
+Elvira 2 C
+
+Waxworks (Amiga version) C
+
+Gobliiins D
+
+Gobliins 2 D
+
+Goblins 3 D
+
+Ween: The Prophecy D
+
+Bargon Attack D
+
+Lost in Time D
+
+Future Wars D
+
+All Sierra AGI games.
+For a complete list, see this page
+<http://wiki.scummvm.org/index.php/AGI> D
+
+Inherit the Earth E
+
+The Legend of Kyrandia F Zoomed view does not follow the
+ speaking character
+
+Lure of the Temptress G
+
+Nippon Safes G
+
+There is no support for Full Throttle, The Dig, or The Curse of Monkey
+Island because of memory issues. There simply is not enough RAM on the
+DS to run these games. Sorry. Also there is no support for Windows Humongous
+Entertainment games. The extra code required to make this work uses up
+too much RAM.
+
+
+ What to do when saving doesn't work or your card gets corrupted -
+ forcing SRAM Saves
+ ------------------------------------------------------------------------
+
+This method only works for cards which use the Game Boy Advance slot on the
+bottom of your DS.
+
+If ScummVM DS cannot save games to your SD card, or it causes corruption
+when it does, you can force it to use GBA SRAM to save the game. This
+uses your flash cart reader's GBA features to save the game to a .sav or
+.dat file (depending on the reader). Only slot-2 devices can use SRAM saves,
+and only ones with support for GBA games.
+
+If you want to use SRAM save, just create a text file called scummvm.ini
+(or scummvmb.ini, scummvmc.ini for builds B or C) in the root of your
+card which contains the following:
+
+[ds]
+forcesramsave=true
+
+When you boot your game, ScummVM DS will not save games to your SD card
+directly, instead it will save to GBA SRAM. On most cards, you need to
+transfer the data to your SD card by rebooting and using your card
+reader's boot-up menu. Using this method, around four saves can me made.
+
+One disadvantage of forcing SRAM saves is that your settings won't be
+saved. You can add games manually to the ini file so that you don't have
+to select them on each boot. Just add a section like the following on
+for each game on your card.
+
+[monkey2]
+description=Monkey Island 2: LeChuck's Revenge (English/DOS)
+path=mp:/MONKEY2
+
+
+ How to Use ScummVM
+ ------------------------------------------------------------------------
+
+Once you've booted up ScummVM, you'll see the start up screen.
+
+ 1. Tap the 'Add' button with the pen, then browse to the folder
+ containing your game data. Once you have clicked on your folder, you will
+ not see any files inside. This is normal, as the folder selector only shows
+ folders!
+
+ 2. Click the 'Choose' button.
+
+ 3. You will get some options for the game. You can usually just click 'Ok' to
+ this.
+
+ 4. Now click on the name of the game you want to play from the list and
+ click 'Start'. Your game will start!
+
+You can use the B button to skip cutscenes, and the select button to
+show an options menu which will let you tweak the DS contols, including
+switch between scaled and unscaled video modes. The text is clearer in
+the unscaled mode, but the whole game doesn't fit on the screen. To
+scroll around, hold either shoulder button and use the D-pad or drag the
+screen around with the stylus. Even in scaled mode, a small amount is
+missing from the top and bottom of the screen. You can scroll around to
+see those areas. The top screen shows a zoomed-in view. This scrolls
+around to focus on the character who's speaking, and also follows where
+the pen touches the screen. You can change the zoom level by holding one
+of the shoulder buttons and pressing B to zoom in and A to zoom out.
+
+Press the start button for the in-game menu where you can load or save
+your game (this works in Lucasarts games, other games vary). Saves will
+write directly to your flash card. You can choose the folder where they
+are stored using the GUI that appears when you boot up. If you're using
+a GBA Flash Cartridge, or an unsupported flash card adaptor, you will be
+using GBA SRAM to save your game. Four or five save game will fit in
+save RAM. If you save more games than will fit, a warning will appear on
+the top screen. When you turn your DS off, the new save will be lost,
+and only the first ones you saved will be present.
+
+Many of the games use both mouse buttons. Usually the right button often
+performs the default action on any object you click on. To simulate this
+with the DS pen, you can switch the input into one of three modes. Press
+left on the D-pad to enable the left mouse button. Press right on the
+D-pad to enable the right mouse button. Press up on the D-pad to enable
+hover mode. In this mode, you won't click on anything, just hover the
+mouse cursor over it. This lets you pick out active objects in the scene.
+
+An icon on the top screen will show you which mode you're in.
+
+In hover mode, there are some additional controls. While holding the pen
+on the screen, tapping D-pad left or D-pad right (or A/Y in left handed
+mode) will click the left or right mouse button.
+
+There is an alternative method of control which doesn't require you to
+change modes with the D-pad. Press 'Select' to bring up the DS options,
+and choose 'Tap for left click, double tap for right click'. In this
+mode, you can quickly tap the screen to left click the mouse, and tap twice
+to right click the mouse.
+
+
+Here is a complete list of controls in right-handed mode (the default
+setting):
+Key Usage
+Pad Left Left mouse button
+Pad Right Right mouse button
+Pad Up Hover mouse (no mouse button)
+Pad Down Skip dialogue line (for some Lucasarts games), Show inventory
+ (for Beneath a Steel Sky), Show active objects (for Simon the Sorceror)
+Start Pause/game menu (works in some games)
+Select DS Options
+B Skip cutscenes
+A Swap main screen and zoomed screen
+Y Show/Hide debug console
+X Show/Hide on-screen keyboard
+L + D-pad or L + Pen Scroll touch screen view
+L + B Zoom in
+L + A Zoom out
+
+
+
+And here's left-handed mode:
+Key Usage
+Y Left mouse button
+A Right mouse button
+X Hover mouse (no mouse button)
+B Skip dialogue line (for some Lucasarts games), Show inventory (for
+ Beneath a Steel Sky), Show active objects (for Simon the Sorceror)
+Start Pause/game menu (works in some games)
+Select DS Options
+D-pad down Skip cutscenes
+D-pad up Swap main screen and zoomed screen
+D-pad left Show/Hide debug console
+D-pad right Show/Hide on-screen keyboard
+R + D-pad or R + Pen Scroll touch screen view
+R + D-pad down Zoom in
+R + d-pad right Zoom out
+
+
+
+ Game-specific controls
+ ------------------------------------------------------------------------
+
+ * Sam and Max Hit the Road: The current cursor mode is displayed on
+ the top screen. Use d-pad right to switch mode.
+ * Indiana Jones games: If you get into a fight, press Select, and
+ check the box marked 'Use Indy Fighting Controls'.
+ Return to the game, then use the following controls to fight:
+
+ D-pad left: move left
+ D-pad right: move right
+ D-pad up: guard up
+ D-pad down: guard down
+ Y: guard middle
+ X: Punch high
+ A: Punch middle
+ B: Punch low
+ Left shoulder: Fight towards the left
+ Right shoulder: Fight towards the right
+
+ The icon on the top screen shows which way you're currently
+ facing. Remember to turn the option off when the fight ends, or
+ the normal controls won't work!
+ * Beneath a Steel Sky: Press D-pad down to show your inventory.
+ * Simon the Sorcerer 1/2: Press D-pad down to show active objects.
+ * AGI games: Press Start to show the menu bar.
+ * Bargon Attack: Press Start to hit F1 when you need to start the
+ game. Use the on-screen keyboard (hit X) to press other function keys.
+
+
+ DS Options Screen
+ ------------------------------------------------------------------------
+
+Pressing the 'select' button during any game to show the DS options
+screen. This screen shows options specific to the Nintendo DS version
+of ScummVM.
+
+Controls tab
+
+Indy Fight Controls - Enable fighting controls for the Indiana Jones
+games. See 'Game Specific Controls' for more information.
+
+Left handed Mode - Switch the controls on the D-pad with the controls
+on the A/B/X/Y buttons.
+
+Show mouse cursor - Shows the game's mouse cursor on the bottom screen.
+
+Snap to edges - makes it easier for the mouse controls to reach the edges
+of the screen. Useful for Beneath a Steel Sky and Goblins 3.
+
+Touch X offset - if your screen doesn't perform properly, this setting
+allows you to adjust when the cursor appears left or right relative to
+the screen's measured touch position.
+
+Touch Y offset - if your screen doesn't perform properly, this setting
+allows you to adjust when the cursor appears higher or lower relative to
+the screen's measured touch position.
+
+Use Laptop Trackpad-style cursor control - In this mode, use the lower
+screen to drag the cursor around, a bit like using a trackpad on a laptop.
+When this option is enabled, the following option is also enabled.
+
+Tap for left click, double tap for right click - In this mode, you can
+quickly tap on the screen to left click the mouse, or quickly
+double tap on the screen to right click the mouse. If you find clicking
+or double-clicking difficult, try and make a firmer touch on the screen,
+and keep the pen down for longer.
+
+Sensitivity - this bar adjusts the speed of cursor movement when laptop
+trackpad-style cursor control is enabled (see above).
+
+Graphics Tab
+
+Scaling options:
+
+Three scaling options are available for the main screen.
+
+Harware Scale - Scales using the DS hardware scaler using a flicker method.
+Produces lower quality graphics but doesn't slow the game down.
+
+Software Scale - Scales using the CPU. A much higher quality image is
+produced, but at the expense of speed in some games.
+
+Unscaled - Allows you to see the graphics as originaly displayed. This
+doesn't fit on the DS screen, but you can scroll the screen around by holding
+the left shoulder button and using the D-pad or touch screen.
+
+Top screen zoom - These three options control the zoom level of the top
+screen when ScummVM is started up. Changing this option will set the zoom
+to the specified level immediately.
+
+Initial top screen scale:
+
+This option controls the scaling level of the zoomed screen. In ScummVM
+DS, one screen shows a zoomed-in view of the action, and this option controls
+how zoomed in it is. You can also adjust this in the game by holding L and
+pressing A/B.
+
+General Tab
+
+High Quality Audio - Enhance the sound quality, at the expense of some
+slowdown during some games.
+
+Disable power off - ScummVM DS turns the power off when the game quits.
+This option disables that feature.
+
+
+
+
+
+
+ Auto completion dictionary for Sierra AGI games
+ ------------------------------------------------------------------------
+
+If you are playing a Sierra AGI game, you will be using the on-screen
+keyboard quite a lot (press X to show it). To reduce the amount you have
+to type, the game can automatically complete long words for you. To use
+this feature, simply copy the PRED.DIC file from the ScummVM DS archive
+into your game folder on your card. Now, when you use the keyboard,
+possible words will be shown underneith it. To type one of those words,
+simply double click on it with your stylus.
+
+
+ Converting your CD audio
+ ------------------------------------------------------------------------
+
+ScummVM supports playing CD audio for specific games which came with
+music stored as standard music CD tracks. To use this music in ScummVM
+DS, they need to be ripped from the CD and stored in a specific format.
+This can only be done for the CD versions of certain games, such as
+Monkey Island 1, Loom, and Gobliiins. All the floppy games and CD games
+that didn't have CD audio tracks for music don't require any conversion,
+and will work unmodified on ScummVM DS. MP3 audio files for CD music are
+not supported.
+
+Cdex can do the conversion very well and I recommend using it to convert
+your audio files, although any CD ripping software can be used, so feel
+free to use your favourite program. The format you need to use is
+IMA-ADPCM 4-bit Mono. You may use any sample rate. All other formats
+will be rejected, including uncompressed WAV files.
+
+Now I will to describe how to rip your CD tracks with Cdex, which can be
+found here: Cdex Homepage <http://sourceforge.net/projects/cdexos/>.
+Other software can be used to create IMA ADPCM files under Linux or
+MacOS.
+
+To set this up in Cdex, select Settings from the Options menu. On the
+Encoder tab, select 'WAV Output Encoder'. Under 'Encoder Options',
+choose the following:
+
+ Format: WAV
+ Compression: IMA ADPCM
+ Samplerate: 22050 Hz
+ Channels: Mono
+ On the fly encoding: On
+
+Next, go to the 'Filenames' tab and select the folder you want to save
+your Wav files to. Under 'Filename format', enter 'track%3'. This should
+name your WAV files in the correct way. Click OK.
+
+Now select all the tracks on your CD, and click 'Extract CD tracks to a
+compressed audio file'. Cdex should rip all the audio off your CD.
+
+Now all you have to do is copy the newly created WAV files into the same
+directory that your other game data is stored on your CompactFlash card.
+Next time your run ScummVM DS, it should play with music!
+
+*Important Note:* Do not select 'Extract CD tracks to a WAV file'. This
+creates uncompressed WAVs only. You want 'Extract CD tracks to a
+compressed audio file'.
+
+
+ Converting Speech files to MP3 format
+ ------------------------------------------------------------------------
+
+ScummVM supports playing back speech for talkie games in MP3 format.
+Unfortunately, the DS CPU is not quite up to the task, and MP3 audio
+will sometimes cause slowdown in your game. However, if your flash card
+isn't big enough to fit the audio files on, you will have no choice!
+
+To convert your audio you will need a copy of the ScummVM Tools package
+<http://sourceforge.net/project/showfiles.php?group_id=37116&package_id=67433>.
+You will also need a copy of the LAME MP3 encoder
+<http://www.free-codecs.com/Lame_Encoder_download.htm>.
+
+Once this is all installed and set up, the process to encode your audio
+varies from game to game, but the Lucasarts games can all be compressed
+using the following command line:
+
+compress_scumm_sou --mp3 monster.sou
+
+This produces a monster.so3 file which you can copy to your flash card
+and replaces the original monster.sou. Ogg format (monster.sog) and flac
+format files are not currently supported by ScummVM DS, and it is
+unlikely they will ever be supported. There is no way to convert .sog or
+.so3 files back to .sou files. Just dig out your original CD and copy
+the file from that.
+
+
+ Frequently Asked Questions
+ ------------------------------------------------------------------------
+
+I get a lot of email about ScummVM DS. Nearly all of them are exactly
+the same. Here I'm going to try and answer the questions that everybody
+asks me in the hope that I will spend less time answering questions that
+are clearly in the documentation and more time helping people who have a
+real problem or have discovered a real bug.
+
+*Q:* I can't see the bottom line of inventory items in Day of the
+Tentacle, Monkey Island 2, or a few other games! What do I do?
+*A:* Hold down the left shoulder button and use D-pad (or the touch
+screen) to scroll the screen around.
+
+*Q:* I dont see a menu when I press Start in Flight of the Amazon Queen
+or Simon the Sorcerer. Is ScummVM broken?
+*A:* No. To save in Simon the Sorcerer, click 'use', then click on the
+postcard in your inventory. In Flight of the Amazon Queen, click 'use',
+then click on the journal in your inventory.
+
+*Q:* Why does ScummVM crash when I play Monkey Island 1?
+*A:* This happens when MP3 audio tracks are present from the PC version
+of ScummVM. Delete the MP3 tracks and reencode them to ADPCM WAV files
+as described in the CD audio section.
+
+*Q:* When will you support my Mini/Micro SD card reader? I want it!
+Pretty please?
+*A:* ScummVM uses DLDI drivers. If your card reader manufacturer doesn't
+provide a driver, there is nothing I can do about it. The people to ask
+are the card reader manufacturers themselves.
+
+*Q:* Can't you use the extra RAM in the M3/Supercard or the official
+Opera Expansion Pack to support more games like The Dig and Full
+Throttle? DS Linux has done it, so why can't you?
+*A:* Not at the moment. The extra RAM has certain differences to the
+build in RAM which makes it difficult to use for general programs. As
+ScummVM DS is an official port, the changes to the ScummVM code base
+must be minimal to avoid making the code difficult to read for other
+users. I do have plans to work on this some time in the future, but
+don't nag me about when it'll be done. If and when there's progress with
+this, I will post on the ScummVM forums about it.
+
+
+*Q:* ScummVM DS turns off my DS when I hit 'Quit' in the game or quit
+from the frontend. Why doesn't it return to the menu?
+*A:* Due to bugs in the ScummVM codebase, many of the ScummVM games
+cannot quit cleanly leaving the machine in the same state as when it
+started. You will notice that no other versions of ScummVM can quit back
+to the menu either. This will be fixed at some time in the future.
+
+
+
+
+ Contributors
+ ------------------------------------------------------------------------
+
+ScummVM DS uses chishm's GBA Movie Player FAT driver.
+The CPU scaler is by Tramboi and Robin Watts
+The ARM code was optimised by Robin Watts
+Thanks to highpass for the ScummVM DS icons.
+Thanks to zhevon for the Sam & Max cursor code.
+Thanks to theNinjaBunny for the M3 Adaptor guide on this site.
+Thanks also to everyone on the GBADev Forums.
+
+This program was brought to you by caffiene, sugar, and late nights.
+
+
+ Donations and Getting Help
+ ------------------------------------------------------------------------
+
+If you have problems getting ScummVM to work on your hardware, please
+read the FAQ first. /Please/ don't ask me questions which are
+answered in the FAQ, I get many emails about this program each day, and
+I can't help the people who really need help if I'm answering the same
+question all the time which is already answered on this page. Other than
+that, feel free to post on the ScummVM DS forum <http://forums.scummvm.org>
+for help. Please do your research first though. There is no way of
+running this on an out-of-the box DS without extra hardware. Most of
+these things are fairly inexpensive though.
+
+If you want to contact me, please email me on scummvm at millstone dot
+demon dot co dot uk.
+
+If you want to help with the development of ScummVM DS, great! Download
+the source code and get building. There are plenty of things left to do.
+
+You can also help by making a donation if you've particularly enjoyed
+ScummVM DS. This uses Paypal, and is completely secure. There's no
+pressure though, ScummVM DS is completely free. This is just for those
+who would like to make a contribution to further development.
+
+
+
+ Building from Sources
+ ------------------------------------------------------------------------
+
+ScummVM is an open source project. This means that anyone is free to
+take the source code to the project and make their own additions and fixes,
+contributing them back to the authors for consideration for the next version.
+
+To build ScummVM DS from source, it's probably better to checkout the
+latest version of the code from the ScummVM SVN repository. The ScummVM
+Sourceforge.net homepage <http://sourceforge.net/projects/scummvm> has
+all the information about how to do this.
+
+By default, ScummVM DS expects to find libmad, an MP3 compressor library
+targeted for the ARM platform. If you don't have this, you must disable
+libmad support by opening 'backends/platform/ds/arm9/makefile' and
+commenting out the line which says USE_MAD = 1.
+
+Then, enter the 'backends/platform/ds' folder and type:
+make SCUMM_BUILD=a
+
+The executable nds file will build inside 'backends/platform/ds/arm9/SCUMMVM-A'.
+
+For other builds, substitute the letters b - g in the above line.
+
+
+
diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile
index cf82090df2..e74bcf28da 100644
--- a/backends/platform/ds/arm9/makefile
+++ b/backends/platform/ds/arm9/makefile
@@ -8,25 +8,29 @@ libndsdir = $(DEVKITPRO)/libnds
# Select the build by setting SCUMM_BUILD to a,b,c,d,e,f or g.
# Anything else gets build a.
-ifeq ($(SCUMM_BUILD),g)
+ifeq ($(SCUMM_BUILD),h)
+ DS_BUILD_H = 1
+ else
+ ifeq ($(SCUMM_BUILD),g)
DS_BUILD_G = 1
-else
- ifeq ($(SCUMM_BUILD),f)
+ else
+ ifeq ($(SCUMM_BUILD),f)
DS_BUILD_F = 1
- else
- ifeq ($(SCUMM_BUILD),e)
- DS_BUILD_E = 1
else
- ifeq ($(SCUMM_BUILD),d)
- DS_BUILD_D = 1
+ ifeq ($(SCUMM_BUILD),e)
+ DS_BUILD_E = 1
else
- ifeq ($(SCUMM_BUILD),c)
- DS_BUILD_C = 1
+ ifeq ($(SCUMM_BUILD),d)
+ DS_BUILD_D = 1
else
- ifeq ($(SCUMM_BUILD),b)
- DS_BUILD_B = 1
+ ifeq ($(SCUMM_BUILD),c)
+ DS_BUILD_C = 1
else
+ ifeq ($(SCUMM_BUILD),b)
+ DS_BUILD_B = 1
+ else
DS_BUILD_A = 1
+ endif
endif
endif
endif
@@ -80,8 +84,8 @@ vpath %.s $(srcdir)
# I actually had to use
# ./configure --host=arm-elf --enable-speed --enable-sso -enable-fpm=arm CFLAGS='-specs=ds_arm9.specs -mthumb-interwork' LDFLAGS='C:/Progra~1/devkitpro/libnds/lib/libnds9.a' --disable-shared --disable-debugging
-USE_ARM_SOUND_ASM = 1
ARM = 1
+USE_ARM_SOUND_ASM = 1
USE_ARM_COSTUME_ASM = 1
ifdef DS_BUILD_A
@@ -140,6 +144,13 @@ ifdef DS_BUILD_G
BUILD=scummvm-G
endif
+ifdef DS_BUILD_H
+ DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_H
+ LOGO = logog.bmp
+ ENABLE_PARALLACTION = STATIC_PLUGIN
+ BUILD=scummvm-H
+endif
+
ARM7BIN := -7 $(CURDIR)/../../arm7/arm7.bin
ICON := -b ../../../logo.bmp "ScummVM;By Neil Millstone;"
@@ -152,6 +163,7 @@ CFLAGS = -Wno-multichar -Wall\
-mcpu=arm9tdmi -mtune=arm9tdmi -fomit-frame-pointer\
-mthumb-interwork -DUSE_ARM_COSTUME_ASM=1
+
# -ffast-math
ifdef USE_DEBUGGER
@@ -165,7 +177,7 @@ ifdef USE_PROFILER
endif
CXXFLAGS= $(CFLAGS) -Wno-non-virtual-dtor -Wno-unknown-pragmas -Wno-reorder \
- -fno-exceptions -fno-rtti -mthumb-interwork
+ -fno-exceptions -fno-rtti -mthumb-interwork -ffunction-sections -fdata-sections
# -mthumb
@@ -185,7 +197,7 @@ ifdef USE_MAD
endif
-LDFLAGS = -specs=ds_arm9.specs -mthumb-interwork -Wl,--wrap,time -mno-fpu -Wl,-Map,map.txt
+LDFLAGS = -specs=ds_arm9.specs -mthumb-interwork -Wl,--wrap,time -mno-fpu -Wl,-Map,map.txt -Wl,--gc-sections
INCLUDES= -I$(portdir)/$(BUILD) -I$(srcdir) -I$(srcdir)/engines \
-I$(portdir)/data -I$(portdir)/../commoninclude \
@@ -237,7 +249,8 @@ endif
DATA_OBJS := $(portdir)/data/icons.o $(portdir)/data/keyboard.o $(portdir)/data/keyboard_pal.o $(portdir)/data/default_font.o $(portdir)/data/8x8font_tga.o
-COMPRESSOR_OBJS := $(portdir)/source/compressor/lz.o
+COMPRESSOR_OBJS :=
+#$(portdir)/source/compressor/lz.o
FAT_OBJS := $(portdir)/source/fat/disc_io.o $(portdir)/source/fat/gba_nds_fat.o\
$(portdir)/source/fat/io_fcsr.o $(portdir)/source/fat/io_m3cf.o\
@@ -257,14 +270,15 @@ FAT_OBJS := $(portdir)/source/fat/disc_io.o $(portdir)/source/fat/gba_nds_fat.o
# $(portdir)/source/fat/io_sd_common.o $(portdir)/source/fat/io_scsd_s.o \
# $(portdir)/source/fat/io_sc_common.o $(portdir)/source/fat/io_sd_common.o
-LIBCARTRESET_OBJS := $(portdir)/source/libcartreset/cartreset.o
+LIBCARTRESET_OBJS :=
+#$(portdir)/source/libcartreset/cartreset.o
# Files in this list will be optimisied for speed, otherwise they will be optimised for space
OPTLIST := actor.cpp ds_main.cpp osystem_ds.cpp blitters.cpp fmopl.cpp rate.cpp mixer.cpp isomap.cpp image.cpp gfx.cpp sprite.cpp actor_path.cpp actor_walk.cpp
#OPTLIST :=
# Compiler options for files which should be optimised for speed
-OPT_SPEED := -O2
+OPT_SPEED := -O3
# Compiler options for files which should be optimised for space
OPT_SIZE := -Os
@@ -286,7 +300,7 @@ ndsall:
include $(srcdir)/Makefile.common
semiclean:
- $(RM) $(portdir)/source/dsoptions.o $(portdir)/source/dsmain.o $(FAT_OBJS) $(DATA_OBJS) $(portdir)/source/wordcompletion.o
+ $(RM) $(portdir)/source/dsoptions.o $(portdir)/source/dsmain.o $(FAT_OBJS) $(DATA_OBJS) $(portdir)/source/wordcompletion.o $(portdir)/source/dsoptions.o
clean:
$(RM) $(OBJS) $(EXECUTABLE)
diff --git a/backends/platform/ds/arm9/source/cdaudio.h b/backends/platform/ds/arm9/source/cdaudio.h
index d237569bb7..d1897d3e5d 100644
--- a/backends/platform/ds/arm9/source/cdaudio.h
+++ b/backends/platform/ds/arm9/source/cdaudio.h
@@ -20,7 +20,7 @@
*
*/
- #ifndef _CDAUDIO_H_
+#ifndef _CDAUDIO_H_
#define _CDAUDIO_H_
namespace DS {
diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp
index ce22ac8e71..872a196e9b 100644
--- a/backends/platform/ds/arm9/source/dsmain.cpp
+++ b/backends/platform/ds/arm9/source/dsmain.cpp
@@ -66,6 +66,7 @@
#include <nds.h>
#include <nds/registers_alt.h>
+#include <nds/arm9/exceptions.h>
//#include <ARM9/console.h> //basic print funcionality
@@ -76,7 +77,6 @@
#include "icons_raw.h"
#include "fat/gba_nds_fat.h"
#include "fat/disc_io.h"
-//#include "common/config-manager.h"
#include "keyboard_raw.h"
#include "keyboard_pal_raw.h"
#define V16(a, b) ((a << 12) | b)
@@ -95,6 +95,26 @@
#endif
#include "backends/fs/ds/ds-fs.h"
+extern "C" u32 getExceptionAddress( u32 opcodeAddress, u32 thumbState);
+extern const char __itcm_start[];
+static const char *registerNames[] =
+ { "r0","r1","r2","r3","r4","r5","r6","r7",
+ "r8 ","r9 ","r10","r11","r12","sp ","lr ","pc " };
+
+/*
+extern "C" void* __real_malloc(size_t size);
+
+extern "C" void* __wrap_malloc(size_t size) {
+ void* res = __real_malloc(size);
+ if (res) {
+ return res;
+ } else {
+ consolePrintf("Failed alloc %d\n", size);
+ return NULL;
+ }
+}
+*/
+
namespace DS {
// From console.c in NDSLib
@@ -167,7 +187,7 @@ bool displayModeIs8Bit = false;
u8 gameID;
bool snapToBorder = false;
-bool consoleEnable = true;
+bool consoleEnable = false;
bool gameScreenSwap = false;
bool isCpuScalerEnabled();
//#define HEAVY_LOGGING
@@ -196,6 +216,13 @@ int mouseHotspotX, mouseHotspotY;
bool cursorEnable = false;
bool mouseCursorVisible = true;
bool rightButtonDown = false;
+bool touchPadStyle = false;
+int touchPadSensitivity = 8;
+bool tapScreenClicks = true;
+
+int tapCount = 0;
+int tapTimeout = 0;
+int tapComplete = 0;
// Dragging
int dragStartX, dragStartY;
@@ -212,7 +239,14 @@ int gameHeight = 200;
// Scale
bool twoHundredPercentFixedScale = false;
bool cpuScalerEnable = false;
-#define NUM_SUPPORTED_GAMES 20
+
+ // 100 256
+ // 150 192
+ // 200 128
+
+ // (256 << 8) / scale
+
+
#ifdef USE_PROFILER
int hBlankCount = 0;
@@ -220,6 +254,7 @@ int hBlankCount = 0;
u8* scalerBackBuffer = NULL;
+#define NUM_SUPPORTED_GAMES 21
gameListType gameList[NUM_SUPPORTED_GAMES] = {
// Unknown game - use normal SCUMM controls
@@ -247,6 +282,7 @@ gameListType gameList[NUM_SUPPORTED_GAMES] = {
{"elvira2", CONT_SIMON},
{"elvira1", CONT_SIMON},
{"waxworks", CONT_SIMON},
+ {"parallaction", CONT_NIPPON},
};
gameListType* currentGame = NULL;
@@ -259,6 +295,7 @@ bool penHeld;
bool penReleased;
bool penDownLastFrame;
s32 penX, penY;
+s32 penDownX, penDownY;
int keysDownSaved;
int keysReleasedSaved;
int keysChangedSaved;
@@ -298,9 +335,41 @@ void setCpuScalerEnable(bool enable) {
cpuScalerEnable = enable;
}
+void setTrackPadStyleEnable(bool enable) {
+ touchPadStyle = enable;
+}
+
+void setTapScreenClicksEnable(bool enable) {
+ tapScreenClicks = enable;
+}
+
+void setGameScreenSwap(bool enable) {
+ gameScreenSwap = enable;
+}
+
+void setSensitivity(int sensitivity) {
+ touchPadSensitivity = sensitivity;
+}
+
+void setTopScreenZoom(int percentage) {
+ // 100 256
+ // 150 192
+ // 200 128
+
+ // (256 << 8) / scale
+
+ s32 scale = (percentage << 8) / 100;
+ subScreenScale = (256 * 256) / scale;
+
+// consolePrintf("Scale is %d %%\n", percentage);
+}
// return (ConfMan.hasKey("cpu_scaler", "ds") && ConfMan.getBool("cpu_scaler", "ds"));
+controlType getControlType() {
+ return currentGame->control;
+}
+
//plays an 8 bit mono sample at 11025Hz
void playSound(const void* data, u32 length, bool loop, bool adpcm, int rate)
@@ -428,14 +497,14 @@ void initGame() {
consolePrintf("initing game...");
#endif
- static bool firstTime = true;
+// static bool firstTime = true;
setOptions();
//strcpy(gameName, ConfMan.getActiveDomain().c_str());
strcpy(gameName, ConfMan.get("gameid").c_str());
- consolePrintf("\n\n\n\nCurrent game: '%s' %d\n", gameName, gameName[0]);
+// consolePrintf("\n\n\n\nCurrent game: '%s' %d\n", gameName, gameName[0]);
currentGame = &gameList[0]; // Default game
@@ -446,16 +515,12 @@ void initGame() {
}
}
- if (firstTime) {
+/* if (firstTime) {
firstTime = false;
- if (ConfMan.hasKey("22khzaudio", "ds") && ConfMan.getBool("22khzaudio", "ds")) {
- startSound(22050, 8192);
- } else {
- startSound(11025, 4096);
- }
}
+*/
#ifdef HEAVY_LOGGING
consolePrintf("done\n");
#endif
@@ -630,7 +695,7 @@ void checkSleepMode() {
void setShowCursor(bool enable)
{
- if (currentGame->control == CONT_SCUMM_SAMNMAX)
+ if ((currentGame) && (currentGame->control == CONT_SCUMM_SAMNMAX))
{
if (cursorEnable) {
sprites[1].attribute[0] = ATTR0_BMP | 150;
@@ -653,23 +718,28 @@ void setCursorIcon(const u8* icon, uint w, uint h, byte keycolor, int hotspotX,
mouseHotspotX = hotspotX;
mouseHotspotY = hotspotY;
+ //consolePrintf("Set cursor icon %d, %d\n", w, h);
+
{
int off = 128*64;
memset(SPRITE_GFX + off, 0, 32 * 32 * 2);
memset(SPRITE_GFX_SUB + off, 0, 32 * 32 * 2);
+
for (uint y=0; y<h; y++) {
for (uint x=0; x<w; x++) {
int color = icon[y*w+x];
+
+ //consolePrintf("%d:%d ", color, OSystem_DS::instance()->getDSPaletteEntry(color));
if (color == keycolor) {
SPRITE_GFX[off+(y)*32+x] = 0x0000; // black background
SPRITE_GFX_SUB[off+(y)*32+x] = 0x0000; // black background
} else {
- SPRITE_GFX[off+(y)*32+x] = BG_PALETTE[color] | 0x8000;
- SPRITE_GFX_SUB[off+(y)*32+x] = BG_PALETTE[color] | 0x8000;
+ SPRITE_GFX[off+(y)*32+x] = OSystem_DS::instance()->getDSCursorPaletteEntry(color) | 0x8000;
+ SPRITE_GFX_SUB[off+(y)*32+x] = OSystem_DS::instance()->getDSCursorPaletteEntry(color) | 0x8000;
}
}
}
@@ -732,6 +802,7 @@ void setCursorIcon(const u8* icon, uint w, uint h, byte keycolor, int hotspotX,
sprites[1].attribute[1] = ATTR1_SIZE_64 | pos;
sprites[1].attribute[2] = ATTR2_ALPHA(1) | 176;
}
+
}
@@ -744,6 +815,7 @@ void displayMode16Bit() {
u16 buffer[32 * 32 * 2];
+ releaseAllKeys();
if (displayModeIs8Bit) {
// static int test = 0;
@@ -1108,7 +1180,7 @@ void setKeyboardEnable(bool en) {
} else {
-
+ DS::releaseAllKeys();
// Restore the palette that the keyboard has used
for (int r = 0; r < 256; r++) {
BG_PALETTE_SUB[r] = BG_PALETTE[r];
@@ -1156,6 +1228,194 @@ bool getIsDisplayMode8Bit() {
return displayModeIs8Bit;
}
+void doScreenTapMode(OSystem_DS* system)
+{
+ Common::Event event;
+ static bool left = false, right = false;
+
+ if (left) {
+ event.type = Common::EVENT_LBUTTONUP;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ left = false;
+ }
+
+ if (right) {
+ event.type = Common::EVENT_RBUTTONUP;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ right = false;
+ }
+
+
+ if (tapComplete == 1) {
+ event.type = Common::EVENT_LBUTTONDOWN;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ tapComplete = 0;
+ left = true;
+ } else if (tapComplete == 2) {
+ event.type = Common::EVENT_RBUTTONDOWN;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ tapComplete = 0;
+ right = true;
+ }
+
+
+ if (getKeysDown() & KEY_LEFT) {
+ event.type = Common::EVENT_LBUTTONDOWN;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ }
+
+ if (getKeysReleased() & KEY_LEFT) {
+ event.type = Common::EVENT_LBUTTONUP;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ }
+
+
+ if (getKeysDown() & KEY_RIGHT) {
+ event.type = Common::EVENT_RBUTTONDOWN;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ }
+
+ if (getKeysReleased() & KEY_RIGHT) {
+ event.type = Common::EVENT_RBUTTONUP;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ }
+
+ event.type = Common::EVENT_MOUSEMOVE;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+}
+
+void doButtonSelectMode(OSystem_DS* system)
+{
+ Common::Event event;
+
+
+ if ((!(getKeysHeld() & KEY_L)) && (!(getKeysHeld() & KEY_R))) {
+ event.type = Common::EVENT_MOUSEMOVE;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ //consolePrintf("x=%d y=%d \n", getPenX(), getPenY());
+ }
+
+ static bool leftButtonDown = false;
+ static bool rightButtonDown = false;
+
+ if (getPenReleased() && (leftButtonDown || rightButtonDown)) {
+ if (leftButtonDown) {
+ event.type = Common::EVENT_LBUTTONUP;
+ } else {
+ event.type = Common::EVENT_RBUTTONUP;
+ }
+
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ }
+
+
+ if ((mouseMode != MOUSE_HOVER) || (!displayModeIs8Bit)) {
+ if (getPenDown() && (!(getKeysHeld() & KEY_L)) && (!(getKeysHeld() & KEY_R))) {
+ if ((mouseMode == MOUSE_LEFT) || (!displayModeIs8Bit)) {
+ event.type = Common::EVENT_LBUTTONDOWN;
+ leftButtonDown = true;
+ } else {
+ event.type = Common::EVENT_RBUTTONDOWN;
+ rightButtonDown = true;
+ }
+
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ }
+
+ } else {
+ // In hover mode, D-pad left and right click the mouse when the pen is on the screen
+
+ if (getPenHeld()) {
+ if (getKeysDown() & KEY_LEFT) {
+ event.type = Common::EVENT_LBUTTONDOWN;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ }
+ if (getKeysReleased() & KEY_LEFT) {
+ event.type = Common::EVENT_LBUTTONUP;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ }
+
+
+ if (getKeysDown() & KEY_RIGHT) {
+ event.type = Common::EVENT_RBUTTONDOWN;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ }
+ if (getKeysReleased() & KEY_RIGHT) {
+ event.type = Common::EVENT_RBUTTONUP;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ system->addEvent(event);
+ }
+ }
+ }
+
+ if (!((getKeysHeld() & KEY_L) || (getKeysHeld() & KEY_R)) && (!getIndyFightState()) && (!getKeyboardEnable())) {
+
+ if (!getPenHeld() || (mouseMode != MOUSE_HOVER)) {
+ if (getKeysDown() & KEY_LEFT) {
+ mouseMode = MOUSE_LEFT;
+ }
+
+ if (rightButtonDown)
+ {
+ Common::Event event;
+ event.mouse = Common::Point(getPenX(), getPenY());
+ event.type = Common::EVENT_RBUTTONUP;
+ system->addEvent(event);
+ rightButtonDown = false;
+ }
+
+
+ if (getKeysDown() & KEY_RIGHT) {
+ if ((currentGame->control != CONT_SCUMM_SAMNMAX) && (currentGame->control != CONT_FUTURE_WARS) && (currentGame->control != CONT_GOBLINS)) {
+ mouseMode = MOUSE_RIGHT;
+ } else {
+ // If we're playing sam and max, click and release the right mouse
+ // button to change verb
+ Common::Event event;
+
+ if (currentGame->control == CONT_FUTURE_WARS) {
+ event.mouse = Common::Point(320 - 128, 200 - 128);
+ event.type = Common::EVENT_MOUSEMOVE;
+ system->addEvent(event);
+ } else {
+ event.mouse = Common::Point(getPenX(), getPenY());
+ }
+
+ rightButtonDown = true;
+
+
+ event.type = Common::EVENT_RBUTTONDOWN;
+ system->addEvent(event);
+
+ //event.type = Common::EVENT_RBUTTONUP;
+ //system->addEvent(event);
+ }
+ }
+
+
+
+ if (getKeysDown() & KEY_UP) {
+ mouseMode = MOUSE_HOVER;
+ }
+ }
+ }
+}
+
void addEventsToQueue() {
#ifdef HEAVY_LOGGING
consolePrintf("addEventsToQueue\n");
@@ -1285,54 +1545,6 @@ void addEventsToQueue() {
}
- if (!getPenHeld() || (mouseMode != MOUSE_HOVER)) {
- if (getKeysDown() & KEY_LEFT) {
- mouseMode = MOUSE_LEFT;
- }
-
- if (rightButtonDown)
- {
- Common::Event event;
- event.mouse = Common::Point(getPenX(), getPenY());
- event.type = Common::EVENT_RBUTTONUP;
- system->addEvent(event);
- rightButtonDown = false;
- }
-
-
- if (getKeysDown() & KEY_RIGHT) {
- if ((currentGame->control != CONT_SCUMM_SAMNMAX) && (currentGame->control != CONT_FUTURE_WARS) && (currentGame->control != CONT_GOBLINS)) {
- mouseMode = MOUSE_RIGHT;
- } else {
- // If we're playing sam and max, click and release the right mouse
- // button to change verb
- Common::Event event;
-
- if (currentGame->control == CONT_FUTURE_WARS) {
- event.mouse = Common::Point(320 - 128, 200 - 128);
- event.type = Common::EVENT_MOUSEMOVE;
- system->addEvent(event);
- } else {
- event.mouse = Common::Point(getPenX(), getPenY());
- }
-
- rightButtonDown = true;
-
-
- event.type = Common::EVENT_RBUTTONDOWN;
- system->addEvent(event);
-
- //event.type = Common::EVENT_RBUTTONUP;
- //system->addEvent(event);
- }
- }
-
-
-
- if (getKeysDown() & KEY_UP) {
- mouseMode = MOUSE_HOVER;
- }
- }
@@ -1358,52 +1570,13 @@ void addEventsToQueue() {
if (!keyboardEnable) {
- if ((!(getKeysHeld() & KEY_L)) && (!(getKeysHeld() & KEY_R))) {
- event.type = Common::EVENT_MOUSEMOVE;
- event.mouse = Common::Point(getPenX(), getPenY());
- system->addEvent(event);
- //consolePrintf("x=%d y=%d \n", getPenX(), getPenY());
+ if ((tapScreenClicks) && (getIsDisplayMode8Bit()))
+ {
+ doScreenTapMode(system);
}
-
- if ((mouseMode != MOUSE_HOVER) || (!displayModeIs8Bit)) {
- if (getPenDown() && (!(getKeysHeld() & KEY_L)) && (!(getKeysHeld() & KEY_R))) {
- event.type = ((mouseMode == MOUSE_LEFT) || (!displayModeIs8Bit))? Common::EVENT_LBUTTONDOWN: Common::EVENT_RBUTTONDOWN;
- event.mouse = Common::Point(getPenX(), getPenY());
- system->addEvent(event);
- }
-
- if (getPenReleased()) {
- event.type = mouseMode == MOUSE_LEFT? Common::EVENT_LBUTTONUP: Common::EVENT_RBUTTONUP;
- event.mouse = Common::Point(getPenX(), getPenY());
- system->addEvent(event);
- }
- } else {
- // In hover mode, D-pad left and right click the mouse when the pen is on the screen
-
- if (getPenHeld()) {
- if (getKeysDown() & KEY_LEFT) {
- event.type = Common::EVENT_LBUTTONDOWN;
- event.mouse = Common::Point(getPenX(), getPenY());
- system->addEvent(event);
- }
- if (getKeysReleased() & KEY_LEFT) {
- event.type = Common::EVENT_LBUTTONUP;
- event.mouse = Common::Point(getPenX(), getPenY());
- system->addEvent(event);
- }
-
-
- if (getKeysDown() & KEY_RIGHT) {
- event.type = Common::EVENT_RBUTTONDOWN;
- event.mouse = Common::Point(getPenX(), getPenY());
- system->addEvent(event);
- }
- if (getKeysReleased() & KEY_RIGHT) {
- event.type = Common::EVENT_RBUTTONUP;
- event.mouse = Common::Point(getPenX(), getPenY());
- system->addEvent(event);
- }
- }
+ else
+ {
+ doButtonSelectMode(system);
}
if (((!(getKeysHeld() & KEY_L)) && (!(getKeysHeld() & KEY_R)) || (indyFightState)) && (displayModeIs8Bit)) {
@@ -1536,8 +1709,8 @@ void triggerIcon(int imageNum) {
void setIcon(int num, int x, int y, int imageNum, int flags, bool enable) {
- sprites[num].attribute[0] = ATTR0_BMP | (enable? y: 192) | (!enable? ATTR0_DISABLED: 0);
- sprites[num].attribute[1] = ATTR1_SIZE_32 | x | flags;
+ sprites[num].attribute[0] = ATTR0_BMP | (enable? (y & 0xFF): 192) | (!enable? ATTR0_DISABLED: 0);
+ sprites[num].attribute[1] = ATTR1_SIZE_32 | (x & 0x1FF) | flags;
sprites[num].attribute[2] = ATTR2_ALPHA(1)| (imageNum * 16);
}
@@ -1551,28 +1724,30 @@ void updateStatus() {
int offs;
if (displayModeIs8Bit) {
- switch (mouseMode) {
- case MOUSE_LEFT: {
- offs = 1;
- break;
- }
- case MOUSE_RIGHT: {
- offs = 2;
- break;
- }
- case MOUSE_HOVER: {
- offs = 0;
- break;
- }
- default: {
- // Nothing!
- offs = 0;
- break;
+ if (!tapScreenClicks) {
+ switch (mouseMode) {
+ case MOUSE_LEFT: {
+ offs = 1;
+ break;
+ }
+ case MOUSE_RIGHT: {
+ offs = 2;
+ break;
+ }
+ case MOUSE_HOVER: {
+ offs = 0;
+ break;
+ }
+ default: {
+ // Nothing!
+ offs = 0;
+ break;
+ }
}
+
+ setIcon(0, 208, 150, offs, 0, true);
}
- setIcon(0, 208, 150, offs, 0, true);
-
if (indyFightState) {
setIcon(1, (190 - 32), 150, 3, (indyFightRight? 0: ATTR1_FLIP_X), true);
// consolePrintf("%d\n", indyFightRight);
@@ -1630,7 +1805,7 @@ void setMainScreenScroll(int x, int y) {
BG3_CX = x + (((frameCount & 1) == 0)? 64: 0);
BG3_CY = y;
- if (!gameScreenSwap) {
+ if ((!gameScreenSwap) || (touchPadStyle)) {
touchX = x >> 8;
touchY = y >> 8;
}
@@ -1659,7 +1834,7 @@ void setMainScreenScale(int x, int y) {
BG3_YDY = y;
}
- if (!gameScreenSwap) {
+ if ((!gameScreenSwap) || (touchPadStyle)) {
touchScX = x;
touchScY = y;
}
@@ -1675,7 +1850,7 @@ void setZoomedScreenScroll(int x, int y, bool shake) {
touchY = y >> 8;
} else */{
- if (gameScreenSwap) {
+ if ((gameScreenSwap) && (!touchPadStyle)) {
touchX = x >> 8;
touchY = y >> 8;
}
@@ -1695,7 +1870,7 @@ void setZoomedScreenScale(int x, int y) {
} else */{
- if (gameScreenSwap) {
+ if ((gameScreenSwap) && (!touchPadStyle)) {
touchScX = x;
touchScY = y;
}
@@ -1756,18 +1931,22 @@ void VBlankHandler(void) {
frameCount++;
- if ((cursorEnable) && (mouseCursorVisible))
- {
+ if ((cursorEnable) && (mouseCursorVisible)) {
if (!keyboardEnable) {
storedMouseX = penX;
storedMouseY = penY;
}
- setIconMain(3, storedMouseX - mouseHotspotX, storedMouseY - mouseHotspotY, 8, 0, true);
- }
- else
- {
+ if (gameScreenSwap) {
+ setIcon(3, storedMouseX - mouseHotspotX, storedMouseY - mouseHotspotY, 8, 0, true);
+ setIconMain(3, 0, 0, 0, 0, false);
+ } else {
+ setIconMain(3, storedMouseX - mouseHotspotX, storedMouseY - mouseHotspotY, 8, 0, true);
+ setIcon(3, 0, 0, 0, 0, false);
+ }
+ } else {
setIconMain(3, 0, 0, 0, 0, false);
+ setIcon(3, 0, 0, 0, 0, false);
}
@@ -1825,7 +2004,7 @@ void VBlankHandler(void) {
SUB_BG3_YDX = 0;
SUB_BG3_YDY = (int) (subScreenHeight / 192.0f * 256);*/
- static int ratio = ( 320 << 8) / SCUMM_GAME_WIDTH;
+ static int ratio = (320 << 8) / SCUMM_GAME_WIDTH;
bool zooming = false;
@@ -1850,8 +2029,12 @@ void VBlankHandler(void) {
subScreenWidth = 256 >> 1;
subScreenHeight = 192 >> 1;
} else {
- subScreenWidth = (((SCUMM_GAME_HEIGHT * 256) / 192) * subScreenScale) >> 8;
- subScreenHeight = SCUMM_GAME_HEIGHT * subScreenScale >> 8;
+// subScreenWidth = (((SCUMM_GAME_HEIGHT * 256) / 192) * subScreenScale) >> 8;
+// subScreenHeight = SCUMM_GAME_HEIGHT * subScreenScale >> 8;
+
+
+ subScreenWidth = (256 * subScreenScale) >> 8;
+ subScreenHeight = (192 * subScreenScale) >> 8;
if ( ((subScreenWidth) > 256 - 8) && ((subScreenWidth) < 256 + 8) ) {
subScreenWidth = 256;
@@ -2214,43 +2397,141 @@ void penUpdate() {
// if (getKeysHeld() & KEY_L) consolePrintf("%d, %d penX=%d, penY=%d tz=%d\n", IPC->touchXpx, IPC->touchYpx, penX, penY, IPC->touchZ1);
- if ((penDownFrames > 1)) { // Is this right? Dunno, but it works for me.
+ bool penDownThisFrame = (IPC->touchZ1 > 0) && (IPC->touchXpx > 0) && (IPC->touchYpx > 0);
+ bool firstFrame = penDownFrames == 2;
+ static bool moved = false;
- if ((penHeld)) {
- penHeld = true;
- penDown = false;
+ if ((tapScreenClicks) && (!getKeyboardEnable()) && (getIsDisplayMode8Bit())) {
- if ((IPC->touchZ1 > 0) && (IPC->touchXpx > 0) && (IPC->touchYpx > 0)) {
- penX = IPC->touchXpx + touchXOffset;
- penY = IPC->touchYpx + touchYOffset;
+ if ((tapTimeout >= 0)) {
+ tapTimeout++;
+
+ if (((tapTimeout > 15) || (tapCount == 2)) && (tapCount > 0)) {
+ tapComplete = tapCount;
+ tapCount = 0;
+// consolePrintf("Taps: %d\n", tapComplete);
}
+ }
- } else {
- penDown = true;
- penHeld = true;
- penDownSaved = true;
+
- //if ( (ABS(penX - IPC->touchXpx) < 10) && (ABS(penY - IPC->touchYpx) < 10) ) {
- if ((IPC->touchZ1 > 0) && (IPC->touchXpx > 0) && (IPC->touchYpx > 0)) {
- penX = IPC->touchXpx;
- penY = IPC->touchYpx;
+ if ((penHeld) && (!penDownThisFrame)) {
+ if ((touchPadStyle) || (moved) || (tapCount == 1)) {
+ if ((penDownFrames > 0) && (penDownFrames < 6) && ((tapTimeout == -1) || (tapTimeout > 2))) {
+ tapCount++;
+ tapTimeout = 0;
+// consolePrintf("Tap! %d\n", penDownFrames);
+ moved = false;
+ }
}
- //}
}
+ }
- } else {
- if (penHeld) {
- penReleased = true;
- penReleasedSaved = true;
+
+
+ if ((touchPadStyle) && (getIsDisplayMode8Bit())) {
+
+ if ((penDownFrames > 0)) {
+
+
+ if ((penHeld)) {
+
+ if (penDownThisFrame)
+ {
+ if (penDownFrames >= 2) {
+ int diffX = IPC->touchXpx - penDownX;
+ int diffY = IPC->touchYpx - penDownY;
+
+ int speed = ABS(diffX) + ABS(diffY);
+
+ if ((ABS(diffX) < 35) && (ABS(diffY) < 35))
+ {
+
+ if (speed >= 8)
+ {
+ diffX *= ((speed >> 3) * touchPadSensitivity) >> 3;
+ diffY *= ((speed >> 3) * touchPadSensitivity) >> 3;
+ }
+
+ penX += diffX;
+ penY += diffY;
+ if (penX > 255) penX = 255;
+ if (penX < 0) penX = 0;
+ if (penY > 191) penY = 191;
+ if (penY < 0) penY = 0;
+ }
+
+// consolePrintf("x: %d y: %d\n", IPC->touchYpx - penDownY, IPC->touchYpx - penDownY);
+ penDownX = IPC->touchXpx;
+ penDownY = IPC->touchYpx;
+
+ }
+ }
+ else
+ {
+ }
+
+
+ } else {
+ penDown = true;
+ penHeld = true;
+ penDownSaved = true;
+
+ // First frame, so save pen positions
+ if (penDownThisFrame) {
+ penDownX = IPC->touchXpx;
+ penDownY = IPC->touchYpx;
+ }
+ }
+
} else {
- penReleased = false;
+ if (penHeld) {
+ penReleased = true;
+ penReleasedSaved = true;
+ } else {
+ penReleased = false;
+ }
+
+ penDown = false;
+ penHeld = false;
}
+ } else {
+ if ((penDownFrames > 1)) { // Is this right? Dunno, but it works for me.
+
+ if ((penHeld)) {
+ penHeld = true;
+ penDown = false;
+ } else {
+ penDown = true;
+ penHeld = true;
+ penDownSaved = true;
+ }
+
+ if ((IPC->touchZ1 > 0) && (IPC->touchXpx > 0) && (IPC->touchYpx > 0)) {
+ penX = IPC->touchXpx + touchXOffset;
+ penY = IPC->touchYpx + touchYOffset;
+ moved = true;
+ }
+
- penDown = false;
- penHeld = false;
+
+ } else {
+ if (penHeld) {
+ penReleased = true;
+ penReleasedSaved = true;
+ } else {
+ penReleased = false;
+ }
+
+ penDown = false;
+ penHeld = false;
+ }
+
+
}
+
if ((IPC->touchZ1 > 0) || ((penDownFrames == 2)) ) {
penDownLastFrame = true;
penDownFrames++;
@@ -2258,7 +2539,6 @@ void penUpdate() {
penDownLastFrame = false;
penDownFrames = 0;
}
-
}
int leftHandedSwap(int keys) {
@@ -2345,8 +2625,7 @@ int getPenX() {
int x = ((penX * touchScX) >> 8) + touchX;
x = x < 0? 0: (x > gameWidth - 1? gameWidth - 1: x);
- if (snapToBorder)
- {
+ if (snapToBorder) {
if (x < 8) x = 0;
if (x > gameWidth - 8) x = gameWidth - 1;
}
@@ -2358,8 +2637,7 @@ int getPenY() {
int y = ((penY * touchScY) >> 8) + touchY;
y = y < 0? 0: (y > gameHeight - 1? gameHeight - 1: y);
- if (snapToBorder)
- {
+ if (snapToBorder) {
if (y < 8) y = 0;
if (y > gameHeight - 8) y = gameHeight - 1;
}
@@ -2376,6 +2654,8 @@ GLvector getPenPos() {
return v;
}
+#ifdef GBA_SRAM_SAVE
+
void formatSramOption() {
consolePrintf("The following files are present in save RAM:\n");
DSSaveFileManager::instance()->listFiles();
@@ -2397,7 +2677,7 @@ void formatSramOption() {
}
}
}
-
+#endif
void setIndyFightState(bool st) {
indyFightState = st;
@@ -2495,8 +2775,6 @@ struct cardTranslate {
char dldiId[5];
};
-#define NUM_CARD_READERS 7
-
cardTranslate cardReaderTable[] = {
{DEVICE_TYPE_M3SD, DEVICE_M3SD, "M3SD"},
{DEVICE_TYPE_M3CF, DEVICE_M3CF, "M3CF"},
@@ -2518,13 +2796,13 @@ void reboot() {
consolePrintf("DLDI Device ID: %s\n", id);
- for (int r = 0; r < NUM_CARD_READERS; r++) {
+ for (int r = 0; r < ARRAYSIZE(cardReaderTable); r++) {
if (!stricmp(id, cardReaderTable[r].dldiId)) {
deviceType = cardReaderTable[r].cartResetId;
}
}
} else {
- for (int r = 0; r < NUM_CARD_READERS; r++) {
+ for (int r = 0; r < ARRAYSIZE(cardReaderTable); r++) {
if (disc_getDeviceId() == cardReaderTable[r].svmId) {
deviceType = cardReaderTable[r].cartResetId;
}
@@ -2572,13 +2850,66 @@ void powerOff() {
/////////////////
-int main(void)
-{
+
+void dsExceptionHandler() {
+ consolePrintf("Blue screen of death");
+ setExceptionHandler(NULL);
+
+
+ u32 currentMode = getCPSR() & 0x1f;
+ u32 thumbState = ((*(u32*)0x027FFD90) & 0x20);
+
+ u32 codeAddress, exceptionAddress = 0;
+
+ int offset = 8;
+
+ if ( currentMode == 0x17 ) {
+ consolePrintf("\x1b[10Cdata abort!\n\n");
+ codeAddress = exceptionRegisters[15] - offset;
+ if ( (codeAddress > 0x02000000 && codeAddress < 0x02400000) ||
+ (codeAddress > (u32)__itcm_start && codeAddress < (u32)(__itcm_start + 32768)) )
+ exceptionAddress = getExceptionAddress( codeAddress, thumbState);
+ else
+ exceptionAddress = codeAddress;
+
+ } else {
+ if (thumbState)
+ offset = 2;
+ else
+ offset = 4;
+ consolePrintf("\x1b[5Cundefined instruction!\n\n");
+ codeAddress = exceptionRegisters[15] - offset;
+ exceptionAddress = codeAddress;
+ }
+
+ consolePrintf(" pc: %08X addr: %08X\n\n",codeAddress,exceptionAddress);
+
+ int i;
+ for ( i=0; i < 8; i++ ) {
+ consolePrintf( " %s: %08X %s: %08X\n",
+ registerNames[i], exceptionRegisters[i],
+ registerNames[i+8],exceptionRegisters[i+8]);
+ }
+// u32 *stack = (u32 *)exceptionRegisters[13];
+// for ( i=0; i<10; i++ ) {
+// consolePrintf( "\x1b[%d;2H%08X: %08X %08X", i + 14, (u32)&stack[i*2],stack[i*2], stack[(i*2)+1] );
+// }
+
+ memoryReport();
+
+ while(1);
+}
+
+
+
+
+int main(void) {
soundCallback = NULL;
initHardware();
+ setExceptionHandler(dsExceptionHandler);
#ifdef USE_DEBUGGER
for (int r = 0; r < 150; r++) {
@@ -2662,36 +2993,33 @@ int main(void)
consolePrintf("-------------------------------\n");
consolePrintf("ScummVM DS\n");
consolePrintf("Ported by Neil Millstone\n");
- consolePrintf("Version 0.11.1 beta2");
+ consolePrintf("Version 0.13.0 SVN ");
#if defined(DS_BUILD_A)
consolePrintf("build A\n");
consolePrintf("Lucasarts SCUMM games (SCUMM)\n");
- consolePrintf("-------------------------------\n");
#elif defined(DS_BUILD_B)
consolePrintf("build B\n");
consolePrintf("BASS, QUEEN\n");
- consolePrintf("-------------------------------\n");
#elif defined(DS_BUILD_C)
consolePrintf("build C\n");
consolePrintf("Simon/Elvira/Waxworks (AGOS)\n");
- consolePrintf("-------------------------------\n");
#elif defined(DS_BUILD_D)
consolePrintf("build D\n");
consolePrintf("AGI, CINE, GOB\n");
- consolePrintf("-------------------------------\n");
#elif defined(DS_BUILD_E)
consolePrintf("build E\n");
consolePrintf("Inherit the Earth (SAGA)\n");
- consolePrintf("-------------------------------\n");
#elif defined(DS_BUILD_F)
consolePrintf("build F\n");
consolePrintf("The Legend of Kyrandia (KYRA)\n");
- consolePrintf("-------------------------------\n");
#elif defined(DS_BUILD_G)
- consolePrintf("build F\n");
- consolePrintf("Lure of the Temptress (LURE)\n");
- consolePrintf("-------------------------------\n");
+ consolePrintf("build G\n");
+ consolePrintf("Lure of the Tempress (LURE)\n");
+#elif defined(DS_BUILD_H)
+ consolePrintf("build H\n");
+ consolePrintf("Nippon Safes (PARALLATION)\n");
#endif
+ consolePrintf("-------------------------------\n");
consolePrintf("L/R + D-pad/pen: Scroll view\n");
consolePrintf("D-pad left: Left mouse button\n");
consolePrintf("D-pad right: Right mouse button\n");
@@ -2807,9 +3135,11 @@ int main(void)
g_system = new OSystem_DS();
assert(g_system);
+#ifdef GBA_SRAM_SAVE
if ((keysHeld() & KEY_L) && (keysHeld() & KEY_R)) {
formatSramOption();
}
+#endif
IPC->adpcm.semaphore = false;
@@ -2830,6 +3160,8 @@ int main(void)
const char *argv[] = {"/scummvmds", "--config=scummvmf.ini"};
#elif defined(DS_BUILD_G)
const char *argv[] = {"/scummvmds", "--config=scummvmg.ini"};
+#elif defined(DS_BUILD_H)
+ const char *argv[] = {"/scummvmds", "--config=scummvmh.ini"};
#endif
while (1) {
diff --git a/backends/platform/ds/arm9/source/dsmain.h b/backends/platform/ds/arm9/source/dsmain.h
index 43258b5c5d..ab74554917 100644
--- a/backends/platform/ds/arm9/source/dsmain.h
+++ b/backends/platform/ds/arm9/source/dsmain.h
@@ -38,7 +38,8 @@ enum controlType {
CONT_SIMON,
CONT_FUTURE_WARS,
CONT_AGI,
- CONT_GOBLINS
+ CONT_GOBLINS,
+ CONT_NIPPON,
};
struct gameListType {
@@ -56,6 +57,7 @@ int getPenX();
int getPenY();
GLvector getPenPos();
void consumePenEvents();
+controlType getControlType();
// Pad reading
int getKeysHeld();
@@ -64,6 +66,8 @@ int getKeysDown();
int getKeysReleased();
void consumeKeys();
int leftHandedSwap(int keys);
+void setGameScreenSwap(bool enable);
+void setSensitivity(int sensitivity);
// Video
void displayMode8Bit(); // Switch to 8-bit mode5
@@ -81,6 +85,7 @@ u16* getScalerBuffer();
void setTalkPos(int x, int y);
void setTopScreenTarget(int x, int y);
void set200PercentFixedScale(bool on);
+void setTopScreenZoom(int percentage);
// Timers
void setTimerCallback(OSystem_DS::TimerProc proc, int interval); // Setup a callback function at a regular interval
@@ -88,7 +93,9 @@ int getMillis(); // Return the current runtime in milliseconds
void doTimerCallback(); // Call callback function if required
// Sound
-void doSoundCallback(); // Call function if sound buffers need more data
+void doSoundCallback();
+void startSound(int freq, int buffer); // Start sound hardware
+// Call function if sound buffers need more data
void playSound(const void* data, u32 length, bool loop, bool adpcm = false, int rate = 22050); // Start a sound
void stopSound(int channel);
int getSoundFrequency();
@@ -131,6 +138,8 @@ void setIndyFightState(bool st);
bool getIndyFightState();
bool isCpuScalerEnabled();
void setCpuScalerEnable(bool enable);
+void setTrackPadStyleEnable(bool enable);
+void setTapScreenClicksEnable(bool enable);
// Display
bool getIsDisplayMode8Bit();
diff --git a/backends/platform/ds/arm9/source/dsoptions.cpp b/backends/platform/ds/arm9/source/dsoptions.cpp
index edb9c70580..2dbc4b842b 100644
--- a/backends/platform/ds/arm9/source/dsoptions.cpp
+++ b/backends/platform/ds/arm9/source/dsoptions.cpp
@@ -25,6 +25,7 @@
#include "gui/dialog.h"
#include "gui/newgui.h"
#include "gui/ListWidget.h"
+#include "gui/TabWidget.h"
#include "osystem_ds.h"
#include "engines/scumm/scumm.h"
#include "touchkeyboard.h"
@@ -41,8 +42,67 @@ namespace Scumm {
namespace DS {
-DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(5, 0, 320 - 5, 230 - 20) {
- addButton(this, 10, 175, "Close", GUI::kCloseCmd, 'C');
+DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(0, 0, 320 - 10, 230 - 40) {
+
+ addButton(this, 10, 170, "Close", GUI::kCloseCmd, 'C');
+ _tab = new GUI::TabWidget(this, 5, 5, 300, 230 - 20 - 40 - 10);
+
+ _tab->addTab("Controls");
+
+ _leftHandedCheckbox = new GUI::CheckboxWidget(_tab, 5, 5, 130, 20, "Left handed mode", 0, 'L');
+ _indyFightCheckbox = new GUI::CheckboxWidget(_tab, 5, 20, 140, 20, "Indy fight controls", 0, 'I');
+ _showCursorCheckbox = new GUI::CheckboxWidget(_tab, 150, 5, 130, 20, "Show mouse cursor", 0, 'T');
+ _snapToBorderCheckbox = new GUI::CheckboxWidget(_tab, 150, 20, 130, 20, "Snap to edges", 0, 'T');
+
+ new GUI::StaticTextWidget(_tab, 20, 35, 100, 15, "Touch X Offset", GUI::kTextAlignLeft);
+ _touchX = new GUI::SliderWidget(_tab, 130, 35, 130, 12, 1);
+ _touchX->setMinValue(-8);
+ _touchX->setMaxValue(+8);
+ _touchX->setValue(0);
+ _touchX->setFlags(GUI::WIDGET_CLEARBG);
+
+ new GUI::StaticTextWidget(_tab, 20, 50, 100, 15, "Touch Y Offset", GUI::kTextAlignLeft);
+ _touchY = new GUI::SliderWidget(_tab, 130, 50, 130, 12, 2);
+ _touchY->setMinValue(-8);
+ _touchY->setMaxValue(+8);
+ _touchY->setValue(0);
+ _touchY->setFlags(GUI::WIDGET_CLEARBG);
+
+ new GUI::StaticTextWidget(_tab, 130 + 65 - 10, 65, 20, 15, "0", GUI::kTextAlignCenter);
+ new GUI::StaticTextWidget(_tab, 130 + 130 - 10, 65, 20, 15, "8", GUI::kTextAlignCenter);
+ new GUI::StaticTextWidget(_tab, 130 - 20, 65, 20, 15, "-8", GUI::kTextAlignCenter);
+
+
+ _touchPadStyle = new GUI::CheckboxWidget(_tab, 5, 80, 270, 20, "Use laptop trackpad-style cursor control", 0x20000001, 'T');
+ _screenTaps = new GUI::CheckboxWidget(_tab, 5, 95, 285, 20, "Tap for left click, double tap right click", 0x20000002, 'T');
+
+ _sensitivityLabel = new GUI::StaticTextWidget(_tab, 20, 110, 110, 15, "Sensitivity", GUI::kTextAlignLeft);
+ _sensitivity = new GUI::SliderWidget(_tab, 130, 110, 130, 12, 1);
+ _sensitivity->setMinValue(4);
+ _sensitivity->setMaxValue(16);
+ _sensitivity->setValue(8);
+ _sensitivity->setFlags(GUI::WIDGET_CLEARBG);
+
+ _tab->addTab("Graphics");
+
+ new GUI::StaticTextWidget(_tab, 5, 70, 180, 15, "Initial top screen scale:", GUI::kTextAlignLeft);
+
+ _100PercentCheckbox = new GUI::CheckboxWidget(_tab, 5, 85, 230, 20, "100%", 0x30000001, 'T');
+ _150PercentCheckbox = new GUI::CheckboxWidget(_tab, 5, 100, 230, 20, "150%", 0x30000002, 'T');
+ _200PercentCheckbox = new GUI::CheckboxWidget(_tab, 5, 115, 230, 20, "200%", 0x30000003, 'T');
+
+ new GUI::StaticTextWidget(_tab, 5, 5, 180, 15, "Main screen scaling:", GUI::kTextAlignLeft);
+
+ _hardScaler = new GUI::CheckboxWidget(_tab, 5, 20, 270, 20, "Hardware scale (fast, but low quality)", 0x10000001, 'T');
+ _cpuScaler = new GUI::CheckboxWidget(_tab, 5, 35, 270, 20, "Software scale (good quality, but slower)", 0x10000002, 'S');
+ _unscaledCheckbox = new GUI::CheckboxWidget(_tab, 5, 50, 270, 20, "Unscaled (you must scroll left and right)", 0x10000003, 'S');
+
+ _tab->addTab("General");
+
+ _highQualityAudioCheckbox = new GUI::CheckboxWidget(_tab, 5, 5, 250, 20, "High quality audio (slower) (reboot)", 0, 'T');
+ _disablePowerOff = new GUI::CheckboxWidget(_tab, 5, 20, 200, 20, "Disable power off", 0, 'T');
+
+ _tab->setActiveTab(0);
_radioButtonMode = false;
@@ -52,46 +112,17 @@ DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(5, 0, 320 - 5, 230 - 20) {
}
#endif
- new GUI::StaticTextWidget(this, 90, 10, 130, 15, "ScummVM DS Options", GUI::kTextAlignCenter);
+// new GUI::StaticTextWidget(this, 90, 10, 130, 15, "ScummVM DS Options", GUI::kTextAlignCenter);
- _leftHandedCheckbox = new GUI::CheckboxWidget(this, 5, 70, 130, 20, "Left handed mode", 0, 'L');
- _indyFightCheckbox = new GUI::CheckboxWidget(this, 5, 40, 200, 20, "Indy fighting controls", 0, 'I');
- _twoHundredPercentCheckbox = new GUI::CheckboxWidget(this, 5, 55, 230, 20, "Zoomed screen at fixed 200% zoom", 0, 'T');
- _highQualityAudioCheckbox = new GUI::CheckboxWidget(this, 5, 25, 250, 20, "High quality audio (slower) (reboot)", 0, 'T');
- _disablePowerOff = new GUI::CheckboxWidget(this, 5, 85, 130, 20, "Disable power off", 0, 'T');
- _showCursorCheckbox = new GUI::CheckboxWidget(this, 5, 100, 130, 20, "Show mouse cursor", 0, 'T');
//#ifdef ALLOW_CPU_SCALER
// _cpuScaler = new GUI::CheckboxWidget(this, 160, 115, 90, 20, "CPU scaler", 0, 'T');
//#endif
- new GUI::StaticTextWidget(this, 180, 70, 130, 15, "Main screen:", GUI::kTextAlignLeft);
-
- _hardScaler = new GUI::CheckboxWidget(this, 140, 85, 170, 20, "Hardware scale (fast)", 0x10000001, 'T');
- _cpuScaler = new GUI::CheckboxWidget(this, 140, 100, 170, 20, "Software scale (quality)", 0x10000002, 'S');
- _unscaledCheckbox = new GUI::CheckboxWidget(this, 140, 115, 170, 20, "Unscaled", 0x10000003, 'S');
- _snapToBorderCheckbox = new GUI::CheckboxWidget(this, 5, 115, 120, 20, "Snap to border", 0, 'T');
- new GUI::StaticTextWidget(this, 20, 145, 110, 15, "Touch X Offset", GUI::kTextAlignLeft);
- _touchX = new GUI::SliderWidget(this, 130, 145, 130, 12, 1);
- _touchX->setMinValue(-8);
- _touchX->setMaxValue(+8);
- _touchX->setValue(0);
- _touchX->setFlags(GUI::WIDGET_CLEARBG);
-
- new GUI::StaticTextWidget(this, 20, 160, 110, 15, "Touch Y Offset", GUI::kTextAlignLeft);
- _touchY = new GUI::SliderWidget(this, 130, 160, 130, 12, 2);
- _touchY->setMinValue(-8);
- _touchY->setMaxValue(+8);
- _touchY->setValue(0);
- _touchY->setFlags(GUI::WIDGET_CLEARBG);
-
- new GUI::StaticTextWidget(this, 130 + 65 - 10, 175, 20, 15, "0", GUI::kTextAlignCenter);
- new GUI::StaticTextWidget(this, 130 + 130 - 10, 175, 20, 15, "8", GUI::kTextAlignCenter);
- new GUI::StaticTextWidget(this, 130 - 10, 175, 20, 15, "-8", GUI::kTextAlignCenter);
#ifdef DS_SCUMM_BUILD
_delDialog = new Scumm::SaveLoadChooser("Delete game:", "Delete", false, Scumm::g_scumm);
@@ -125,10 +156,36 @@ DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(5, 0, 320 - 5, 230 - 20) {
_unscaledCheckbox->setState(false);
}
- if (ConfMan.hasKey("twohundredpercent", "ds")) {
- _twoHundredPercentCheckbox->setState(ConfMan.getBool("twohundredpercent", "ds"));
+
+ if (ConfMan.hasKey("topscreenzoom", "ds")) {
+
+ _100PercentCheckbox->setState(false);
+ _150PercentCheckbox->setState(false);
+ _200PercentCheckbox->setState(false);
+
+ switch (ConfMan.getInt("topscreenzoom", "ds"))
+ {
+ case 100: {
+ _100PercentCheckbox->setState(true);
+ break;
+ }
+
+ case 150: {
+ _150PercentCheckbox->setState(true);
+ break;
+ }
+
+ case 200: {
+ _200PercentCheckbox->setState(true);
+ break;
+ }
+ }
+
+ } else if (ConfMan.hasKey("twohundredpercent", "ds")) {
+ _200PercentCheckbox->setState(ConfMan.getBool("twohundredpercent", "ds"));
} else {
- _twoHundredPercentCheckbox->setState(false);
+ // No setting
+ _150PercentCheckbox->setState(true);
}
if (ConfMan.hasKey("22khzaudio", "ds")) {
@@ -165,6 +222,29 @@ DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(5, 0, 320 - 5, 230 - 20) {
_touchY->setValue(0);
}
+ if (ConfMan.hasKey("sensitivity", "ds")) {
+ _sensitivity->setValue(ConfMan.getInt("sensitivity", "ds"));
+ } else {
+ _sensitivity->setValue(8);
+ }
+
+ if (ConfMan.hasKey("touchpad", "ds")) {
+ _touchPadStyle->setState(ConfMan.getBool("touchpad", "ds"));
+ } else {
+ _touchPadStyle->setState(0);
+ }
+
+ if (ConfMan.hasKey("screentaps", "ds")) {
+ _screenTaps->setState(ConfMan.getBool("screentaps", "ds"));
+ } else {
+ _screenTaps->setState(0);
+ }
+
+ _screenTaps->setEnabled(!_touchPadStyle->getState());
+ _sensitivity->setEnabled(_touchPadStyle->getState());
+ _sensitivityLabel->setEnabled(_touchPadStyle->getState());
+ _sensitivityLabel->draw();
+
if (!_cpuScaler->getState() && !_unscaledCheckbox->getState()) {
_hardScaler->setState(true);
}
@@ -180,7 +260,7 @@ DSOptionsDialog::~DSOptionsDialog() {
void DSOptionsDialog::updateConfigManager() {
ConfMan.setBool("lefthanded", _leftHandedCheckbox->getState(), "ds");
ConfMan.setBool("unscaled", _unscaledCheckbox->getState(), "ds");
- ConfMan.setBool("twohundredpercent", _twoHundredPercentCheckbox->getState(), "ds");
+// ConfMan.setBool("twohundredpercent", _twoHundredPercentCheckbox->getState(), "ds");
ConfMan.setBool("22khzaudio", _highQualityAudioCheckbox->getState(), "ds");
ConfMan.setBool("disablepoweroff", _disablePowerOff->getState(), "ds");
#ifdef ALLOW_CPU_SCALER
@@ -190,6 +270,24 @@ void DSOptionsDialog::updateConfigManager() {
ConfMan.setInt("yoffset", _touchY->getValue(), "ds");
ConfMan.setBool("showcursor", _showCursorCheckbox->getState(), "ds");
ConfMan.setBool("snaptoborder", _snapToBorderCheckbox->getState(), "ds");
+ ConfMan.setBool("touchpad", _touchPadStyle->getState(), "ds");
+ ConfMan.setBool("screentaps", _screenTaps->getState(), "ds");
+ ConfMan.setInt("sensitivity", _sensitivity->getValue(), "ds");
+
+ u32 zoomLevel = 150;
+
+ if (_100PercentCheckbox->getState()) {
+ zoomLevel = 100;
+ } else if (_150PercentCheckbox->getState()) {
+ zoomLevel = 150;
+ } else if (_200PercentCheckbox->getState()) {
+ zoomLevel = 200;
+ }
+
+ consolePrintf("Saved zoom: %d\n", zoomLevel);
+
+ ConfMan.setInt("topscreenzoom", zoomLevel, "ds");
+
DS::setOptions();
}
@@ -227,6 +325,70 @@ void DSOptionsDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint
}
+ if ((!guard) && (_radioButtonMode))
+ {
+ guard = true;
+
+ if ((sender == _touchPadStyle) && (cmd == 0x20000001)) {
+
+ if (_touchPadStyle->getState()) {
+ // Swap screens when turning on trackpad style, it feels
+ // much more natural!
+ DS::setGameScreenSwap(true);
+
+ _screenTaps->setState(true);
+ _screenTaps->setEnabled(false);
+ _screenTaps->draw();
+ _sensitivity->setEnabled(true);
+ _sensitivityLabel->setEnabled(true);
+ _sensitivityLabel->draw();
+ _sensitivity->draw();
+ } else {
+ DS::setGameScreenSwap(false);
+
+ _screenTaps->setEnabled(true);
+ _screenTaps->setState(false);
+ _screenTaps->draw();
+ _sensitivity->setEnabled(false);
+ _sensitivityLabel->setEnabled(false);
+ _sensitivityLabel->draw();
+ _sensitivity->draw();
+ }
+ }
+
+ guard = false;
+ }
+
+ if ((!guard) && (_radioButtonMode)) {
+
+ guard = true;
+
+ if (cmd == 0x30000001) {
+ _100PercentCheckbox->setState(true);
+ _150PercentCheckbox->setState(false);
+ _200PercentCheckbox->setState(false);
+ DS::setTopScreenZoom(100);
+ }
+
+ if (cmd == 0x30000002) {
+ _100PercentCheckbox->setState(false);
+ _150PercentCheckbox->setState(true);
+ _200PercentCheckbox->setState(false);
+ DS::setTopScreenZoom(150);
+ }
+
+ if (cmd == 0x30000003) {
+ _100PercentCheckbox->setState(false);
+ _150PercentCheckbox->setState(false);
+ _200PercentCheckbox->setState(true);
+ DS::setTopScreenZoom(200);
+ }
+
+ guard = false;
+
+ }
+
+
if (cmd == GUI::kCloseCmd) {
updateConfigManager();
close();
@@ -297,6 +459,8 @@ void showOptionsDialog() {
}
void setOptions() {
+ static bool firstLoad = true;
+
ConfMan.addGameDomain("ds");
if (ConfMan.hasKey("lefthanded", "ds")) {
@@ -327,10 +491,16 @@ void setOptions() {
DS::setUnscaledMode(false);
}
- if (ConfMan.hasKey("twohundredpercent", "ds")) {
- DS::set200PercentFixedScale(ConfMan.getBool("twohundredpercent", "ds"));
- } else {
- DS::set200PercentFixedScale(false);
+ if (firstLoad) {
+ if (ConfMan.hasKey("topscreenzoom", "ds")) {
+ DS::setTopScreenZoom(ConfMan.getInt("topscreenzoom", "ds"));
+ } else {
+ if (ConfMan.hasKey("twohundredpercent", "ds")) {
+ DS::setTopScreenZoom(200);
+ } else {
+ DS::setTopScreenZoom(150);
+ }
+ }
}
if (ConfMan.hasKey("xoffset", "ds")) {
@@ -345,6 +515,12 @@ void setOptions() {
DS::setTouchXOffset(0);
}
+ if (ConfMan.hasKey("sensitivity", "ds")) {
+ DS::setSensitivity(ConfMan.getInt("sensitivity", "ds"));
+ } else {
+ DS::setSensitivity(8);
+ }
+
#ifdef ALLOW_CPU_SCALER
if (ConfMan.hasKey("cpu_scaler", "ds")) {
DS::setCpuScalerEnable(ConfMan.getBool("cpu_scaler", "ds"));
@@ -353,6 +529,33 @@ void setOptions() {
}
#endif
+ if (ConfMan.hasKey("screentaps", "ds")) {
+ DS::setTapScreenClicksEnable(ConfMan.getBool("screentaps", "ds"));
+ } else {
+ DS::setTapScreenClicksEnable(false);
+ }
+
+ if (ConfMan.hasKey("touchpad", "ds")) {
+ bool enable = ConfMan.getBool("touchpad", "ds");
+
+ DS::setTrackPadStyleEnable(enable);
+
+ if ((enable) and (firstLoad)) {
+ // If we've just booted up, want to swap screens when trackpad mode is in use
+ // but not every time we enter the options dialog.
+ DS::setGameScreenSwap(true);
+ }
+
+ if (enable) {
+ DS::setTapScreenClicksEnable(true);
+ }
+
+ } else {
+ DS::setTrackPadStyleEnable(false);
+ }
+
+
+ firstLoad = false;
}
}
diff --git a/backends/platform/ds/arm9/source/dsoptions.h b/backends/platform/ds/arm9/source/dsoptions.h
index 9cfa785ca8..e3ab2f55e0 100644
--- a/backends/platform/ds/arm9/source/dsoptions.h
+++ b/backends/platform/ds/arm9/source/dsoptions.h
@@ -30,6 +30,7 @@
#include "gui/object.h"
#include "gui/widget.h"
#include "gui/dialog.h"
+#include "gui/TabWidget.h"
#include "scumm/dialogs.h"
namespace DS {
@@ -45,11 +46,18 @@ protected:
void togglePause();
void updateConfigManager();
+ GUI::TabWidget* _tab;
+
+ GUI::StaticTextWidget* _sensitivityLabel;
+
GUI::SliderWidget* _touchX;
GUI::SliderWidget* _touchY;
+ GUI::SliderWidget* _sensitivity;
GUI::CheckboxWidget* _leftHandedCheckbox;
GUI::CheckboxWidget* _unscaledCheckbox;
- GUI::CheckboxWidget* _twoHundredPercentCheckbox;
+ GUI::CheckboxWidget* _100PercentCheckbox;
+ GUI::CheckboxWidget* _150PercentCheckbox;
+ GUI::CheckboxWidget* _200PercentCheckbox;
GUI::CheckboxWidget* _indyFightCheckbox;
GUI::CheckboxWidget* _highQualityAudioCheckbox;
GUI::CheckboxWidget* _disablePowerOff;
@@ -59,6 +67,9 @@ protected:
GUI::CheckboxWidget* _hardScaler;
GUI::CheckboxWidget* _cpuScaler;
+ GUI::CheckboxWidget* _touchPadStyle;
+ GUI::CheckboxWidget* _screenTaps;
+
#ifdef DS_SCUMM_BUILD
Scumm::SaveLoadChooser* _delDialog;
#endif
diff --git a/backends/platform/ds/arm9/source/gbampsave.cpp b/backends/platform/ds/arm9/source/gbampsave.cpp
index ed45d02b1e..068d996e92 100644
--- a/backends/platform/ds/arm9/source/gbampsave.cpp
+++ b/backends/platform/ds/arm9/source/gbampsave.cpp
@@ -155,11 +155,13 @@ GBAMPSaveFile* GBAMPSaveFileManager::openSavefile(char const* name, bool saveOrL
sprintf(fileSpec, "%s/%s", getSavePath(), name);
}
-// consolePrintf(fileSpec);
+// consolePrintf("Opening the file: %s\n", fileSpec);
GBAMPSaveFile* sf = new GBAMPSaveFile(fileSpec, saveOrLoad);
if (sf->isOpen()) {
+// consolePrintf("Ok");
return sf;
} else {
+// consolePrintf("Fail");
delete sf;
return NULL;
}
diff --git a/backends/platform/ds/arm9/source/osystem_ds.cpp b/backends/platform/ds/arm9/source/osystem_ds.cpp
index 79b0c5390b..5ddcb50b15 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.cpp
+++ b/backends/platform/ds/arm9/source/osystem_ds.cpp
@@ -41,7 +41,8 @@
OSystem_DS* OSystem_DS::_instance = NULL;
OSystem_DS::OSystem_DS()
- : eventNum(0), lastPenFrame(0), queuePos(0), _mixer(NULL), _timer(NULL), _frameBufferExists(false)
+ : eventNum(0), lastPenFrame(0), queuePos(0), _mixer(NULL), _timer(NULL), _frameBufferExists(false),
+ _disableCursorPalette(true), _graphicsEnable(true)
{
// eventNum = 0;
// lastPenFrame = 0;
@@ -71,7 +72,13 @@ void OSystem_DS::initBackend() {
_timer = new DSTimerManager();
DS::setTimerCallback(&OSystem_DS::timerHandler, 10);
- _mixer->setOutputRate(11025 /*DS::getSoundFrequency()*/);
+ if (ConfMan.hasKey("22khzaudio", "ds") && ConfMan.getBool("22khzaudio", "ds")) {
+ DS::startSound(22050, 8192);
+ } else {
+ DS::startSound(11025, 4096);
+ }
+
+ _mixer->setOutputRate(DS::getSoundFrequency());
_mixer->setReady(true);
OSystem::initBackend();
@@ -79,7 +86,7 @@ void OSystem_DS::initBackend() {
bool OSystem_DS::hasFeature(Feature f) {
// consolePrintf("hasfeature\n");
- return (f == kFeatureVirtualKeyboard);
+ return (f == kFeatureVirtualKeyboard) || (f == kFeatureCursorHasPalette);
}
void OSystem_DS::setFeatureState(Feature f, bool enable) {
@@ -107,7 +114,7 @@ bool OSystem_DS::setGraphicsMode(int mode) {
}
bool OSystem_DS::setGraphicsMode(const char *name) {
-// consolePrintf("Set gfx mode %s\n", name);
+ consolePrintf("Set gfx mode %s\n", name);
return true;
}
@@ -116,8 +123,15 @@ int OSystem_DS::getGraphicsMode() const {
}
void OSystem_DS::initSize(uint width, uint height) {
-// consolePrintf("Set gfx mode %d x %d\n", width, height);
- DS::setGameSize(width, height);
+ // For Lost in Time, the title screen is displayed in 640x400.
+ // In order to support this game, the screen mode is set, but
+ // all draw calls are ignored until the game switches to 320x200.
+ if ((width == 640) && (height == 400)) {
+ _graphicsEnable = false;
+ } else {
+ _graphicsEnable = true;
+ DS::setGameSize(width, height);
+ }
}
int16 OSystem_DS::getHeight() {
@@ -129,9 +143,8 @@ int16 OSystem_DS::getWidth() {
}
void OSystem_DS::setPalette(const byte *colors, uint start, uint num) {
-// consolePrintf("Set palette %d, %d colours\n", start, num);
-//return;
- if (!DS::getIsDisplayMode8Bit()) return;
+// consolePrintf("Setpal %d, %d\n", start, num);
+
for (unsigned int r = start; r < start + num; r++) {
int red = *colors;
int green = *(colors + 1);
@@ -141,17 +154,44 @@ void OSystem_DS::setPalette(const byte *colors, uint start, uint num) {
green >>= 3;
blue >>= 3;
- if (r != 255)
+// if (r != 255)
{
- BG_PALETTE[r] = red | (green << 5) | (blue << 10);
- if (!DS::getKeyboardEnable()) {
- BG_PALETTE_SUB[r] = red | (green << 5) | (blue << 10);
+ u16 paletteValue = red | (green << 5) | (blue << 10);
+
+ if (DS::getIsDisplayMode8Bit()) {
+ BG_PALETTE[r] = paletteValue;
+ if (!DS::getKeyboardEnable()) {
+ BG_PALETTE_SUB[r] = paletteValue;
+ }
}
+
+ _palette[r] = paletteValue;
}
-// if (num == 16) consolePrintf("pal:%d r:%d g:%d b:%d\n", r, red, green, blue);
+ // if (num == 255) consolePrintf("pal:%d r:%d g:%d b:%d\n", r, red, green, blue);
+
+ colors += 4;
+ }
+}
+
+void OSystem_DS::setCursorPalette(const byte *colors, uint start, uint num) {
+
+// consolePrintf("Cursor palette set: start: %d, cols: %d\n", start, num);
+ for (unsigned int r = start; r < start + num; r++) {
+ int red = *colors;
+ int green = *(colors + 1);
+ int blue = *(colors + 2);
+
+ red >>= 3;
+ green >>= 3;
+ blue >>= 3;
+ u16 paletteValue = red | (green << 5) | (blue << 10);
+ _cursorPalette[r] = paletteValue;
+
colors += 4;
}
+
+ _disableCursorPalette = false;
}
bool OSystem_DS::grabRawScreen(Graphics::Surface* surf) {
@@ -184,9 +224,11 @@ void OSystem_DS::grabPalette(unsigned char *colors, uint start, uint num) {
}
+#define MISALIGNED16(ptr) (((u32) (ptr) & 1) != 0)
+
void OSystem_DS::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) {
-// consolePrintf("Copy rect %d, %d %d, %d ", x, y, w, h);
-
+ //consolePrintf("Copy rect %d, %d %d, %d ", x, y, w, h);
+ if (!_graphicsEnable) return;
if (w <= 1) return;
if (h < 0) return;
if (!DS::getIsDisplayMode8Bit()) return;
@@ -195,6 +237,9 @@ void OSystem_DS::copyRectToScreen(const byte *buf, int pitch, int x, int y, int
s32 stride;
u16* bgSub = (u16 *) BG_GFX_SUB;
+ // The DS video RAM doesn't support 8-bit writes because Nintendo wanted
+ // to save a few pennies/euro cents on the hardware.
+
if (_frameBufferExists) {
bg = (u16 *) _framebuffer.pixels;
stride = _framebuffer.pitch;
@@ -203,46 +248,117 @@ void OSystem_DS::copyRectToScreen(const byte *buf, int pitch, int x, int y, int
stride = DS::get8BitBackBufferStride();
}
- u16* src = (u16 *) buf;
-
- if (DS::getKeyboardEnable()) {
-
+ if (((pitch & 1) != 0) || ((w & 1) != 0) || (((int) (buf) & 1) != 0)) {
+
+ // Something is misaligned, so we have to use the slow but sure method
+
+ int by = 0;
+
for (int dy = y; dy < y + h; dy++) {
- u16* dest = bg + (dy * (stride >> 1)) + (x >> 1);
-
- DC_FlushRange(src, w << 1);
- DC_FlushRange(dest, w << 1);
- dmaCopyHalfWords(3, src, dest, w);
-
- src += pitch >> 1;
+ u8* dest = ((u8 *) (bg)) + (dy * stride) + x;
+ u8* destSub = ((u8 *) (bgSub)) + (dy * 512) + x;
+ u8* src = (u8 *) buf + (pitch * by);
+
+ u32 dx;
+
+ u32 pixelsLeft = w;
+
+ if (MISALIGNED16(dest)) {
+ // Read modify write
+
+ dest--;
+ u16 mix = *((u16 *) dest);
+
+ mix = (mix & 0x00FF) | (*src++ << 8);
+
+ *dest = mix;
+ *destSub = mix;
+
+ dest += 2;
+ destSub += 2;
+ pixelsLeft--;
+ }
+
+ // We can now assume dest is aligned
+ u16* dest16 = (u16 *) dest;
+ u16* destSub16 = (u16 *) destSub;
+
+ for (dx = 0; dx < pixelsLeft; dx+=2) {
+ u16 mix;
+
+ mix = *src + (*(src + 1) << 8);
+ *dest16++ = mix;
+ *destSub16++ = mix;
+ src += 2;
+ }
+
+ pixelsLeft -= dx;
+
+ // At the end we may have one pixel left over
+
+ if (pixelsLeft != 0) {
+ u16 mix = *dest16;
+
+ mix = (mix & 0x00FF) | ((*src++) << 8);
+
+ *dest16 = mix;
+ *destSub16 = mix;
+ }
+
+ by++;
+
}
-
+
+// consolePrintf("Slow method used!\n");
+
+
} else {
- for (int dy = y; dy < y + h; dy++) {
- u16* dest1 = bg + (dy * (stride >> 1)) + (x >> 1);
- u16* dest2 = bgSub + (dy << 8) + (x >> 1);
+
+ // Stuff is aligned to 16-bit boundaries, so it's safe to do DMA.
+
+ u16* src = (u16 *) buf;
+
+ if (DS::getKeyboardEnable()) {
+
+ for (int dy = y; dy < y + h; dy++) {
+ u16* dest = bg + (dy * (stride >> 1)) + (x >> 1);
- DC_FlushRange(src, w << 1);
- DC_FlushRange(dest1, w << 1);
- DC_FlushRange(dest2, w << 1);
-
- dmaCopyHalfWords(3, src, dest1, w);
- dmaCopyHalfWords(3, src, dest2, w);
-
- src += pitch >> 1;
- }
- }
+ DC_FlushRange(src, w << 1);
+ DC_FlushRange(dest, w << 1);
+ dmaCopyHalfWords(3, src, dest, w);
-// consolePrintf("Done\n");
+ while (dmaBusy(3));
+
+ src += pitch >> 1;
+ }
+
+ } else {
+ for (int dy = y; dy < y + h; dy++) {
+ u16* dest1 = bg + (dy * (stride >> 1)) + (x >> 1);
+ u16* dest2 = bgSub + (dy << 8) + (x >> 1);
+
+ DC_FlushRange(src, w << 1);
+ DC_FlushRange(dest1, w << 1);
+ DC_FlushRange(dest2, w << 1);
+
+ dmaCopyHalfWords(3, src, dest1, w);
-
+ if ((!_frameBufferExists) || (buf == _framebuffer.pixels)) {
+ dmaCopyHalfWords(2, src, dest2, w);
+ }
+ while (dmaBusy(2) || dmaBusy(3));
+
+ src += pitch >> 1;
+ }
+ }
+ }
+// consolePrintf("Done\n");
}
void OSystem_DS::updateScreen() {
- if ((_frameBufferExists) && (DS::getIsDisplayMode8Bit()))
- {
+ if ((_frameBufferExists) && (DS::getIsDisplayMode8Bit())) {
_frameBufferExists = false;
// Copy temp framebuffer back to screen
@@ -253,6 +369,12 @@ void OSystem_DS::updateScreen() {
DS::doSoundCallback();
// DS::doTimerCallback();
DS::addEventsToQueue();
+
+ // Force back buffer usage for Nippon Safes, as it doesn't double buffer it's output
+ if (DS::getControlType() == DS::CONT_NIPPON) {
+ OSystem_DS::instance()->lockScreen();
+ OSystem_DS::instance()->unlockScreen();
+ }
}
void OSystem_DS::setShakePos(int shakeOffset) {
@@ -334,7 +456,21 @@ void OSystem_DS::warpMouse(int x, int y) {
}
void OSystem_DS::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor, int targetCursorScale) {
- DS::setCursorIcon(buf, w, h, keycolor, hotspotX, hotspotY);
+ if ((w > 0) && (w < 64) && (h > 0) && (h < 64))
+ {
+ memcpy(_cursorImage, buf, w * h);
+ _cursorW = w;
+ _cursorH = h;
+ _cursorHotX = hotspotX;
+ _cursorHotY = hotspotY;
+ _cursorKey = keycolor;
+ _cursorScale = targetCursorScale;
+ refreshCursor();
+ }
+}
+
+void OSystem_DS::refreshCursor() {
+ DS::setCursorIcon(_cursorImage, _cursorW, _cursorH, _cursorKey, _cursorHotX, _cursorHotY);
}
void OSystem_DS::addEvent(Common::Event& e) {
@@ -489,7 +625,11 @@ Common::SaveFileManager* OSystem_DS::getSavefileManager() {
if (DS::isGBAMPAvailable() && (!forceSram)) {
return &mpSaveManager;
} else {
+#ifdef GBA_SRAM_SAVE
return &saveManager;
+#else
+ return NULL;
+#endif
}
}
diff --git a/backends/platform/ds/arm9/source/osystem_ds.h b/backends/platform/ds/arm9/source/osystem_ds.h
index 8c8d661ad8..16c8f41491 100644
--- a/backends/platform/ds/arm9/source/osystem_ds.h
+++ b/backends/platform/ds/arm9/source/osystem_ds.h
@@ -52,17 +52,32 @@ protected:
Common::Event eventQueue[96];
int queuePos;
+#ifdef GBA_SRAM_SAVE
DSSaveFileManager saveManager;
+#endif
GBAMPSaveFileManager mpSaveManager;
DSAudioMixer* _mixer;
DSTimerManager* _timer;
Graphics::Surface _framebuffer;
bool _frameBufferExists;
-
+ bool _graphicsEnable;
static OSystem_DS* _instance;
+
+ u16 _palette[256];
+ u16 _cursorPalette[256];
+
+ u8 _cursorImage[64 * 64];
+ uint _cursorW;
+ uint _cursorH;
+ int _cursorHotX;
+ int _cursorHotY;
+ byte _cursorKey;
+ int _cursorScale;
+
Graphics::Surface* createTempFrameBuffer();
+ bool _disableCursorPalette;
public:
typedef void (*SoundProc)(byte *buf, int len);
@@ -159,7 +174,16 @@ public:
virtual void clearAutoComplete();
virtual void setCharactersEntered(int count);
+ u16 getDSPaletteEntry(u32 entry) { return _palette[entry]; }
+ u16 getDSCursorPaletteEntry(u32 entry) { return !_disableCursorPalette? _cursorPalette[entry]: _palette[entry]; }
+
+ virtual void setCursorPalette(const byte *colors, uint start, uint num);
+
+ virtual void disableCursorPalette(bool dis) { _disableCursorPalette = dis; refreshCursor(); }
+
FilesystemFactory *getFilesystemFactory();
+
+ void refreshCursor();
};
static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
diff --git a/backends/platform/ds/arm9/source/portdefs.h b/backends/platform/ds/arm9/source/portdefs.h
index de7a5795f5..16f3d8cc9b 100644
--- a/backends/platform/ds/arm9/source/portdefs.h
+++ b/backends/platform/ds/arm9/source/portdefs.h
@@ -81,7 +81,10 @@ void consolePrintf(const char* s, ...);
#define ITCM_DATA __attribute__((section(".itcm")))
-
+// Since I can't change the engine at the moment (post lockdown) this define can go here.
+// This define changes the mouse-relative motion which doesn't make sense on a touch screen to
+// a more conventional form of input where the menus can be clicked on.
+#define LURE_CLICKABLE_MENUS
//#include "common/array.h"
//#include "common/str.h"
diff --git a/backends/platform/ds/arm9/source/ramsave.cpp b/backends/platform/ds/arm9/source/ramsave.cpp
index 30c3a06721..a9f4e3d2fc 100644
--- a/backends/platform/ds/arm9/source/ramsave.cpp
+++ b/backends/platform/ds/arm9/source/ramsave.cpp
@@ -19,7 +19,9 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
- // Save in order 1,2,3,4,larger 2,5
+#ifdef GBA_SRAM_SAVE
+
+
#include "ramsave.h"
#include "nds.h"
#include "compressor/lz.h"
@@ -237,7 +239,7 @@ uint32 DSSaveFile::write(const void *buf, uint32 size) {
return size;
}
-bool DSSaveFile::matches(char* prefix, int num) {
+bool DSSaveFile::matches(const char *prefix, int num) {
char str[16];
if (isValid()) {
sprintf(str, "%s%02d", prefix, num);
@@ -251,7 +253,7 @@ bool DSSaveFile::matches(char* prefix, int num) {
}
}
-bool DSSaveFile::matches(char* filename) {
+bool DSSaveFile::matches(const char *filename) {
if (isValid()) {
return !strcmp(save.name, filename);
} else {
@@ -532,3 +534,5 @@ int DSSaveFileManager::getExtraData() {
return 0;
}
}
+
+#endif
diff --git a/backends/platform/ds/arm9/source/ramsave.h b/backends/platform/ds/arm9/source/ramsave.h
index 98430b9d11..034e957b7f 100644
--- a/backends/platform/ds/arm9/source/ramsave.h
+++ b/backends/platform/ds/arm9/source/ramsave.h
@@ -78,8 +78,8 @@ public:
bool isValid() { return save.isValid; }
bool isTemp() { return isTempFile; }
- bool matches(char* prefix, int num);
- bool matches(char* filename);
+ bool matches(const char *prefix, int num);
+ bool matches(const char *filename);
void clearData();
void compress();
diff --git a/backends/platform/ds/arm9/source/touchkeyboard.cpp b/backends/platform/ds/arm9/source/touchkeyboard.cpp
index 11832f4e3a..85f80fac92 100644
--- a/backends/platform/ds/arm9/source/touchkeyboard.cpp
+++ b/backends/platform/ds/arm9/source/touchkeyboard.cpp
@@ -402,6 +402,23 @@ void createKeyEvent(int keyNum, Common::Event& event)
}
}
+void releaseAllKeys() {
+ for (int r = 0; r < DS_NUM_KEYS; r++) {
+ if (keys[r].pressed) {
+ DS::setKeyHighlight(r, false);
+
+ OSystem_DS* system = OSystem_DS::instance();
+
+ Common::Event event;
+ createKeyEvent(r, event);
+ event.type = Common::EVENT_KEYUP;
+ system->addEvent(event);
+
+ keys[r].pressed = false;
+ }
+ }
+}
+
void addKeyboardEvents() {
bool resetShift = false;
@@ -446,7 +463,7 @@ void addKeyboardEvents() {
// consolePrintf("Key: %d\n", r);
if ((keys[r].character == Common::KEYCODE_INVALID)) {
// Close button
- DS::closed = true;
+ //DS::closed = true;
} else {
createKeyEvent(r, event);
}
@@ -492,9 +509,14 @@ void addKeyboardEvents() {
OSystem_DS* system = OSystem_DS::instance();
Common::Event event;
- createKeyEvent(r, event);
- event.type = Common::EVENT_KEYUP;
- system->addEvent(event);
+ if ((keys[r].character == Common::KEYCODE_INVALID)) {
+ // Close button
+ DS::closed = true;
+ } else {
+ createKeyEvent(r, event);
+ event.type = Common::EVENT_KEYUP;
+ system->addEvent(event);
+ }
keys[r].pressed = false;
diff --git a/backends/platform/ds/arm9/source/touchkeyboard.h b/backends/platform/ds/arm9/source/touchkeyboard.h
index 8a5fc728ce..91efbc1e9a 100644
--- a/backends/platform/ds/arm9/source/touchkeyboard.h
+++ b/backends/platform/ds/arm9/source/touchkeyboard.h
@@ -40,6 +40,7 @@ bool getKeyboardClosed();
void addAutoComplete(char* word);
void clearAutoComplete();
void setCharactersEntered(int count);
+void releaseAllKeys();
}