3.0 beta1 release candidate

This commit is contained in:
Chris Danford
2002-07-03 21:27:26 +00:00
parent c6f4421f32
commit 9b546bb721
28 changed files with 473 additions and 464 deletions
+152 -146
View File
@@ -1,60 +1,57 @@
____ __
 ____ __
/\ _`\ /\ \__ /'\_/`\ __
\ \,\L\_\ \ ,_\ __ _____ /\ \ __ ___ /\_\ __
\/_\__ \\ \ \/ /'__`\/\ '__`\ \ \__\ \ /'__`\ /' _ `\/\ \ /'__`\
 \/_\__ \\ \ \/ /'__`\/\ '__`\ \ \__\ \ /'__`\ /' _ `\/\ \ /'__`\
/\ \L\ \ \ \_/\ __/\ \ \L\ \ \ \_/\ \/\ \L\.\_/\ \/\ \ \ \/\ \L\.\_
\ `\____\ \__\ \____\\ \ ,__/\ \_\\ \_\ \__/.\_\ \_\ \_\ \_\ \__/.\_\
\/_____/\/__/\/____/ \ \ \/ \/_/ \/_/\/__/\/_/\/_/\/_/\/_/\/__/\/_/
\ \_\
\/_/
__ __
/'__`\ /'__`\
/\_\L\ \ /\ \/\ \
\/_/_\_<_ \ \ \ \ \
/\ \L\ \__\ \ \_\ \
\ \____/\_\\ \____/
\/___/\/_/ \/___/
__ __
 /'__`\ /'__`\
/\_\L\ \ /\ \/\ \
\/_/_\_<_ \ \ \ \ \
/\ \L\ \__\ \ \_\ \
\ \____/\_\\ \____/
\/___/\/_/ \/___/
(c)2001-2002, StepMania team
http://www.stepmania.com
************************************************************
Readme Table of Contents
Table of Contents
************************************************************
1. About StepMania
2. Minimum Requirements
3. DirectX
4. Installation
5. How StepMania Loads Songs
5. Connecting Dance Pads
6. Compatibility Issues
7. FAQ / Troubleshooting
8. StepMania Packages - .smzip
9. Questions, Bugs, Suggestions, and Help
11. Song and Notes File Formats
12. Game and Style File Formats
13. Building StepMania from Source Code
14. Version History
1. About StepMania
2. Minimum Requirements
3. DirectX
4. Installation
5. Controls
6. How StepMania Loads Songs
7. Connecting Dance Pads
8. Compatibility Issues
9. FAQ / Troubleshooting
10. StepMania Packages - .smzip
11. Questions, Bugs, Suggestions, and Help
12. The StepMania Editor
13. The .SM File Format
14. Building StepMania from CVS Source
15. Version History
************************************************************
1. About StepMania
1. About StepMania
************************************************************
StepMania game system is capable of playing many game types. Currently, it supports games Dance Dance Revolution and Pump It Up, with future support for EZ 2 Dancer, BeatMania, Guitar Freaks, Drum Mania, Para Para Paradise and more.
StepMania game system is capable of playing many game types. Currently, it supports games Dance Dance Revolution and Pump It Up, with future support for EZ 2 Dancer, BeatMania, Guitar Freaks, DrumMania, Para Para Paradise and more.
************************************************************
2. Minimum Requirements
2. Minimum Requirements
************************************************************
* Windows 98, Windows ME, Windows 2000, or Windows XP.
* Required: Pentium II, Pentium III, Celeron, Athlon, or compatible processor, 266MHz minimum (400 MHz highly recommended).
* 64 MB of RAM.
* 75 MB of hard drive space.
* 16-bit video card (24-bit or higher recommended).
* Video card that supports High Color (16-bit color).
* Video card that supports High Color (16-bit color) and has 16MB video RAM.
* DirectX 8.1 compatible video card with drivers.
* DirectX 8.1 compatible sound card with drivers.
* DivX 5 video codec (for movie visualizations).
@@ -72,59 +69,44 @@ DirectX 8.1 is required before installing StepMania. If DirectX 8.1 is not insta
To install StepMania, download the file stepmania3.exe to a known location on your hard drive, then double-click the file icon to begin the installation. The installer automatically remove an older version of the program if one is present. The default installation directory is 'C:\Program Files\StepMania'.
************************************************************
5. How StepMania Loads Songs
5. Controls
************************************************************
StepMania supports two completely independent directory structures for organizing your songs:
The StepMania directory structure, which resides in the folder called "Songs"
The DWI's directory structure, which resides in the folder called "DWI support".
The organization method you use is up to you. The StepMania directory structure gains many advantages from the fact that all files needed to play a song reside in a single directory.
Sharing a song is as easy as zipping up the directory.
Remove a song by delete the song directory.
Change the group of a song just by moving the whole directory.
The advantage of the DWI directory structure is that it's compatible with the very popular and very good simulator called Dance With Intensity. The disadvantage of this structure is that the files needed to play a song are spread over 3 different directories, making songs difficult to manage.
Use the "Config Key/Joy" option from the Title Menu to configure your keyboad or dance pad.
STEPMANIA DIRECTORY STRUCTURE
example:
StepMania
Songs
3rd Mix
Dam Dariram
Turn Me On
4th Mix
B4U
One Two
Any time:
* F4 = toggle fullscreen
* F5 = toggle detail
Inside the "Songs" folder you must create group folders for organizing your songs. StepMania initially comes with one group folder called "Default". Inside the group folders are your song folders. Each song folder contains all of the files needed to play a song:
Background (optional) - Can be in PNG, JPG, GIF, or BMP format. No restrictions on dimensions, but looks best with a 4:3 aspect ratio. Be aware that the file will be stretched to the entire screen while dancing.
Banner (optional) - Can be in PNG, JPG, GIF, or BMP format. No restrictions on dimensions, but the most common size is 192x55.
Music (required) - Can be in MP3, WAV, or OGG format.
Steps file(s) (required) - For any given song, you can use either multiple BMS files or a single DWI file.
DWI DIRECTORY STRUCTURE
DWI directory support means gives StepMania 100% compatibly with the simulator Dance With Intensity.
If you want to copy all of your songs from DWI into StepMania, go to your DWI program folder and copy "Backgrounds", "Banners", "Music", and "DWIs" into the StepMania folder called "DWI support".
If you want to copy your songs back into DWI, take all of the folders inside StepMania's folder called "DWI support" and copy them back into your DWI program folder.
If you some zipped DWI song files that you would like to use with StepMania, just unzip them into the StepMania folder "DWI support".
Inside the "DWI support" folder, there are 4 directories:
Backgrounds (optional) - For StepMania, these files can be in PNG, JPG, GIF, or BMP format. To be compatible with DWI though, they must be PNG and have dimensions 320x240.
Banners (optional) - For StepMania, these files can be in PNG, JPG, GIF, or BMP format. To be compatible with DWI though, they must be PNG, be rotated 45 degrees counter-clockwise and have dimensions 175x175. (Note that StepMania will automatically detect and correct the rotation of any DWI-formatted banners.
Music (required) - For StepMania, these files can be in PNG, JPG, GIF, or BMP format. To be compatible with DWI though, they must be PNG, be rotated 45 degrees counter-clockwise and have dimensions 175x175. (Note that StepMania will automatically detect and correct the rotation of any DWI-formatted banners.
DWI file (required) - See the Dance With Intensity readme for more information on the DWI file format.
Goals of a new file format:
 support multiple game types
In menus:
* Arrow keys navigate menus
* Enter = Start, Escape = Back
In gameplay:
* F11 = decrease offset
* F12 = increase offset
************************************************************
5. Connecting Dance Pads
6. How StepMania Loads Songs
************************************************************
All song files for a specific song (data file, music file, banner, background) must reside in a single folder. This folder must have the following path:
Songs/<group folder>/<song folder>/
For example, the song B4U may consist of the following files:
Songs/Dance Dance Revolution 4th Mix/B4U/b4u.dwi
Songs/Dance Dance Revolution 4th Mix/B4U/b4u.mp3
Songs/Dance Dance Revolution 4th Mix/B4U/b4u-banner.png
Songs/Dance Dance Revolution 4th Mix/B4U/b4u.png
************************************************************
7. Connecting Dance Pads
************************************************************
There are several devices that allow you to connect PlayStation dance pads to your PC.
* Not recommended: generic PlayStation->USB converter
Using a generic PlayStation->USB converter is not recommended to play any dancing game on the PC. The vast majority of these converters are not capable of registering simultaneous presses of Left+Right or Up+Down. This restriction will cause the player to miss many notes where two buttons must be hit simultaneously.
@@ -140,7 +122,7 @@ PlayStation->Parallel converters do not have the simultaneous button problem tha
For Windows 98 and Windows Me users, the recommended driver is “DirectPad Pro 5.0 for Win9x”. For Windows 2000 and Windows XP, the recommended drivers are NTPad XP 1.x. Both of these drivers can be downloaded from Aldos web site: http://www.aldostools.com/dpad.html
************************************************************
6. Compatibility Issues
8. Compatibility Issues
************************************************************
Some video card/driver combinations have visual errors when running StepMania. If you experience any visual errors, please visit your video card manufacturer's web site and download the latest Direct3D 8.1 drivers. Below is a list of known issues that are thought to be video card driver bugs:
@@ -159,7 +141,7 @@ Explanation: These problems are most often video card driver bugs. Please upgra
************************************************************
7. FAQ / Troubleshooting
9. FAQ / Troubleshooting
************************************************************
* The error "Cannot find Dinput8.dll" appears when launching the game.
@@ -171,36 +153,37 @@ You need to download DirectX 8.1. http://www.microsoft.com/directx
Some very old sound cards do not support sound playback rates that are greater than the original sample rate. This problem is likely to be corrected by newer sound card drivers.
* StepMania reports “Direct3D Create Device failed”.
This error means that your video card or drivers do not support Direct3D 8. Download the latest drivers for your video card. If your video card is older than 2 or 3 years, Direct3D 8 drivers may not be available. Sorry.
* Im looking to purchase a video card. What works well with StepMania?
Just about any video card manufactured in the last year will run StepMania flawlessly at 60 frames per second. I recommend any card with an nVidia GeForce chip or an ATI Radeon chip.
* How can I improve performance with my existing video card
1. Install the latest drivers for your video card.
2. Press F5 in the game to toggle between high detail and low detail modes.
************************************************************
8. StepMania Packages - .smzip
10. StepMania Packages - .smzip
************************************************************
The StepMania package format was created to make the distribution of songs and other add-ons very easy. StepMania package files have the extension '.smzip' and can be installed by double-clicking the .smzip file.
The StepMania package format was created to make the distribution of songs and other add-ons very easy.  StepMania package files have the extension '.smzip' and can be installed by double-clicking the .smzip file.
A StepMania package is 'installed' by extracting all files in the package to the StepMania program directory. This allows songs, courses, themes, and visualizations to all be installed by the Package Manager.
The file format of an .smzip file is actually the PK-Zip standard. This means you can rename any .smzip file to have the extension '.zip', and then open the file in any compression package (e.g. WinZip).
The file format of an .smzip file is actually the PK-Zip standard.  This means you can rename any .smzip file to have the extension '.zip', and then open the file in any compression package (e.g. WinZip).
The StepMania Package Manager (smpackage.exe) can also create song packages for you. Simply launch the Package Manager (Start Menu->Programs->StepMania->Package Manager), click the song you want to create a package for, click the Export button, and a .smzip package will be placed on your desktop.
************************************************************
9. Questions, Bugs, Suggestions, and Help
11. Questions, Bugs, Suggestions, and Help
************************************************************
If you have a question or problem about StepMania, please try asking your question to the StepMania message board. A link is available from the StepMania web site http://www.stepmania.com.
If you have found a bug, please file a bug report into the SourceForge bug tracking system (http://sourceforge.net/tracker/?group_id=37892&atid=421366). This will allow the developers to track and fix bugs much more efficiently.
If you have found a bug, please file a bug report into the SourceForge bug tracking system (http://sourceforge.net/tracker/?group_id=37892&atid=421366).  This will allow the developers to track and fix bugs much more efficiently.  
* In a bug report, please specify your video card brand and model, and your OS version.
* PLEASE, PLEASE enter your e-mail address on the bug reports. In many cases, we need more information from the bug reporter.
@@ -209,104 +192,129 @@ Please use SourceForge's feature request system to enter new feature requests (h
If you would like to help with development of StepMania, please send an email to the StepMania developers list ([email protected]) or to Chris ([email protected]).
************************************************************
12. The StepMania editor
************************************************************
The StepMania editor allows you to edit, record, synchronize, and play back note patterns. Current, it support saving only in the .SM format. If you save a song that was originally in DWI or BMS format, the old DWI and BMS files will be renamed to have ".old" appended to avoid conflicts when the song is next loaded. All of the commands are listed along the left side of the screen.
************************************************************
13. The .SM file format
************************************************************
The .SM song file format was created to be one file format that supports all game types that StepMania can play (dance, pump, beat, guitar, etc). The .SM file syntax is identical to DWI except for some different tags and meanings. These are a list of all supported tags.
All images can be in png, gif, jpg, or bmp format. All sounds can be in ogg, mp3, or wav format.
#TITLE:...; - The "main title" of the song.
#SUBTITLE:...; - This text will appear underneath the main title of the song on the Select Music screen. e.g. "-Dirty Mix-", "(remix)".
#ARTIST:...; - The artist of the song.
#CREDIT:...; - Give yourself some credit here for creating a wonderful song.
#BPM:...; - BPM of the music
#BANNER:...; - The file name of the banner image. e.g. "b4u-banner.png". This image must reside in the song folder.
#BACKGROUND:...; - The file name of the background image. e.g. "b4u-bg.png". This image must reside in the song folder.
#CDTITLE:...; - The file name of the spinning CD logo. e.g. "b4u-cdtitle.png". This image must reside in the song folder.
#MUSIC:...; - The file name of the music file. e.g. "b4u.mp3". This image must reside in the song folder.
#MUSICBYTES:...; - The size in bytes of the music file that this song was last synchronized with. A "Song may be out of synch" warning will be displayed if the value of this tag does not match the actual size of the music file.
#OFFSET:...; - The time in seconds at which beat 0 occurs in the music. This is specified as a floating point value. e.g. "2.34".
#SAMPLESTART:...; - The time in seconds to start the music sample that plays on the Select Music screen. This is specified as a floating point value. e.g. "32.34".
#SAMPLELENGTH:...; - The time in seconds let the sample music play after starting. This is specified as a floating point value. e.g. "32.34". Note that in the last 1 second of playing the music will fade out.
#FREEZE:...; - A value of the format "beat=sec". Indicates that at 'beat', the motion of the arrows should stop for "sec" seconds. Both of these values are specified as floating point values. Multiple freezes can be given by separating them with commas. e.g. "60=2.23,80=1.12".
#BPMS:...; - A value of the format "beat=bpm". Indicates that at 'beat', the speed of the arrows will change to "bpm". Both of these values are specified as floating point values. You must specifiy a BPM value for beat 0. Multiple freezes can be given by separating them with commas. e.g. "0=160,120=80".
Each pattern of steps for different modes have the same basic format:
#NOTES:(NotesType):(Description):(DifficultyClass):(DifficultyMeter):(RadarValues):(NoteData);
NotesType: Must be one of the currently supported types in StepMania: "dance-single", "dance-double", "dance-couple", "dance-solo", "pump-single", "pump-double".
Description: This will be displayed on the gameplay screen. This can be any text, but is most commonly "Basic", "Another", "Trick", "Standard", "SSR", "Maniac", "Heavy", or "Challenge".
DifficultyClass: This value must be "easy", "medium", or "hard". These values correspond the levels of difficulty on the Select Difficulty screen.
DifficultyMeter: The difficulty of these notes as a bar rating. The value must be an integer between 1 and 10.
RadarValues: The values that will be displayed on the Groove Radar as floats between 0.00 and 1.00. The 5 values must be separated by commas, and are specified in the order: "stream,voltage,air,freeze,chaos". For MAX300, these values are "0.95,0.98,0.22,0.12,0.13". These values will automatically be written when you save the song in the StepMania editor, but you may edit the .SM file afterward to tweak them.
NoteData:
, // measure 32
1000
0000
0000
0001
0000
0000
1000
0000
, // measure 33
0010
0100
0010
0000
************************************************************
11. Song and Notes File Formats
14. Building StepMania from CVS source
************************************************************
very strict syntax
trivial to parse
human readable notes
Analysis of BMS:
+ support for an arbitrary number of note types through “tracks”
+ can define couple and double patterns without having two blocks of notes
+/- note format is pretty human readable (better than DWI anyway)
+ supports more than 2 simultaneous notes (required for some game types)
- redefines song attributes in every file
- not a strict file format
- has confusing definitions for “offset”
- doesnt support freezes
- terrible way of defining hold notes (run of 32nd notes)
Analysis of DWI:
+ more strict file format than BMS
+ defines song attributes only once
+ great way of defining BPM changes and freezes
- notes are not human readable (especially with escape sequences like “04{300500}54”
- bad way of defining hold notes (especially for overlapping holds like Exotic Ethnic double Maniac)
- no support for an arbitrary number of note types (doesnt even handle 6 panel DDR well)
- requires two blocks of notes for styles like couple and double (related to “no support for an arbitrary number of note types”)
************************************************************
12. .SM File Format
************************************************************
************************************************************
13. Building StepMania from Source Code
************************************************************
CVS is the repository that manages the StepMania source code. Our CVS server is graciously provided by SourceForge. You can get the absolute-latest bleeding edge updates to StepMania by taking the source from CVS. Below are instructions on how to configure your computer to download source code from CVS and complile the source into a working executable.
* Step 1: Install and configure Visual C++
The StepMania source can currently be built only on Microsoft Visual C++ 6.0. Installing Visual C++ or Visual Studio with all the default options is sufficient. Also, this is a good time to grab the latest Service Pack from Microsoft.
The StepMania source can currently be built with Microsoft Visual C++ 6.0 or Visual C++ .Net. Installing Visual C++ or Visual Studio with all the default options is sufficient.
* Step 2: Install the Direct X 8.1 SDK
The DirectX 8.1 SDK is a free download from Microsoft available here. Using the default installation path ("C:\DXSDK") works well.
* Step 3: Build the DirectShow baseclasses and configure MSVC paths
StepMania's movie texture support depends on a DirectShow wrapper library included with the DirectX SDK. You must build this library and add it to your MSVC paths before compiling StepMania.
Open the project "C:\DXSDK\samples\Multimedia\DirectShow\BaseClasses" and build in both Debug and Release modes.
- Click Tools->Options.
- Click the Directories tab.
- In the Show directories for: dropdown, choose Include files.
- Click the New toolbar button and add a new entry for C:\DXSDK\samples\Multimedia\DirectShow\BaseClasses.
- In the Show directories for: dropdown, choose Library files.
- Click the New toolbar button and add a new entry for C:\DXSDK\samples\Multimedia\DirectShow\BaseClasses\Debug.
- Click the New toolbar button and add a new entry for C:\DXSDK\samples\Multimedia\DirectShow\BaseClasses\Release.
- IMPORTANT: Using the mouse, drag the last two library paths you just added to the top of the list. If you don't do this, you'll get linking errors that look like this: unresolved external symbol class CFactoryTemplate * g_Templates
The DirectX 8.1 SDK is a free (but large) download from Microsoft (link here). Install it using all the default settings. The SDK installer will configure Visual C++ with the correct paths needed to find the DirectX 8.1 libraries and headers.
* Step 3: Install WinCVS
CVS is required to "checkout" the latest versions from the SourceForge-hosted code repository. Download the latest stable version of WinCVS from here, and choose the default installation options.
IMPORTANT: Now, open and close WinCVS once. This will let CVS refresh its registry entries, which is required for the next step...
A CVS client is required to "checkout" the course from the CVS server. Download version 1.2 of WinCVS here - http://www.cvsgui.org.
IMPORTANT: Now, open and close WinCVS once. This will cause WinCVS to create registry entries, which is required for the next step...
* Step 4: Use SourceForge Setup to install SSH and configure CVS
* Step 4: Use SourceForge Setup to install SSH and configure WinCVS
IMPORTANT: If you are using Windows 2000 or Windows XP, you must unhide the file c:\autoexec.bat. If you don't unhide this file, SourceForge Setup won't be able to add environment variables for you.
A small utility called SourceForge Setup will greatly simplify the steps needed to configure WinCVS and SSH. Download the program from here, choose the default installation options, and answer the questions as follows:
A small utility called SourceForge Setup will greatly simplify the steps needed to configure SSH and WinCVS. Download SourceForge Setup here - link here. Use the following settings when prompted by SF Setup:
- Unpack SSH directory: c:\ssh
- SSH install direcotory: c:\ssh
- Your home directory: c:\ssh
- Your SourceForge user name: -yourusername-
- Name of the project: stepmania
- The directory where you will be keeping checked out project sources: c:\stepmania
IMPORTANT: You must restart after running SourceForge Setup so that the new environment variables take effect.
If you need more help, a HOWTO is available here.
IMPORTANT: If you are using Windows 2000 or Windows XP SourceForge Setup will not correctly write changes to the c:\autoexec.bat file. Verify that the following lines are present after you run SF Setup:
* DONE! Enjoy staying on the bleeding edge of StepMania releases!
rem SourceForge setup stuff
SET PATH=%PATH%;c:\ssh
SET HOME=c:\ssh
If you're interested in helping in any capacity, please join the StepMania developers mailing list.
IMPORTANT: You must restart after running SF Setup so that the new environment variables take effect.
* DONE! Enjoy staying on the bleeding edge of StepMania releases! 
************************************************************
14. Version History
15. Version History
************************************************************
------------------------Version 3.00 beta 1------------------
NEW FEATURE: Roulette
NEW FEATURE: AutoPlay (selectable from Game Options screen)
NEW FEATURE: Read Delight BMS 0.5 (hold notes, freezes, and new BPM changes supported)
NEW FEATURE: Editor - edit, record, playback, and synchronize from one screen
NEW FEATURE: Oni Nonstop Challenge (not finished)
NEW FEATURE: "Judge Window" option to adjust difficulty of step judging
NEW FEATURE: Song data cache for faster loading.
NEW FEATURE: Groove Radar
NEW FEATURE: Dark Mode (selectable from Player Options screen)
NEW FEATURE (partially complete): Pump It Up support
NEW FEATURE (partially complete): Background Animations (defaut animations go in BGAnimations dir)
------------------------Version 2.90-------------------------
CHANGE: Ogg Vorbis music support re-enabled
NEW FEATURE: Game skins (selectable from Player Options screen)
NEW FEATURE: Note Skins (selectable from Player Options screen)
------------------------Version 2.50-------------------------
NEW FEATURE: New multi game compatible .sm file format.
@@ -314,7 +322,6 @@ CHANGE: "Graphic Detail" presets
BUG FIX: Installer DirectX check now works
NEW FEATURE: Aracde and Free Play game modes
------------------------Version 1.90-------------------------
OPTIMIZATION: Major speedup to BitmapText loading
CHANGE: Menus changes to accomodate MAX-style menus
@@ -326,10 +333,9 @@ NEW FEATURE: Select Group menu
NEW FEATURE: Edit / Record / Playback
NEW FEATURE: Support for DWI solo notes in DWI reader
------------------------Version 1.65-------------------------
BUG FIX: Statistics now save and load correctly
BUG FIX: Less jitter while dancing on slower computers
BUG FIX: Better framerate during gameplay
------------------------Version 1.64-------------------------
NEW FEATURE: Group banners on Select Music screen. Just put a banner in the group folder.
+8 -7
View File
@@ -61,13 +61,14 @@ bool Background::LoadFromSong( Song* pSong, bool bDisableVisualizations )
//
// load song background
//
CString sBackgroundMoviePath;
if( pSong->HasBackgroundMovie() )
{
m_sprSongBackground.Load( pSong->GetBackgroundMoviePath() );
m_sprSongBackground.SetZoomY( -1 ); // flip
}
else if( pSong->HasBackground() )
// CString sBackgroundMoviePath;
// if( pSong->HasBackgroundMovie() )
// {
// m_sprSongBackground.Load( pSong->GetBackgroundMoviePath() );
// m_sprSongBackground.SetZoomY( -1 ); // flip
// }
// else
if( pSong->HasBackground() )
{
m_sprSongBackground.Load( pSong->GetBackgroundPath(), false, 2, 0, true );
}
+3 -1
View File
@@ -79,8 +79,10 @@ void Course::LoadFromCRSFile( CString sPath, CArray<Song*,Song*> &apSongs )
CString sSongDir = arrayValueTokens[1];
CString sNotesDescription = arrayValueTokens[2];
int i;
Song* pSong = NULL;
for( int i=0; i<apSongs.GetSize(); i++ )
for( i=0; i<apSongs.GetSize(); i++ )
if( 0 == stricmp(apSongs[i]->m_sSongDir, sSongDir) )
pSong = apSongs[i];
+15 -13
View File
@@ -102,7 +102,7 @@ inline NoteType GetNoteType( int iNoteIndex )
return NOTE_12TH;
else if( iNoteIndex % (ELEMENTS_PER_MEASURE/16) == 0)
return NOTE_16TH;
ASSERT(0);
// ASSERT(0);
return NOTE_INVALID;
};
@@ -337,18 +337,6 @@ inline Game StyleToGame( Style s )
struct PlayerOptions
{
PlayerOptions() {
m_fArrowScrollSpeed = 1.0f;
m_EffectType = EFFECT_NONE;
m_AppearanceType = APPEARANCE_VISIBLE;
m_TurnType = TURN_NONE;
m_bLittle = false;
m_bReverseScroll = false;
m_ColorType = COLOR_ARCADE;
m_bHoldNotes = true;
m_DrainType = DRAIN_NORMAL;
};
float m_fArrowScrollSpeed;
enum EffectType { EFFECT_NONE=0, EFFECT_BOOST, EFFECT_WAVE, EFFECT_DRUNK, EFFECT_DIZZY, EFFECT_SPACE };
EffectType m_EffectType;
@@ -361,9 +349,23 @@ struct PlayerOptions
enum ColorType { COLOR_ARCADE=0, COLOR_NOTE, COLOR_FLAT, COLOR_PLAIN };
ColorType m_ColorType;
bool m_bHoldNotes;
bool m_bDark;
enum DrainType { DRAIN_NORMAL=0, DRAIN_NO_RECOVER, DRAIN_SUDDEN_DEATH };
DrainType m_DrainType;
PlayerOptions() {
m_fArrowScrollSpeed = 1.0f;
m_EffectType = EFFECT_NONE;
m_AppearanceType = APPEARANCE_VISIBLE;
m_TurnType = TURN_NONE;
m_bLittle = false;
m_bReverseScroll = false;
m_ColorType = COLOR_ARCADE;
m_bHoldNotes = true;
m_bDark = false;
m_DrainType = DRAIN_NORMAL;
};
CString GetString()
{
CString sReturn;
+3 -1
View File
@@ -32,7 +32,6 @@ void GrayArrowRow::Load( PlayerNumber pn, StyleDef* pStyleDef, PlayerOptions po
m_iNumCols = pStyleDef->m_iColsPerPlayer;
// init arrow rotations
for( int c=0; c<m_iNumCols; c++ )
{
m_GrayArrow[c].Load( GAMEMAN->GetPathToGraphic(pn, c, GRAPHIC_RECEPTOR) );
@@ -54,6 +53,9 @@ void GrayArrowRow::Update( float fDeltaTime, float fSongBeat )
void GrayArrowRow::DrawPrimitives()
{
if( m_PlayerOptions.m_bDark )
return;
for( int c=0; c<m_iNumCols; c++ )
{
// set arrow X
+3 -3
View File
@@ -142,7 +142,7 @@ void GrooveRadar::GrooveRadarValueMap::DrawPrimitives()
ActorFrame::DrawPrimitives();
// draw radar filling
const float fRadius = m_sprRadarBase.GetZoomedHeight()/2.0f;
const float fRadius = m_sprRadarBase.GetZoomedHeight()/2.0f*1.1f;
LPDIRECT3DVERTEXBUFFER8 pVB = DISPLAY->GetVertexBuffer();
LPDIRECT3DDEVICE8 pd3dDevice = DISPLAY->GetDevice();
pd3dDevice->SetTexture( 0, NULL );
@@ -173,7 +173,7 @@ void GrooveRadar::GrooveRadarValueMap::DrawPrimitives()
{
const int c = i%NUM_RADAR_CATEGORIES;
const float fDistFromCenter =
( m_fValuesOld[p][c] * (1-m_PercentTowardNew[p]) + m_fValuesNew[p][c] * m_PercentTowardNew[p] + 0.15f ) * fRadius;
( m_fValuesOld[p][c] * (1-m_PercentTowardNew[p]) + m_fValuesNew[p][c] * m_PercentTowardNew[p] + 0.07f ) * fRadius;
const float fRotation = RADAR_VALUE_ROTATION(i);
const float fX = cosf(fRotation) * fDistFromCenter;
const float fY = -sinf(fRotation) * fDistFromCenter;
@@ -196,7 +196,7 @@ void GrooveRadar::GrooveRadarValueMap::DrawPrimitives()
{
const int c = i%NUM_RADAR_CATEGORIES;
const float fDistFromCenter =
( m_fValuesOld[p][c] * (1-m_PercentTowardNew[p]) + m_fValuesNew[p][c] * m_PercentTowardNew[p] + 0.15f ) * fRadius;
( m_fValuesOld[p][c] * (1-m_PercentTowardNew[p]) + m_fValuesNew[p][c] * m_PercentTowardNew[p] + 0.07f ) * fRadius;
const float fDistFromCenterInner = fDistFromCenter-2;
const float fDistFromCenterOutter = fDistFromCenter+2;
const float fRotation = RADAR_VALUE_ROTATION(i);
+1 -1
View File
@@ -501,7 +501,7 @@ void MusicWheel::BuildWheelItemDatas( CArray<WheelItemData, WheelItemData&> &arr
if( sThisSection != sLastSection ) // new section, make a section item
{
WheelItemData &WID = arrayWheelItemDatas[iCurWheelItem++];
colorSection = (so==SORT_TITLE) ? SONGMAN->GetGroupColor(pSong->m_sGroupName) : SECTION_COLORS[iSectionColorIndex];
colorSection = (so==SORT_GROUP) ? SONGMAN->GetGroupColor(pSong->m_sGroupName) : SECTION_COLORS[iSectionColorIndex];
iSectionColorIndex = (iSectionColorIndex+1) % NUM_SECTION_COLORS;
WID.Load( TYPE_SECTION, NULL, sThisSection, NULL, colorSection );
sLastSection = sThisSection;
+27 -29
View File
@@ -27,7 +27,7 @@ NoteData::NoteData()
void NoteData::Init()
{
memset( m_TapNotes, '0', MAX_NOTE_TRACKS*MAX_TAP_NOTE_ROWS );
memset( m_TapNotes, '0', MAX_NOTE_TRACKS*MAX_TAP_NOTE_ROWS*sizeof(m_TapNotes[0][0]) );
m_iNumTracks = 0;
m_iNumHoldNotes = 0;
}
@@ -61,6 +61,12 @@ void NoteData::LoadFromSMNoteDataString( CString sSMNoteData )
CStringArray asMeasureLines;
split( sMeasureString, "\n", asMeasureLines, true ); // ignore empty is important
//ASSERT( asMeasureLines.GetSize() == 4 ||
// asMeasureLines.GetSize() == 8 ||
// asMeasureLines.GetSize() == 12 ||
// asMeasureLines.GetSize() == 16 );
for( int l=0; l<asMeasureLines.GetSize(); l++ )
{
CString &sMeasureLine = asMeasureLines[l];
@@ -78,6 +84,7 @@ void NoteData::LoadFromSMNoteDataString( CString sSMNoteData )
m_TapNotes[c][iIndex] = sMeasureLine[c];
}
}
this->Convert2sAnd3sToHoldNotes();
}
CString NoteData::GetSMNoteDataString()
@@ -709,28 +716,27 @@ float NoteData::GetStreamRadarValue( float fSongSeconds )
// density of steps
int iNumNotes = GetNumTapNotes() + GetNumHoldNotes();
float fNotesPerSecond = iNumNotes/fSongSeconds;
float fReturn = fNotesPerSecond / 10;
float fReturn = fNotesPerSecond / 7;
return min( fReturn, 1.0f );
}
float NoteData::GetVoltageRadarValue( float fSongSeconds )
{
float fAvgBPS = GetLastBeat() / fSongSeconds;
// peak density of steps
float fMaxDensityPerSecSoFar = 0;
float fMaxDensitySoFar = 0;
for( int i=0; i<MAX_BEATS; i+=16 )
const int BEAT_WINDOW = 8;
for( int i=0; i<MAX_BEATS; i+=BEAT_WINDOW )
{
int iNumNotesThisMeasure = GetNumTapNotes((float)i,(float)i+8) + GetNumHoldNotes((float)i,(float)i+8);
float fDensityThisMeasure = iNumNotesThisMeasure/2.0f;
float fDensityPerSecThisMeasure = fDensityThisMeasure / fSongSeconds;
if( fDensityPerSecThisMeasure > fMaxDensityPerSecSoFar )
fMaxDensityPerSecSoFar = fDensityPerSecThisMeasure;
int iNumNotesThisWindow = GetNumTapNotes((float)i,(float)i+BEAT_WINDOW) + GetNumHoldNotes((float)i,(float)i+BEAT_WINDOW);
float fDensityThisWindow = iNumNotesThisWindow/(float)BEAT_WINDOW;
fMaxDensitySoFar = max( fMaxDensitySoFar, fDensityThisWindow );
}
float fReturn = fMaxDensityPerSecSoFar*5;
float fReturn = fMaxDensitySoFar*fAvgBPS/10;
return min( fReturn, 1.0f );
}
@@ -745,14 +751,14 @@ float NoteData::GetAirRadarValue( float fSongSeconds )
float NoteData::GetChaosRadarValue( float fSongSeconds )
{
// count number of triplets
int iNumTriplets = 0;
int iNumChaosNotes = 0;
for( int r=0; r<MAX_TAP_NOTE_ROWS; r++ )
{
if( !IsRowEmpty(r) && IsNoteOfType(r, NOTE_12TH) )
iNumTriplets++;
if( !IsRowEmpty(r) && GetNoteType(r) >= NOTE_12TH )
iNumChaosNotes++;
}
float fReturn = iNumTriplets / fSongSeconds;
float fReturn = iNumChaosNotes / fSongSeconds * 0.5;
return min( fReturn, 1.0f );
}
@@ -767,17 +773,10 @@ float NoteData::GetFreezeRadarValue( float fSongSeconds )
void NoteData::LoadTransformed( NoteData* pOriginal, int iNewNumTracks, int iNewToOriginalTrack[] )
{
// init
for( int i=0; i<MAX_NOTE_TRACKS; i++ )
{
for( int j=0; j<MAX_TAP_NOTE_ROWS; j++ )
m_TapNotes[i][j] = '0';
}
m_iNumHoldNotes = 0;
Init();
m_iNumTracks = iNewNumTracks;
// copy tracks
for( int t=0; t<m_iNumTracks; t++ )
{
@@ -785,12 +784,11 @@ void NoteData::LoadTransformed( NoteData* pOriginal, int iNewNumTracks, int iNew
int i;
for( i=0; i<MAX_TAP_NOTE_ROWS; i++ )
m_TapNotes[t][i] = pOriginal->m_TapNotes[iOriginalTrack][i];
memcpy( m_TapNotes[t], pOriginal->m_TapNotes[iOriginalTrack], MAX_TAP_NOTE_ROWS*sizeof(m_TapNotes[0][0]) );
for( i=0; i<MAX_HOLD_NOTE_ELEMENTS; i++ )
for( i=0; i<pOriginal->m_iNumHoldNotes; i++ )
{
HoldNote hn = pOriginal->m_HoldNotes[i];
HoldNote &hn = pOriginal->m_HoldNotes[i];
if( hn.m_iTrack == iOriginalTrack )
{
hn.m_iTrack = t;
+15 -18
View File
@@ -21,14 +21,12 @@ NoteDataWithScoring::NoteDataWithScoring()
void NoteDataWithScoring::Init()
{
// init step elements
for( int t=0; t<MAX_NOTE_TRACKS; t++ )
for( int i=0; i<MAX_TAP_NOTE_ROWS; i++ )
m_TapNoteScores[t][i] = TNS_NONE;
for( int i=0; i<MAX_HOLD_NOTE_ELEMENTS; i++ )
m_HoldNoteScores[i] = HNS_NONE;
}
@@ -99,28 +97,27 @@ float NoteDataWithScoring::GetActualStreamRadarValue( float fSongSeconds )
// density of steps
int iNumSuccessfulNotes = GetNumSuccessfulTapNotes() + GetNumSuccessfulHoldNotes();
float fNotesPerSecond = iNumSuccessfulNotes/fSongSeconds;
float fReturn = fNotesPerSecond / 10;
float fReturn = fNotesPerSecond / 7;
return min( fReturn, 1.0f );
}
float NoteDataWithScoring::GetActualVoltageRadarValue( float fSongSeconds )
{
float fAvgBPS = GetLastBeat() / fSongSeconds;
// peak density of steps
float fMaxDensityPerSecSoFar = 0;
float fMaxDensitySoFar = 0;
for( int i=0; i<MAX_BEATS; i+=16 )
const int BEAT_WINDOW = 8;
for( int i=0; i<MAX_BEATS; i+=BEAT_WINDOW )
{
int iNumNotesThisMeasure = GetNumSuccessfulTapNotes((float)i,(float)i+8) + GetNumSuccessfulHoldNotes((float)i,(float)i+8);
float fDensityThisMeasure = iNumNotesThisMeasure/2.0f;
float fDensityPerSecThisMeasure = fDensityThisMeasure / fSongSeconds;
if( fDensityPerSecThisMeasure > fMaxDensityPerSecSoFar )
fMaxDensityPerSecSoFar = fDensityPerSecThisMeasure;
int iNumNotesThisWindow = GetNumSuccessfulTapNotes((float)i,(float)i+BEAT_WINDOW) + GetNumSuccessfulHoldNotes((float)i,(float)i+BEAT_WINDOW);
float fDensityThisWindow = iNumNotesThisWindow/(float)BEAT_WINDOW;
fMaxDensitySoFar = max( fMaxDensitySoFar, fDensityThisWindow );
}
float fReturn = fMaxDensityPerSecSoFar*5;
float fReturn = fMaxDensitySoFar*fAvgBPS/10;
return min( fReturn, 1.0f );
}
@@ -135,14 +132,14 @@ float NoteDataWithScoring::GetActualAirRadarValue( float fSongSeconds )
float NoteDataWithScoring::GetActualChaosRadarValue( float fSongSeconds )
{
// count number of triplets
int iNumTripletsCompleted = 0;
int iNumChaosNotesCompleted = 0;
for( int r=0; r<MAX_TAP_NOTE_ROWS; r++ )
{
if( !IsRowComplete(r) && IsNoteOfType(r, NOTE_12TH) )
iNumTripletsCompleted++;
if( !IsRowComplete(r) && GetNoteType(r) >= NOTE_12TH )
iNumChaosNotesCompleted++;
}
float fReturn = iNumTripletsCompleted / fSongSeconds;
float fReturn = iNumChaosNotesCompleted / fSongSeconds * 0.5;
return min( fReturn, 1.0f );
}
+61 -77
View File
@@ -115,6 +115,7 @@ bool Notes::LoadFromBMSFile( const CString &sPath )
LOG->WriteLine( "Notes::LoadFromBMSFile( '%s' )", sPath );
NoteData tempNoteData;
tempNoteData.m_iNumTracks = MAX_NOTE_TRACKS;
CStdioFile file;
if( !file.Open( sPath, CFile::modeRead|CFile::shareDenyNone ) )
@@ -235,78 +236,63 @@ bool Notes::LoadFromBMSFile( const CString &sPath )
if( m_NotesType == NOTES_TYPE_DANCE_SINGLE ||
m_NotesType == NOTES_TYPE_DANCE_DOUBLE ||
m_NotesType == NOTES_TYPE_DANCE_COUPLE ) // if there are 4 panels, then we have to flip the Up and Up+Right bits
m_NotesType == NOTES_TYPE_DANCE_COUPLE ) // if there are 4 panels, then the Up+Right track really contains the notes for Up
{
for( int i=0; i<MAX_TAP_NOTE_ROWS; i++ ) // for each TapNote
{
if( tempNoteData.m_TapNotes[DANCE_NOTE_PAD1_UPRIGHT][i] != '0' ) // if up+right is a step
{
tempNoteData.m_TapNotes[DANCE_NOTE_PAD1_UP][i] = tempNoteData.m_TapNotes[DANCE_NOTE_PAD1_UPRIGHT][i]; // add up
tempNoteData.m_TapNotes[DANCE_NOTE_PAD1_UPRIGHT][i] = '0'; // subtract up+right
}
if( tempNoteData.m_TapNotes[DANCE_NOTE_PAD2_UPRIGHT][i] != '0' ) // if up+right is a step
{
tempNoteData.m_TapNotes[DANCE_NOTE_PAD2_UP][i] = tempNoteData.m_TapNotes[DANCE_NOTE_PAD2_UPRIGHT][i]; // add up
tempNoteData.m_TapNotes[DANCE_NOTE_PAD2_UPRIGHT][i] = '0'; // subtract up+right
}
memcpy(
tempNoteData.m_TapNotes[DANCE_NOTE_PAD1_UP],
tempNoteData.m_TapNotes[DANCE_NOTE_PAD1_UPRIGHT],
MAX_TAP_NOTE_ROWS*sizeof(tempNoteData.m_TapNotes[0][0])
);
memcpy(
tempNoteData.m_TapNotes[DANCE_NOTE_PAD2_UP],
tempNoteData.m_TapNotes[DANCE_NOTE_PAD2_UPRIGHT],
MAX_TAP_NOTE_ROWS*sizeof(tempNoteData.m_TapNotes[0][0])
);
}
}
// we're done reading in all of the BMS values
int iNumNewTracks = NotesTypeToNumTracks( m_NotesType );
int iTransformNewToOld[MAX_NOTE_TRACKS];
CMap<int, int, int, int> mapDanceNoteToNoteDataColumn;
if( m_NotesType == NOTES_TYPE_DANCE_SINGLE )
switch( m_NotesType )
{
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0;
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 1;
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 2;
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 3;
}
else if( m_NotesType == NOTES_TYPE_DANCE_DOUBLE )
{
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0;
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 1;
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 2;
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 3;
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_LEFT] = 4;
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_DOWN] = 5;
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_UP] = 6;
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_RIGHT] = 7;
}
else if( m_NotesType == NOTES_TYPE_DANCE_COUPLE )
{
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0;
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 1;
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 2;
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 3;
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_LEFT] = 4;
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_DOWN] = 5;
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_UP] = 6;
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_RIGHT] = 7;
}
else if( m_NotesType == NOTES_TYPE_DANCE_SOLO )
{
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0;
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UPLEFT] = 1;
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 2;
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 3;
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UPRIGHT] = 4;
mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 5;
case NOTES_TYPE_DANCE_SINGLE:
iTransformNewToOld[0] = DANCE_NOTE_PAD1_LEFT;
iTransformNewToOld[1] = DANCE_NOTE_PAD1_DOWN;
iTransformNewToOld[2] = DANCE_NOTE_PAD1_UP;
iTransformNewToOld[3] = DANCE_NOTE_PAD1_RIGHT;
break;
case NOTES_TYPE_DANCE_DOUBLE:
case NOTES_TYPE_DANCE_COUPLE:
iTransformNewToOld[0] = DANCE_NOTE_PAD1_LEFT;
iTransformNewToOld[1] = DANCE_NOTE_PAD1_UP;
iTransformNewToOld[2] = DANCE_NOTE_PAD1_UP;
iTransformNewToOld[3] = DANCE_NOTE_PAD1_RIGHT;
iTransformNewToOld[4] = DANCE_NOTE_PAD2_LEFT;
iTransformNewToOld[5] = DANCE_NOTE_PAD2_DOWN;
iTransformNewToOld[6] = DANCE_NOTE_PAD2_UP;
iTransformNewToOld[7] = DANCE_NOTE_PAD2_RIGHT;
break;
case NOTES_TYPE_DANCE_SOLO:
iTransformNewToOld[0] = DANCE_NOTE_PAD1_LEFT;
iTransformNewToOld[1] = DANCE_NOTE_PAD1_UPLEFT;
iTransformNewToOld[2] = DANCE_NOTE_PAD1_DOWN;
iTransformNewToOld[3] = DANCE_NOTE_PAD1_UP;
iTransformNewToOld[4] = DANCE_NOTE_PAD1_UPRIGHT;
iTransformNewToOld[5] = DANCE_NOTE_PAD1_RIGHT;
break;
default:
throw RageException( "Invalid NotesType." );
}
NoteData tempNoteData2;
int iTransformNewToOld[MAX_NOTE_TRACKS];
POSITION pos = mapDanceNoteToNoteDataColumn.GetStartPosition();
while( pos != NULL ) // iterate over all k/v pairs in map
{
int iOldTrack;
int iNewTrack;
mapDanceNoteToNoteDataColumn.GetNextAssoc( pos, iOldTrack, iNewTrack );
iTransformNewToOld[iNewTrack] = iOldTrack;
}
tempNoteData2.m_iNumTracks = iNumNewTracks;
tempNoteData2.LoadTransformed( &tempNoteData, iNumNewTracks, iTransformNewToOld );
tempNoteData2.LoadTransformed( &tempNoteData, mapDanceNoteToNoteDataColumn.GetCount(), iTransformNewToOld );
m_sSMNoteData = tempNoteData2.GetSMNoteDataString();
TidyUpData();
@@ -363,12 +349,17 @@ void DWIcharToNote( char c, InstrumentNumber i, DanceNote &note1Out, DanceNote &
bool Notes::LoadFromDWITokens(
const CString &sMode, const CString &sDescription,
const int &iNumFeet,
const CString &sStepData1, const CString &sStepData2 )
CString sMode, CString sDescription,
int iNumFeet,
CString sStepData1, CString sStepData2 )
{
LOG->WriteLine( "Notes::LoadFromDWITokens()" );
sStepData1.Replace( "\n", "" );
sStepData1.Replace( " ", "" );
sStepData2.Replace( "\n", "" );
sStepData2.Replace( " ", "" );
if( sMode == "#SINGLE" ) m_NotesType = NOTES_TYPE_DANCE_SINGLE;
else if( sMode == "#DOUBLE" ) m_NotesType = NOTES_TYPE_DANCE_DOUBLE;
else if( sMode == "#COUPLE" ) m_NotesType = NOTES_TYPE_DANCE_COUPLE;
@@ -413,9 +404,6 @@ bool Notes::LoadFromDWITokens(
//m_DifficultyClass = DifficultyClassFromDescriptionAndMeter( m_sDescription, m_iMeter );
m_sCredit = "";
NoteData tempNoteData;
tempNoteData.m_iNumTracks = mapDanceNoteToNoteDataColumn.GetCount();
@@ -532,7 +520,6 @@ bool Notes::LoadFromDWITokens(
void Notes::LoadFromSMTokens(
const CString &sNotesType,
const CString &sDescription,
const CString &sCredit,
const CString &sDifficultyClass,
const CString &sMeter,
const CString &sRadarValues,
@@ -543,7 +530,6 @@ void Notes::LoadFromSMTokens(
m_NotesType = StringToNotesType(sNotesType);
m_sDescription = sDescription;
m_sCredit = sCredit;
m_DifficultyClass = StringToDifficultyClass( sDifficultyClass );
m_iMeter = atoi(sMeter);
CStringArray saValues;
@@ -563,23 +549,15 @@ void Notes::WriteSMNotesTag( FILE* fp )
fprintf( fp, "#NOTES:\n" );
fprintf( fp, " %s:\n", NotesTypeToString(m_NotesType) );
fprintf( fp, " %s:\n", m_sDescription );
fprintf( fp, " %s:\n", m_sCredit );
fprintf( fp, " %s:\n", DifficultyClassToString(m_DifficultyClass) );
fprintf( fp, " %d:\n", m_iMeter );
CStringArray asRadarValues;
for( int r=0; r<NUM_RADAR_VALUES; r++ )
asRadarValues.Add( ssprintf("%.1f", m_fRadarValues[r]) );
asRadarValues.Add( ssprintf("%.2f", m_fRadarValues[r]) );
fprintf( fp, " %s:\n", join(",",asRadarValues) );
fprintf( fp, " %s;\n", m_sSMNoteData );
}
void Notes::GetNoteData( NoteData* pNoteDataOut )
{
pNoteDataOut->m_iNumTracks = NotesTypeToNumTracks( m_NotesType );
pNoteDataOut->LoadFromSMNoteDataString( m_sSMNoteData );
fprintf( fp, "%s;\n", m_sSMNoteData );
}
void Notes::SetNoteData( NoteData* pNewNoteData )
@@ -588,6 +566,12 @@ void Notes::SetNoteData( NoteData* pNewNoteData )
m_sSMNoteData = pNewNoteData->GetSMNoteDataString();
}
void Notes::GetNoteData( NoteData* pNoteDataOut )
{
pNoteDataOut->m_iNumTracks = NotesTypeToNumTracks( m_NotesType );
pNoteDataOut->LoadFromSMNoteDataString( m_sSMNoteData );
}
void Notes::TidyUpData()
{
if( m_DifficultyClass == CLASS_INVALID )
+4 -6
View File
@@ -27,15 +27,14 @@ public:
bool LoadFromNotesFile( const CString &sPath );
bool LoadFromBMSFile( const CString &sPath );
bool LoadFromDWITokens(
const CString &sMode,
const CString &sDescription,
const int &iNumFeet,
const CString &sStepData1, const CString &sStepData2
CString sMode,
CString sDescription,
int iNumFeet,
CString sStepData1, const CString sStepData2
);
void LoadFromSMTokens(
const CString &sNotesType,
const CString &sDescription,
const CString &sCredit,
const CString &sDifficultyClass,
const CString &sMeter,
const CString &sRadarValues,
@@ -46,7 +45,6 @@ public:
public:
NotesType m_NotesType;
CString m_sDescription; // This text is displayed next to thte number of feet when a song is selected
CString m_sCredit; // name of the person who created these Notes
DifficultyClass m_DifficultyClass; // this is inferred from m_sDescription
int m_iMeter; // difficulty from 1-10
float m_fRadarValues[NUM_RADAR_VALUES]; // between 0.0-1.2 starting from 12-o'clock rotating clockwise
+2 -18
View File
@@ -39,23 +39,6 @@ Player::Player()
m_fSongBeat = 0;
m_PlayerNumber = PLAYER_INVALID;
// init step elements
for( int t=0; t<MAX_NOTE_TRACKS; t++ )
{
for( int i=0; i<MAX_TAP_NOTE_ROWS; i++ )
{
m_TapNotes[t][i] = '0';
m_TapNoteScores[t][i] = TNS_NONE;
}
}
m_iNumHoldNotes = 0;
for( int i=0; i<MAX_HOLD_NOTE_ELEMENTS; i++ )
{
m_HoldNoteScores[i] = HNS_NONE;
m_fHoldNoteLife[i] = 1.0f;
}
m_pLifeMeter = NULL;
m_pScore = NULL;
@@ -77,6 +60,8 @@ void Player::Load( PlayerNumber player_no, StyleDef* pStyleDef, NoteData* pNoteD
//LOG->WriteLine( "Player::Load()", );
this->CopyAll( pNoteData );
NoteDataWithScoring::Init();
for( int i=0; i<MAX_TAP_NOTE_ROWS; i++ )
m_fHoldNoteLife[i] = 1.0f;
m_PlayerNumber = player_no;
m_PlayerOptions = po;
@@ -500,7 +485,6 @@ GameplayStatistics Player::GetGameplayStatistics()
GSreturn.failed = m_pLifeMeter ? m_pLifeMeter->HasFailed() : false;
for( int r=0; r<NUM_RADAR_VALUES; r++ )
{
GSreturn.fRadarPossible[r] = this->GetRadarValue( (RadarCategory)r, SONGMAN->GetCurrentSong()->m_fMusicLengthSeconds );
+7
View File
@@ -23,6 +23,7 @@ RageException::RageException( LPCTSTR fmt, ...)
va_start(va, fmt);
m_sError = vssprintf( fmt, va );
#ifdef _DEBUG
MessageBox( NULL, m_sError, "Fatal Error", MB_OK );
DebugBreak();
#endif
}
@@ -34,6 +35,12 @@ RageException::RageException( HRESULT hr, LPCTSTR fmt, ...)
m_sError = vssprintf( fmt, va );
m_sError += ssprintf( "(%s)", DXGetErrorString8(hr) );
#ifdef _DEBUG
MessageBox( NULL, m_sError, "Fatal Error", MB_OK );
DebugBreak();
#endif
}
const char* RageException::what() const
{
return m_sError;
}
+3 -2
View File
@@ -10,14 +10,15 @@
-----------------------------------------------------------------------------
*/
#include <exception>
class RageException
class RageException : exception
{
public:
RageException( LPCTSTR fmt, ...);
RageException( HRESULT hr, LPCTSTR fmt, ...);
CString GetError() { return m_sError; };
virtual const char *what() const;
protected:
CString m_sError;
+2 -2
View File
@@ -300,7 +300,7 @@ void ScreenEdit::Update( float fDeltaTime )
DifficultyClassToString( m_pNotes->m_DifficultyClass ),
SONGMAN->GetCurrentNotes(PLAYER_1) ? SONGMAN->GetCurrentNotes(PLAYER_1)->m_sDescription : "no description",
iNumTapNotes, iNumHoldNotes,
m_pSong->m_fOffsetInSeconds,
m_pSong->m_fBeat0OffsetInSeconds,
m_pSong->m_fMusicSampleStartSeconds, m_pSong->m_fMusicSampleLengthSeconds
) );
}
@@ -736,7 +736,7 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ
if( type == IET_FAST_REPEAT )
fOffsetDelta *= 40;
m_pSong->m_fOffsetInSeconds += fOffsetDelta;
m_pSong->m_fBeat0OffsetInSeconds += fOffsetDelta;
}
break;
case DIK_M:
+3 -5
View File
@@ -129,12 +129,10 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
break;
case RM_ARCADE_SUMMARY:
{
if( SONGMAN->m_aGameplayStatistics[0].GetSize() > STAGES_TO_SHOW_IN_SUMMARY )
{
// crop down to 3
for( int p=0; p<NUM_PLAYERS; p++ )
// crop down to 3
for( int p=0; p<NUM_PLAYERS; p++ )
if( SONGMAN->m_aGameplayStatistics[p].GetSize() > STAGES_TO_SHOW_IN_SUMMARY )
SONGMAN->m_aGameplayStatistics[p].RemoveAt( 0, SONGMAN->m_aGameplayStatistics[p].GetSize() - STAGES_TO_SHOW_IN_SUMMARY );
}
const int iSongsToShow = SONGMAN->m_aGameplayStatistics[0].GetSize();
ASSERT( iSongsToShow > 0 );
+22 -18
View File
@@ -545,31 +545,34 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ
// Handle special keys to adjust the offset
if( type == IET_FIRST_PRESS && DeviceI.device == DEVICE_KEYBOARD )
if( DeviceI.device == DEVICE_KEYBOARD )
{
switch( DeviceI.button )
{
case DIK_F9: m_pCurSong->m_fOffsetInSeconds -= 0.01f; break;
case DIK_F10: m_pCurSong->m_fOffsetInSeconds += 0.01f; break;
case DIK_F11: m_pCurSong->m_fOffsetInSeconds -= 1/fBPS; break;
case DIK_F12: m_pCurSong->m_fOffsetInSeconds += 1/fBPS; break;
}
switch( DeviceI.button )
{
case DIK_F9:
case DIK_F10:
case DIK_F11:
case DIK_F12:
m_textDebug.SetText( ssprintf("Offset = %f.", m_pCurSong->m_fOffsetInSeconds) );
m_textDebug.SetDiffuseColor( D3DXCOLOR(1,1,1,1) );
m_textDebug.StopTweening();
m_textDebug.BeginTweeningQueued( 3 ); // sleep
m_textDebug.BeginTweeningQueued( 0.5f ); // fade out
m_textDebug.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,0) );
{
float fOffsetDelta;
switch( DeviceI.button )
{
case DIK_F11: fOffsetDelta = -0.025f; break;
case DIK_F12: fOffsetDelta = +0.025f; break;
default: ASSERT(0);
}
if( type == IET_FAST_REPEAT )
fOffsetDelta *= 40;
m_pCurSong->m_fBeat0OffsetInSeconds += fOffsetDelta;
m_textDebug.SetText( ssprintf("Offset = %f.", m_pCurSong->m_fBeat0OffsetInSeconds) );
m_textDebug.SetDiffuseColor( D3DXCOLOR(1,1,1,1) );
m_textDebug.StopTweening();
m_textDebug.BeginTweeningQueued( 3 ); // sleep
m_textDebug.BeginTweeningQueued( 0.5f ); // fade out
m_textDebug.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,0) );
}
break;
}
}
@@ -665,6 +668,7 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM )
break;
case SM_GoToResults:
SaveSummary();
m_pCurSong->SaveToSMFile(); // save offset changes
SCREENMAN->SetNewScreen( new ScreenEvaluation(false) );
break;
+1 -1
View File
@@ -31,7 +31,7 @@ const float HELP_Y = SCREEN_HEIGHT-35;
const float ITEM_GAP_X = 12;
const float LABELS_X = 80;
const float LINE_START_Y= 80;
const float LINE_GAP_Y = 36;
const float LINE_GAP_Y = 34;
const ScreenMessage SM_PlaySample = ScreenMessage(SM_User-4);
+4
View File
@@ -33,6 +33,7 @@ enum {
PO_SCROLL,
PO_COLOR,
PO_HOLD_NOTES,
PO_DARK,
PO_DRAIN,
PO_SKIN,
NUM_PLAYER_OPTIONS_LINES
@@ -46,6 +47,7 @@ OptionLineData g_PlayerOptionsLines[NUM_PLAYER_OPTIONS_LINES] = {
{ "Scroll", 2, {"STANDARD","REVERSE"} },
{ "Color", 4, {"ARCADE","NOTE","FLAT","PLAIN"} },
{ "Holds", 2, {"OFF","ON"} },
{ "Dark", 2, {"OFF","ON"} },
{ "Drain", 3, {"NORMAL", "NO-RECOVER", "SUDDEN-DEATH"} },
{ "Skin", 0, {""} }, // fill this in on ImportOptions();
};
@@ -99,6 +101,7 @@ void ScreenPlayerOptions::ImportOptions()
m_iSelectedOption[p][PO_SCROLL] = po.m_bReverseScroll ? 1 : 0 ;
m_iSelectedOption[p][PO_COLOR] = po.m_ColorType;
m_iSelectedOption[p][PO_HOLD_NOTES] = po.m_bHoldNotes ? 1 : 0;
m_iSelectedOption[p][PO_DARK] = po.m_bDark ? 1 : 0;
m_iSelectedOption[p][PO_DRAIN] = po.m_DrainType;
// highlight currently selected skin
@@ -135,6 +138,7 @@ void ScreenPlayerOptions::ExportOptions()
po.m_bReverseScroll = (m_iSelectedOption[p][PO_SCROLL] == 1);
po.m_ColorType = (PlayerOptions::ColorType)m_iSelectedOption[p][PO_COLOR];
po.m_bHoldNotes = (m_iSelectedOption[p][PO_HOLD_NOTES] == 1);
po.m_bDark = (m_iSelectedOption[p][PO_DARK] == 1);
po.m_DrainType = (PlayerOptions::DrainType)m_iSelectedOption[p][PO_DRAIN];
int iSelectedSkin = m_iSelectedOption[p][PO_SKIN];
+1 -1
View File
@@ -127,7 +127,7 @@ ScreenSelectDifficulty::ScreenSelectDifficulty()
for( p=0; p<NUM_PLAYERS; p++ )
{
m_iSelection[p] = 0;
m_iSelection[p] = 1; // Select "medium"
m_bChosen[p] = false;
if( !GAMEMAN->IsPlayerEnabled((PlayerNumber)p) )
+37 -24
View File
@@ -112,6 +112,39 @@ ScreenSelectGroup::ScreenSelectGroup()
}
//
// Generate what text will show in the contents for each group
//
for( i=0; i<min(m_arrayGroupNames.GetSize(), MAX_GROUPS); i++ )
{
CArray<Song*, Song*> arraySongs;
const CString &sCurGroupName = m_arrayGroupNames[i];
if( i == 0 ) arraySongs.Copy( SONGMAN->m_pSongs );
else SONGMAN->GetSongsInGroup( sCurGroupName, arraySongs );
m_iNumSongsInGroup[i] = arraySongs.GetSize();
SortSongPointerArrayByTitle( arraySongs );
for( int c=0; c<NUM_CONTENTS_COLUMNS; c++ )
{
CString sText;
for( int j=c*TITLES_PER_COLUMN; j<(c+1)*TITLES_PER_COLUMN; j++ )
{
if( j < arraySongs.GetSize() )
{
if( j == NUM_CONTENTS_COLUMNS * TITLES_PER_COLUMN - 1 )
sText += ssprintf( "%d more.....", arraySongs.GetSize() - NUM_CONTENTS_COLUMNS * TITLES_PER_COLUMN - 1 );
else
sText += arraySongs[j]->GetFullTitle() + "\n";
}
}
m_sContentsText[i][c] = sText;
}
}
m_soundChange.Load( THEME->GetPathTo(SOUND_SELECT_GROUP_CHANGE) );
m_soundSelect.Load( THEME->GetPathTo(SOUND_MENU_START) );
@@ -198,30 +231,10 @@ void ScreenSelectGroup::AfterChange()
m_textGroup[iSel].SetTweenX( BUTTON_SELECTED_X );
m_textGroup[iSel].SetEffectGlowing();
for( int c=0; c<NUM_CONTENTS_COLUMNS; c++ )
m_textContents[c].SetText( m_sContentsText[m_iSelection][c] );
CArray<Song*, Song*> arraySongs;
const CString sSelectedGroupName = m_arrayGroupNames[m_iSelection];
if( m_iSelection == 0 ) arraySongs.Copy( SONGMAN->m_pSongs );
else SONGMAN->GetSongsInGroup( m_arrayGroupNames[m_iSelection], arraySongs );
SortSongPointerArrayByTitle( arraySongs );
for( int i=0; i<NUM_CONTENTS_COLUMNS; i++ )
{
CString sText;
for( int j=i*TITLES_PER_COLUMN; j<(i+1)*TITLES_PER_COLUMN; j++ )
{
if( j < arraySongs.GetSize() )
{
if( j == NUM_CONTENTS_COLUMNS * TITLES_PER_COLUMN - 1 )
sText += ssprintf( "(%d more).....", arraySongs.GetSize() - NUM_CONTENTS_COLUMNS * TITLES_PER_COLUMN - 2 );
else
sText += arraySongs[j]->GetFullTitle() + "\n";
}
}
m_textContents[i].SetText( sText );
}
CString sSelectedGroupName = m_arrayGroupNames[m_iSelection];
CString sGroupBannerPath;
if( 0 == stricmp(sSelectedGroupName, "ALL MUSIC") )
@@ -232,7 +245,7 @@ void ScreenSelectGroup::AfterChange()
sGroupBannerPath = THEME->GetPathTo(GRAPHIC_FALLBACK_BANNER);
// There is too much Z-fighting when we rotate this, so fake a rotation with a squash
m_GroupInfoFrame.Set( sGroupBannerPath, arraySongs.GetSize() );
m_GroupInfoFrame.Set( sGroupBannerPath, m_iNumSongsInGroup[m_iSelection] );
}
+4 -1
View File
@@ -18,7 +18,7 @@
#include "GroupInfoFrame.h"
const int MAX_GROUPS = 12;
const int MAX_GROUPS = 15;
const int NUM_CONTENTS_COLUMNS = 3;
class ScreenSelectGroup : public Screen
@@ -55,6 +55,9 @@ private:
Sprite m_sprContentsHeader;
BitmapText m_textContents[NUM_CONTENTS_COLUMNS];
CString m_sContentsText[MAX_GROUPS][NUM_CONTENTS_COLUMNS];
int m_iNumSongsInGroup[MAX_GROUPS];
RandomSample m_soundChange;
RandomSample m_soundSelect;
RandomSample m_soundFlyOff;
+1 -1
View File
@@ -38,7 +38,7 @@
const CString CHOICE_TEXT[ScreenTitleMenu::NUM_TITLE_MENU_CHOICES] = {
"GAME START",
"SWITCH GAME",
"KEY/JOY MAPPING",
"CONFIG KEY/JOY",
"GAME OPTIONS",
"EDIT/RECORD/SYNCH",
"EXIT",
+40 -42
View File
@@ -19,7 +19,7 @@
#include "NoteData.h"
const int FILE_CACHE_VERSION = 26; // increment this to force a cache reload (useful when the SM file format changes)
const int FILE_CACHE_VERSION = 29; // increment this to force a cache reload (useful when the SM file format changes)
int CompareBPMSegments(const void *arg1, const void *arg2)
@@ -73,7 +73,7 @@ void SortFreezeSegmentsArray( CArray<FreezeSegment,FreezeSegment&> &arrayFreezeS
Song::Song()
{
m_bChangedSinceSave = false;
m_fOffsetInSeconds = 0;
m_fBeat0OffsetInSeconds = 0;
m_fMusicSampleStartSeconds = 0;
m_fMusicSampleLengthSeconds = 16; // start fading out at m_fMusicSampleLengthSeconds-1 seconds
m_iMusicBytes = 0;
@@ -108,7 +108,7 @@ void Song::GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatOut, fl
// LOG->WriteLine( "GetBeatAndBPSFromElapsedTime( fElapsedTime = %f )", fElapsedTime );
// This function is a nightmare. Don't even try to understand it. :-)
fElapsedTime += m_fOffsetInSeconds;
fElapsedTime += m_fBeat0OffsetInSeconds;
for( int i=0; i<m_BPMSegments.GetSize(); i++ ) // foreach BPMSegment
@@ -284,14 +284,6 @@ bool Song::LoadFromSongDir( CString sDir )
goto load_without_cache;
LoadFromSMFile( GetCacheFilePath() ); // don't load NoteData
// Save length of music
if( GetMusicPath() != "" )
{
RageSoundStream sound;
sound.Load( GetMusicPath() );
m_fMusicLengthSeconds = sound.GetLengthSeconds();
}
LOG->WriteLine( "Loading '%s' from cache file '%s'.", m_sSongDir, GetCacheFilePath() );
return true;
}
@@ -463,12 +455,15 @@ bool Song::LoadFromBMSDir( CString sDir )
switch( iBMSTrackNo )
{
case 1: // background music track
float fBeatOffset;
fBeatOffset = NoteRowToBeat( (float)iStepIndex );
float fBPS;
fBPS = m_BPMSegments[0].m_fBPM/60.0f;
m_fOffsetInSeconds = fBeatOffset / fBPS;
//LOG->WriteLine( "Found offset to be index %d, beat %f", iStepIndex, NoteRowToBeat(iStepIndex) );
{
float fBeatOffset = fBeatOffset = NoteRowToBeat( (float)iStepIndex );
if( fBeatOffset > 10 ) // some BPMs's play the music again at the end. Why? Who knows...
break;
float fBPS;
fBPS = m_BPMSegments[0].m_fBPM/60.0f;
m_fBeat0OffsetInSeconds = fBeatOffset / fBPS;
//LOG->WriteLine( "Found offset to be index %d, beat %f", iStepIndex, NoteRowToBeat(iStepIndex) );
}
break;
case 3: // bpm change
{
@@ -718,7 +713,7 @@ bool Song::LoadFromDWIFile( CString sPath )
}
else if( sValueName == "#GAP" )
// the units of GAP is 1/1000 second
m_fOffsetInSeconds = -atoi( arrayValueTokens[1] ) / 1000.0f;
m_fBeat0OffsetInSeconds = -atoi( arrayValueTokens[1] ) / 1000.0f;
else if( sValueName == "#SAMPLESTART" )
m_fMusicSampleStartSeconds = TimeToSeconds( arrayValueTokens[1] );
@@ -862,8 +857,8 @@ bool Song::LoadFromSMFile( CString sPath )
else if( sValueName == "#BACKGROUND" )
m_sBackgroundFile = arrayValueTokens[1];
else if( sValueName == "#BACKGROUNDMOVIE" )
m_sBackgroundMovieFile = arrayValueTokens[1];
// else if( sValueName == "#BACKGROUNDMOVIE" )
// m_sBackgroundMovieFile = arrayValueTokens[1];
else if( sValueName == "#CDTITLE" )
m_sCDTitleFile = arrayValueTokens[1];
@@ -874,6 +869,9 @@ bool Song::LoadFromSMFile( CString sPath )
else if( sValueName == "#MUSICBYTES" )
m_iMusicBytes = atoi( arrayValueTokens[1] );
else if( sValueName == "#MUSICLENGTH" )
m_fMusicLengthSeconds = (float)atof( arrayValueTokens[1] );
else if( sValueName == "#SAMPLESTART" )
m_fMusicSampleStartSeconds = TimeToSeconds( arrayValueTokens[1] );
@@ -881,7 +879,7 @@ bool Song::LoadFromSMFile( CString sPath )
m_fMusicSampleLengthSeconds = TimeToSeconds( arrayValueTokens[1] );
else if( sValueName == "#OFFSET" )
m_fOffsetInSeconds = (float)atof( arrayValueTokens[1] );
m_fBeat0OffsetInSeconds = (float)atof( arrayValueTokens[1] );
else if( sValueName == "#FREEZES" )
{
@@ -940,8 +938,8 @@ bool Song::LoadFromSMFile( CString sPath )
m_arrayNotes.Add( pNewNotes );
}
if( arrayValueTokens.GetSize() != 8 )
throw RageException( "The song file '%s' is has %d in a #NOTES tag, but should have %d.", sPath, arrayValueTokens.GetSize(), 8 );
if( arrayValueTokens.GetSize() != 7 )
throw RageException( "The song file '%s' is has %d fields in a #NOTES tag, but should have %d.", sPath, arrayValueTokens.GetSize(), 7 );
pNewNotes->LoadFromSMTokens(
arrayValueTokens[1],
@@ -949,8 +947,7 @@ bool Song::LoadFromSMFile( CString sPath )
arrayValueTokens[3],
arrayValueTokens[4],
arrayValueTokens[5],
arrayValueTokens[6],
arrayValueTokens[7]
arrayValueTokens[6]
);
}
@@ -992,7 +989,7 @@ void Song::TidyUpData()
m_fMusicLengthSeconds = sound.GetLengthSeconds();
}
if( !DoesFileExist(GetBannerPath()) )
if( !HasBanner() )
{
m_sBannerFile = "";
// find the smallest image in the directory
@@ -1023,7 +1020,7 @@ void Song::TidyUpData()
//throw RageException( ssprintf("Banner could not be found. Please check the Song file '%s' and verify the specified #BANNER exists.", GetSongFilePath()) );
}
if( !DoesFileExist(GetBackgroundPath()) )
if( !HasBackground() )
{
m_sBackgroundFile = "";
// find the largest image in the directory
@@ -1050,20 +1047,20 @@ void Song::TidyUpData()
m_sBackgroundFile = sLargestFileSoFar;
}
if( !DoesFileExist(GetBackgroundMoviePath()) )
{
m_sBackgroundMovieFile = "";
// if( !DoesFileExist(GetBackgroundMoviePath()) )
// {
// m_sBackgroundMovieFile = "";
//
// CStringArray arrayPossibleBackgroundMovies;
// GetDirListing( m_sSongDir + CString("*.avi"), arrayPossibleBackgroundMovies );
// GetDirListing( m_sSongDir + CString("*.mpg"), arrayPossibleBackgroundMovies );
// GetDirListing( m_sSongDir + CString("*.mpeg"), arrayPossibleBackgroundMovies );
//
// if( arrayPossibleBackgroundMovies.GetSize() > 0 ) // we found a match
// m_sBackgroundMovieFile = arrayPossibleBackgroundMovies[0];
// }
CStringArray arrayPossibleBackgroundMovies;
GetDirListing( m_sSongDir + CString("*.avi"), arrayPossibleBackgroundMovies );
GetDirListing( m_sSongDir + CString("*.mpg"), arrayPossibleBackgroundMovies );
GetDirListing( m_sSongDir + CString("*.mpeg"), arrayPossibleBackgroundMovies );
if( arrayPossibleBackgroundMovies.GetSize() > 0 ) // we found a match
m_sBackgroundMovieFile = arrayPossibleBackgroundMovies[0];
}
if( !DoesFileExist(GetCDTitlePath()) )
if( !HasCDTitle() )
{
m_sCDTitleFile = "";
}
@@ -1141,11 +1138,12 @@ void Song::SaveToSMFile( CString sPath )
fprintf( fp, "#CREDIT:%s;\n", m_sCredit );
fprintf( fp, "#BANNER:%s;\n", m_sBannerFile );
fprintf( fp, "#BACKGROUND:%s;\n", m_sBackgroundFile );
fprintf( fp, "#BACKGROUNDMOVIE:%s;\n", m_sBackgroundMovieFile );
// fprintf( fp, "#BACKGROUNDMOVIE:%s;\n", m_sBackgroundMovieFile );
fprintf( fp, "#CDTITLE:%s;\n", m_sCDTitleFile );
fprintf( fp, "#MUSIC:%s;\n", m_sMusicFile );
fprintf( fp, "#MUSICBYTES:%u;\n", m_iMusicBytes );
fprintf( fp, "#OFFSET:%.2f;\n", m_fOffsetInSeconds );
fprintf( fp, "#MUSICLENGTH:%.2f;\n", m_fMusicLengthSeconds );
fprintf( fp, "#OFFSET:%.2f;\n", m_fBeat0OffsetInSeconds );
fprintf( fp, "#SAMPLESTART:%.2f;\n", m_fMusicSampleStartSeconds );
fprintf( fp, "#SAMPLELENGTH:%.2f;\n", m_fMusicSampleLengthSeconds );
+51 -34
View File
@@ -70,7 +70,7 @@ const CString g_sAppClassName = "StepMania Class";
HWND g_hWndMain; // Main Window Handle
HINSTANCE g_hInstance; // The Handle to Window Instance
HANDLE g_hMutex; // Used to check if an instance of our app is already
const DWORD g_dwWindowStyle = WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU|WS_THICKFRAME;
const DWORD g_dwWindowStyle = WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU;
BOOL g_bIsActive = FALSE; // Whether the focus is on our app
@@ -100,19 +100,44 @@ void ApplyGraphicOptions(); // Set the display mode according to the user's pref
CString g_sErrorString;
//-----------------------------------------------------------------------------
// Name: StructuredExceptionHandler()
// Desc: Callback for SEH exceptions
//-----------------------------------------------------------------------------
void StructuredExceptionHandler(unsigned int uCode,
struct _EXCEPTION_POINTERS* /* pXPointers */)
{
const char* msg;
switch( uCode )
{
case EXCEPTION_ACCESS_VIOLATION: msg = "Access Violation"; break;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: msg = "Array Bounds Exceeded"; break;
case EXCEPTION_STACK_OVERFLOW: msg = "Stack Overflow"; break;
case EXCEPTION_FLT_DENORMAL_OPERAND: msg = "Floating Point Denormal Operation"; break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO: msg = "Floating Point Divide by Zero"; break;
case EXCEPTION_FLT_INVALID_OPERATION: msg = "Floating Point Invalid Operation"; break;
case EXCEPTION_FLT_UNDERFLOW: msg = "Floating Point Underflow"; break;
case EXCEPTION_FLT_OVERFLOW: msg = "Floating Point Overflow"; break;
case EXCEPTION_FLT_STACK_CHECK: msg = "Floating Point Stack Over/Underflow"; break;
case EXCEPTION_INT_DIVIDE_BY_ZERO: msg = "Integer Divide by Zero"; break;
case EXCEPTION_INT_OVERFLOW: msg = "Integer Overflow"; break;
default: msg = "Unknown Exception"; break;
}
throw std::exception(msg);
}
//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: Application entry point
//-----------------------------------------------------------------------------
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow )
{
#ifdef RELEASE
try
#endif
{
// Initialize ActiveX for Flash
//AfxEnableControlContainer();
_set_se_translator( StructuredExceptionHandler );
#ifndef _DEBUG
try
{
#endif
//
// Check to see if the app is already running.
//
@@ -191,9 +216,9 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow )
CreateObjects( g_hWndMain ); // Create the game objects
ShowWindow( g_hWndMain, SW_SHOW );
#ifdef RELEASE
#ifndef _DEBUG // release
LOG->HideConsole();
#endif
#endif
// Now we're ready to recieve and process Windows messages.
MSG msg;
@@ -229,41 +254,33 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow )
DestroyObjects(); // deallocate our game objects and leave fullscreen
ShowWindow( g_hWndMain, SW_HIDE );
#ifndef _DEBUG
}
#ifdef _RELEASE
catch( RageException e )
{
g_sErrorString = e.GetError();
g_sErrorString = e.what();
}
catch( exception e )
{
g_sErrorString = e.what();
}
catch( ... )
{
switch( GetExceptionCode() )
{
case EXCEPTION_ACCESS_VIOLATION: g_sErrorString = "EXCEPTION_ACCESS_VIOLATION"; break;
case EXCEPTION_BREAKPOINT: g_sErrorString = "EXCEPTION_BREAKPOINT"; break;
case EXCEPTION_DATATYPE_MISALIGNMENT: g_sErrorString = "EXCEPTION_DATATYPE_MISALIGNMENT"; break;
case EXCEPTION_SINGLE_STEP: g_sErrorString = "EXCEPTION_SINGLE_STEP"; break;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: g_sErrorString = "EXCEPTION_ARRAY_BOUNDS_EXCEEDED"; break;
case EXCEPTION_FLT_DENORMAL_OPERAND: g_sErrorString = "EXCEPTION_FLT_DENORMAL_OPERAND"; break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO: g_sErrorString = "EXCEPTION_FLT_DIVIDE_BY_ZERO"; break;
case EXCEPTION_FLT_INEXACT_RESULT: g_sErrorString = "EXCEPTION_FLT_INEXACT_RESULT"; break;
case EXCEPTION_FLT_INVALID_OPERATION: g_sErrorString = "EXCEPTION_FLT_INVALID_OPERATION"; break;
case EXCEPTION_FLT_OVERFLOW: g_sErrorString = "EXCEPTION_FLT_OVERFLOW"; break;
case EXCEPTION_FLT_STACK_CHECK: g_sErrorString = "EXCEPTION_FLT_STACK_CHECK"; break;
case EXCEPTION_FLT_UNDERFLOW: g_sErrorString = "EXCEPTION_FLT_UNDERFLOW"; break;
case EXCEPTION_INT_DIVIDE_BY_ZERO: g_sErrorString = "EXCEPTION_INT_DIVIDE_BY_ZERO"; break;
case EXCEPTION_INT_OVERFLOW: g_sErrorString = "EXCEPTION_INT_OVERFLOW"; break;
case EXCEPTION_PRIV_INSTRUCTION: g_sErrorString = "EXCEPTION_PRIV_INSTRUCTION"; break;
case EXCEPTION_NONCONTINUABLE_EXCEPTION:g_sErrorString = "EXCEPTION_NONCONTINUABLE_EXCEPTION"; break;
case EXCEPTION_ACCESS_VIOLATION: g_sErrorString = "EXCEPTION_ACCESS_VIOLATION"; break;
case EXCEPTION_ACCESS_VIOLATION: g_sErrorString = "EXCEPTION_ACCESS_VIOLATION"; break;
default: g_sErrorString = "Unknown exception."; break;
}
g_sErrorString = "Unknown exception";
}
if( g_sErrorString != "" )
{
if( LOG )
LOG->WriteLine(
"\n"
"//////////////////////////////////////////////////////\n"
"Exception: %s"
"//////////////////////////////////////////////////////\n"
"\n",
g_sErrorString
);
// throw up a pretty error dialog
DialogBox(
hInstance,
-8
View File
@@ -528,14 +528,6 @@ SOURCE=.\BPMDisplay.h
# End Source File
# Begin Source File
SOURCE=.\Course.cpp
# End Source File
# Begin Source File
SOURCE=.\Course.h
# End Source File
# Begin Source File
SOURCE=.\CourseContentsFrame.cpp
# End Source File
# Begin Source File
+2 -1
View File
@@ -21,6 +21,7 @@
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/EHa"
Optimization="0"
PreprocessorDefinitions="WIN32,_DEBUG,_WINDOWS,DEBUG"
BasicRuntimeChecks="3"
@@ -87,7 +88,7 @@
FavorSizeOrSpeed="2"
OptimizeForProcessor="2"
OptimizeForWindowsApplication="TRUE"
PreprocessorDefinitions="WIN32,NDEBUG,_WINDOWS"
PreprocessorDefinitions="WIN32,NDEBUG,_WINDOWS,RELEASE"
StringPooling="TRUE"
MinimalRebuild="FALSE"
RuntimeLibrary="0"
+1 -4
View File
@@ -71,26 +71,23 @@ public:
CString m_sMusicFile;
DWORD m_iMusicBytes;
float m_fOffsetInSeconds;
float m_fBeat0OffsetInSeconds;
float m_fMusicLengthSeconds;
float m_fMusicSampleStartSeconds;
float m_fMusicSampleLengthSeconds;
CString m_sBannerFile;
CString m_sBackgroundFile;
CString m_sBackgroundMovieFile;
CString m_sCDTitleFile;
CString GetMusicPath() {return m_sSongDir+m_sMusicFile; };
CString GetBannerPath() {return m_sSongDir+m_sBannerFile; };
CString GetBackgroundPath() {return m_sSongDir+m_sBackgroundFile; };
CString GetBackgroundMoviePath(){return m_sSongDir+m_sBackgroundMovieFile; };
CString GetCDTitlePath() {return m_sSongDir+m_sCDTitleFile; };
bool HasMusic() {return m_sMusicFile != "" && DoesFileExist(GetMusicPath()); };
bool HasBanner() {return m_sBannerFile != "" && DoesFileExist(GetBannerPath()); };
bool HasBackground() {return m_sBackgroundFile != "" && DoesFileExist(GetBackgroundPath()); };
bool HasBackgroundMovie() {return m_sBackgroundMovieFile != ""&& DoesFileExist(GetBackgroundMoviePath()); };
bool HasCDTitle() {return m_sCDTitleFile != "" && DoesFileExist(GetCDTitlePath()); };