diff --git a/Docs/Luadoc/LuaDocumentation.xml b/Docs/Luadoc/LuaDocumentation.xml
index f2504a4f5f..fab6b8e330 100644
--- a/Docs/Luadoc/LuaDocumentation.xml
+++ b/Docs/Luadoc/LuaDocumentation.xml
@@ -2339,7 +2339,7 @@ save yourself some time, copy this for undocumented things:
Resets the specific Player's mods to the default settings.
- Saves the machine profile data.
+ Saves the bookkeeping and machine profile data.
Sets the current for the specified .
diff --git a/Docs/Userdocs/sm5_beginner.txt b/Docs/Userdocs/sm5_beginner.txt
index 966c10994f..24c31d8535 100644
--- a/Docs/Userdocs/sm5_beginner.txt
+++ b/Docs/Userdocs/sm5_beginner.txt
@@ -156,6 +156,7 @@ menus were re-shuffled around for the StepMania 4 alphas.
The typical StepMania 3.9 Options Menu:
* Appearance Options
* Background Options
+* Bookkeeping
* Center Image
* Coin Options
* Config Key/Joy Mappings
diff --git a/Themes/HelloWorld/screens.txt b/Themes/HelloWorld/screens.txt
index ee3ca9203b..a046631d70 100644
--- a/Themes/HelloWorld/screens.txt
+++ b/Themes/HelloWorld/screens.txt
@@ -78,6 +78,7 @@ ScreenUnlockCelebrate
*
ScreenAttract
+ScreenBookkeeping
ScreenEdit
ScreenEditMenu
ScreenEvaluation
diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini
index 6784dc74d5..100dcd63ea 100644
--- a/Themes/_fallback/Languages/en.ini
+++ b/Themes/_fallback/Languages/en.ini
@@ -5,6 +5,7 @@ StepMania=StepMania
[LoadingWindow]
Couldn't open any loading windows.=Couldn't open any loading windows.
Starting sound subsystem...=Starting sound subsystem...
+Initializing bookkeeper...=Initializing bookkeeper...
Starting lights subsystem...=Starting lights subsystem...
Loading game type...=Loading game type...
Building song cache index...=Building song cache index...
@@ -349,10 +350,12 @@ BGBrightness=Controls how bright the background will appear. Turn this setting d
Background=Change options that control the backgrounds that play during gameplay.
BarDrain=BarDrain
BatLives=BatLives
+Bookkeeping=Check coin drop statistics.
Calibrate Machine Sync=Calibrate the audio synchronization.
CelShadeModels=Choose if dancing characters are drawn with cel shading.
Center Image=Center the image on your monitor.
Characters=Characters
+Clear Bookkeeping Data=Clear all coin drop data.
Clear Machine Edits=Save all step edits saved to this machine.
Clear USB edits=Clear USB edits
Clear Machine Stats=Clear all scores saved to this machine.
@@ -847,6 +850,7 @@ BarDrain=Bar Drain
BatLives=Bat Lives
Base Difficulty=Base Difficulty
Beat 0 Offset=Beat 0 Offset
+Bookkeeping=Bookkeeping
Calibrate Machine Sync=Calibrate Audio Sync
CPUSkill=CPU Skill
CelShadeModels=Cel-shaded Models
@@ -856,6 +860,7 @@ Characters=Characters
Chart Name=Chart Name
Chart Style=Chart Style
Choose=Choose
+Clear Bookkeeping Data=Clear Bookkeeping Data
Clear Machine Edits=Clear Machine Edits
Clear Machine Stats=Clear Machine Scores
Clear USB edits=Clear USB edits
@@ -1274,6 +1279,15 @@ HeaderSubText=Get the best performance
HeaderText=Advanced Options
HeaderSubText=These settings are for advanced users
+[ScreenBookkeeping]
+All-time Coin Total:=All-time Coin Total:
+Total Song Plays: %d=Total Song Plays: %d
+Coin Data by Day of Week, All-Time=Coin Data by Day of Week, All-Time
+Coin Data by Hour of Day, All-Time=Coin Data by Hour of Day, All-Time
+Coin Data of Last %d Days=Coin Data of Last %d Days
+Coin Data of Last %d Weeks=Coin Data of Last %d Weeks
+HeaderText=Bookkeeping
+
[ScreenCaution]
Caution=CAUTION!
CautionText=Keep the dance platform a safe distance from your monitor and furniture.\n\nBe careful that you do not injure pets, children, or spectators while dancing.
@@ -1635,6 +1649,7 @@ HelpTextTextEntry=Type a value using the keyboard. Press Enter to finish.
HelpTextMapControllers=Use arrow keys to move, ENTER to assign, SPACE to clear::Press ESCAPE when done
HelpTextOnline=smonline.us to connect to official Stepmania Online Server::Check out Stepmaniaonline.com for more information
HelpTextNetSelectMusic=Ctrl + Enter to enter room/select song::&UP; for Player Options
+HelpTextBookkeeping=Press &MENULEFT;&MENURIGHT; to cycle data. Press ESCAPE when done.
[ScreenSelectGame]
HeaderText=Select Game
@@ -1674,6 +1689,7 @@ HeaderSubText=Let's get started. I know you can!
%d edits cleared, %d errors.=%d edits cleared, %d errors.
%d failed=%d failed
%d ignored=%d ignored
+Bookkeeping data cleared.=Bookkeeping data cleared.
Copied from P%d card:=Copied from P%d card:
Copied to P%d card:=Copied to P%d card:
Edits not cleared - No memory cards ready.=Edits not cleared - No memory cards ready.
diff --git a/Themes/_fallback/Languages/es.ini b/Themes/_fallback/Languages/es.ini
index 37191689fc..3131aa7906 100644
--- a/Themes/_fallback/Languages/es.ini
+++ b/Themes/_fallback/Languages/es.ini
@@ -5,6 +5,7 @@ StepMania=StepMania
[LoadingWindow]
Couldn't open any loading windows.=Couldn't open any loading windows.
Starting sound subsystem...=Starting sound subsystem...
+Initializing bookkeeper...=Initializing bookkeeper...
Starting lights subsystem...=Starting lights subsystem...
Loading game type...=Loading game type...
Building song cache index...=Building song cache index...
@@ -332,10 +333,12 @@ BGBrightness=Controls how bright the background will appear. Turn this setting d
Background=Change options that control the backgrounds that play during gameplay.
BarDrain=BarDrain
BatLives=BatLives
+Bookkeeping=Check coin drop statistics.
Calibrate Machine Sync=Calibrate the audio synchronization.
CelShadeModels=Choose if dancing characters are drawn with cel shading.
Center Image=Center the image on your monitor.
Characters=Characters
+Clear Bookkeeping Data=Clear all coin drop data.
Clear Machine Edits=Save all step edits saved to this machine.
Clear USB edits=Clear USB edits
Clear Machine Stats=Clear all scores saved to this machine.
@@ -820,6 +823,7 @@ BarDrain=Bar Drain
BatLives=Bat Lives
Base Difficulty=Base Difficulty
Beat 0 Offset=Beat 0 Offset
+Bookkeeping=Bookkeeping
Calibrate Machine Sync=Calibrate Audio Sync
CPUSkill=CPU Skill
CelShadeModels=Cel-shaded Models
@@ -829,6 +833,7 @@ Characters=Characters
Chart Name=Chart Name
Chart Style=Chart Style
Choose=Choose
+Clear Bookkeeping Data=Clear Bookkeeping Data
Clear Machine Edits=Clear Machine Edits
Clear Machine Stats=Clear Machine Scores
Clear USB edits=Clear USB edits
@@ -1218,6 +1223,15 @@ HeaderSubText=Get the best performance
HeaderText=Advanced Options
HeaderSubText=These settings are for advanced users
+[ScreenBookkeeping]
+All-time Coin Total:=All-time Coin Total:
+Total Song Plays: %d=Total Song Plays: %d
+Coin Data by Day of Week, All-Time=Coin Data by Day of Week, All-Time
+Coin Data by Hour of Day, All-Time=Coin Data by Hour of Day, All-Time
+Coin Data of Last %d Days=Coin Data of Last %d Days
+Coin Data of Last %d Weeks=Coin Data of Last %d Weeks
+HeaderText=Bookkeeping
+
[ScreenCaution]
Caution=¡ADVERTENCIA!
CautionText=Mantén la plataforma de baile a una distancia segura del monitor y muebles.\n\nTen cuidado para no hacer daño a mascotas, niños o espectadores mientras bailas.
@@ -1567,6 +1581,7 @@ HelpTextTextEntry=Type a value using the keyboard. Press Enter to finish.
HelpTextMapControllers=Use arrow keys to move, ENTER to assign, SPACE to clear::Press ESCAPE when done
HelpTextOnline=smonline.us to connect to official Stepmania Online Server::Check out Stepmaniaonline.com for more information
HelpTextNetSelectMusic=Ctrl + Enter to enter room/select song::&UP; for Player Options
+HelpTextBookkeeping=Press &MENULEFT;&MENURIGHT; to cycle data. Press ESCAPE when done.
[ScreenSelectGame]
HeaderText=Seleccionar Juego
@@ -1606,6 +1621,7 @@ HeaderSubText=Let's get started. I know you can!
%d edits cleared, %d errors.=%d edits cleared, %d errors.
%d failed=%d failed
%d ignored=%d ignored
+Bookkeeping data cleared.=Bookkeeping data cleared.
Copied from P%d card:=Copied from P%d card:
Copied to P%d card:=Copied to P%d card:
Edits not cleared - No memory cards ready.=Edits not cleared - No memory cards ready.
diff --git a/Themes/_fallback/Languages/ja.ini b/Themes/_fallback/Languages/ja.ini
index 17c2b91874..3b93495ed3 100644
--- a/Themes/_fallback/Languages/ja.ini
+++ b/Themes/_fallback/Languages/ja.ini
@@ -14,6 +14,7 @@ StepMania=StepMania
[LoadingWindow]
Couldn't open any loading windows.=読み込みウインドウが開けませんでした。
Starting sound subsystem...=音声システム開始
+Initializing bookkeeper...=クレジット記録初期化中
Starting lights subsystem...=サイドライト初期化中
Loading game type...=ゲーム読み込み中
Building song cache index...=譜面データベース生成中
@@ -333,10 +334,12 @@ BGBrightness=背景の明度を調整します。
Background=プレイ中の背景を設定します。「Static」で背景を固定します。\n「Random Background」はRandomMoviesフォルダの背景を再生します。
BarDrain=ライフバーの減り方を設定します。
BatLives=ライフバッテリーの個数を設定します。
+Bookkeeping=クレジットの投入履歴を閲覧できます。
Calibrate Machine Sync=グローバルオフセットを設定します。
CelShadeModels=3Dキャラクターをセルシェードで表示します。
Center Image=モニタと画像の位置を調整します。
Characters=キャラクターの使用設定をします。
+Clear Bookkeeping Data=クレジットデータを削除します。
Clear Machine Edits=Songs以外のローカルに保存されているエディットデータを削除します。
Clear USB edits=メモリーカードに保存されているエディットデータを削除します。
Clear Machine Stats=スコアデータを削除します。
@@ -818,6 +821,7 @@ BarDrain=バーの減り方
BatLives=バッテリーの個数
Base Difficulty=基本難易度
Beat 0 Offset=0小節のオフセット
+Bookkeeping=クレジット履歴
Calibrate Machine Sync=音の同期
CPUSkill=CPUのうまさ
CelShadeModels=セルシェード\nモデル
@@ -827,6 +831,7 @@ Characters=キャラクター
Chart Name=譜面の名前
Chart Style=譜面の推奨プレイスタイル
Choose=選択
+Clear Bookkeeping Data=クレジット\n履歴の消去
Clear Machine Edits=筐体エディットの消去
Clear Machine Stats=筐体スコアの消去
Clear USB edits=メモリーカード\nエディットの消去
@@ -1222,6 +1227,15 @@ HeaderSubText=画像と音声に関するオプションです。
HeaderText=ゲームオプション
HeaderSubText=プレイ中のスコア形式など、ゲーム難易度に関わる設定です。
+[ScreenBookkeeping]
+All-time Coin Total:=今まで投入されたコインの枚数:
+Total Song Plays: %d=プレイされた曲: %d
+Coin Data by Day of Week, All-Time=週間のコイン枚数
+Coin Data by Hour of Day, All-Time=時間のコイン枚数
+Coin Data of Last %d Days=%d日前からのコイン枚数
+Coin Data of Last %d Weeks=%d週前からのコイン枚数
+HeaderText=コイン枚数を確認できます。
+
[ScreenCaution]
Caution=CAUTION!
CautionText=プレイする周りには物を置かないようにしてください。また、近隣の迷惑にならないようにしてください。
@@ -1576,6 +1590,7 @@ HelpTextTextEntry=キーボードのタイプ(例:106、109)を入力します
HelpTextMapControllers=矢印キーを設定します。ENTERキーで設定、SPACEキーで削除します。Escキーで終了します。
HelpTextOnline=日本サーバはsmojp.ath.cxです。一度接続そのもののテストを行うことを推奨します。\n詳しくはstepmaniaonline.com(英語)を参照してください。
HelpTextNetSelectMusic=Ctrl+Enter 決定&UP; プレイヤーオプション
+HelpTextBookkeeping=&MENULEFT;&MENURIGHT; 周回データ Escキーで戻ります。
[ScreenSelectGame]
HeaderText=シミュレートするゲームの選択
@@ -1615,6 +1630,7 @@ HeaderSubText=モードを選択してください。
%d edits cleared, %d errors.=%dシーケンス削除、%dエラー
%d failed=%d失敗
%d ignored=%d無視
+Bookkeeping data cleared.=クレジット履歴を削除しました。
Copied from P%d card:=P%dのメモリーカードからコピーしました。
Copied to P%d card:=P%dのメモリーカードへコピーしました。
Edits not cleared - No memory cards ready.=メモリーカードがありません。削除は失敗しました。
diff --git a/Themes/_fallback/Languages/nl.ini b/Themes/_fallback/Languages/nl.ini
index 4c6efaf854..09b10a0bc3 100644
--- a/Themes/_fallback/Languages/nl.ini
+++ b/Themes/_fallback/Languages/nl.ini
@@ -5,6 +5,7 @@ StepMania=StepMania
[LoadingWindow]
Couldn't open any loading windows.=Kon geen laad scherm openen.
Starting sound subsystem...=Start geluid subsysteem...
+Initializing bookkeeper...=Initialiseren van de boekhouder...
Starting lights subsystem...=Start licht subsysteem...
Loading game type...=Laad spel type...
Building song cache index...=Bouw nummer cache index...
@@ -330,10 +331,12 @@ BGBrightness=Beheerst hoe fel de achtergrond er uit ziet. Zet dit lager als je d
Background=Verander de opties voor welke achtergrond tijdens het spelen zichtbaar is.
BarDrain=BalkDrain
BatLives=BatLevens
+Bookkeeping=Bekijk de ingeworpen munt statistieken.
Calibrate Machine Sync=Stel de geluid synchronisatie af.
CelShadeModels=Kies of de dansende karakters getekend worden met cel shading.
Center Image=Centreer het beeld op je monitor.
Characters=Karakters
+Clear Bookkeeping Data=Verwijder alle munt invoer data.
Clear Machine Edits=Sla alle stap wijzigingen op voor dit apparaat.
Clear USB edits=Verwijder alle USB wijzigingen.
Clear Machine Stats=Verwijder alle ranglijsten van deze machine.
@@ -817,6 +820,7 @@ BarDrain=Balk Leeglopen
BatLives=Bat Levens
Base Difficulty=Basis Niveau
Beat 0 Offset=Ritme 0 Offset
+Bookkeeping=Boekhouding
Calibrate Machine Sync=Kalibreer Geluid Synchronisatie
CPUSkill=CPU Bekwaamheid
CelShadeModels=Cel-shaded Modelen
@@ -826,6 +830,7 @@ Characters=Karakters
Chart Name=Stappen Kaart Naam
Chart Style=Stappen Kaart Stijl
Choose=Kies
+Clear Bookkeeping Data=Wis Boekhoud Data
Clear Machine Edits=Wis Machine Wijzigingen
Clear Machine Stats=Wis Machine Scores
Clear USB edits=Wis USB Wijzigingen
@@ -1217,6 +1222,15 @@ HeaderSubText=Haal de beste prestatie
HeaderText=Geavanceerde Opties
HeaderSubText=Deze settings zijn voor geavanceerde gebruikers
+[ScreenBookkeeping]
+All-time Coin Total:=Totaal Van Alle Munten:
+Total Song Plays: %d=Totaal Nummers Ooit Gespeeld: %d
+Coin Data by Day of Week, All-Time=Munt Data Per Dag Van De Week
+Coin Data by Hour of Day, All-Time=Munt Data Per Uur Van De Week
+Coin Data of Last %d Days=Munt Data Van De Laatste %d Dagen
+Coin Data of Last %d Weeks=Munt Data Van De Laatste %d Weken
+HeaderText=Boekhouding
+
[ScreenCaution]
Caution=KIJK UIT!
CautionText=Zet het dansplatform op een veilige afstand van je scherm en meubels.\n\nWees voorzichtig dat je geen dieren, kinderen of omstanders bezeert.
@@ -1569,6 +1583,7 @@ HelpTextTextEntry=Type een waarden met het toetsenbord. Druk op Enter als je kl
HelpTextMapControllers=Gebruik de pijlen om te bewegen, ENTER om toe te wijzen, SPATIE om leeg te maken::Druk ESCAPE als je klaar bent
HelpTextOnline=smonline.us om te verbinden met de officiële StepMania Online Server::Bekijk Stepmaniaonline.com voor meer informatie.
HelpTextNetSelectMusic=Ctrl + Enter ga een kamer in/selecteer nummer:: &UP; voor Speler Opties
+HelpTextBookkeeping=Druk &MENULEFT;&MENURIGHT; om data te doorlopen. Druk op ESCAPE als je klaar bent.
[ScreenSelectGame]
HeaderText=Selecteer Spel
@@ -1608,6 +1623,7 @@ HeaderSubText=Laten we beginnen. Ik weet dat je het kan!
%d edits cleared, %d errors.=%d bewerkingen geklaard, %d problemen.
%d failed=%d gefaald
%d ignored=%d genegeerd
+Bookkeeping data cleared.=Boekhouding data opgeschoond
Copied from P%d card:=Gekopieerd van P%d kaart:
Copied to P%d card:=Gekopieerd naar P%d kaart:
Edits not cleared - No memory cards ready.=Bewerkingen niet geklaard - Geen geheugenkaart klaar.
diff --git a/Themes/_fallback/Languages/pl.ini b/Themes/_fallback/Languages/pl.ini
index d8c5b1cf1d..6947726a43 100755
--- a/Themes/_fallback/Languages/pl.ini
+++ b/Themes/_fallback/Languages/pl.ini
@@ -5,6 +5,7 @@ StepMania=StepMania PL
[LoadingWindow]
Couldn't open any loading windows.=Nie udało się otowrzyć żadnego okna ładowania.
Starting sound subsystem...=Uruchamianie podsystemu dźwięku...
+Initializing bookkeeper...=Inicjalizacja modułu statystyk...
Starting lights subsystem...=Uruchamianie podsystemu świateł...
Loading game type...=Ładowanie modelu gry...
Building song cache index...=Tworzenie indeksu bufora piosenek...
@@ -327,10 +328,12 @@ BGBrightness=Ustala poziom jasność filmów odtwarzanych w tle piosenki. Zmniej
Background=Zmienia opcje kontrolujące tła odtwarzanych w trakcie gry.
BarDrain=Zużycie Energii
BatLives=Ilość pasków baterii
+Bookkeeping=Statystyka rzuconych żetonów/monet/kredytów.
Calibrate Machine Sync=Kalibracja synchronizacji dźwięku.
CelShadeModels=Decyduje czy Postacie Tańczące w tle są generowane z użyciem algorytmu Cel Shading.
Center Image=Centrowanie obrazu monitora.
Characters=Tańczące Postacie
+Clear Bookkeeping Data=Zerowanie statystyk wrzuconych żetonów/monet/kredytów.
Clear Machine Edits=Usunięcie wszystkich edycji kroków wgranych na maszynę.
Clear USB edits=Zerowanie plików programu na pamięci USB
Clear Machine Stats=Usunięcie wszystkich statystyk zapisanych na maszynie.
@@ -819,6 +822,7 @@ BarDrain=Zużycie Energii
BatLives=Ilość pasków Baterii
Base Difficulty=Podstawowy Poziom
Beat 0 Offset=Beat 0 Offset
+Bookkeeping=Statystyka
Calibrate Machine Sync=Kalibracja Synchronizacji Dźwięku
CPUSkill=Poziom CPU
CelShadeModels=Cel-shadedowane Modele
@@ -828,6 +832,7 @@ Characters=Tancerze
Chart Name=Nazwa Chart`a
Chart Style=Styl Chart`a
Choose=Wybierz
+Clear Bookkeeping Data=Czyść dane wyrzutnika monet
Clear Machine Edits=Czyść Zmodyfikowane Układy
Clear Machine Stats=Czyść dane statystyczne
Clear USB edits=Czyść Zmodyfikowane Układy na USB
@@ -1221,6 +1226,15 @@ HeaderSubText=Ustaw najlepszą wydajność
HeaderText=Opcje Zaawansowane
HeaderSubText=Ustawienia przeznaczone dla zaawansowanych użytkowników
+[ScreenBookkeeping]
+All-time Coin Total:=Suma Wszystkich Monet:
+Total Song Plays: %d=Liczba Odegranych piosenek: %d
+Coin Data by Day of Week, All-Time=Wszystkie Monety z podz. na dni tygodnia
+Coin Data by Hour of Day, All-Time=Wszystkie Monety z podz. na godziny
+Coin Data of Last %d Days=Monety z Ostatnich %d Dni
+Coin Data of Last %d Weeks=Monety z Ostatnich %d Tygodni
+HeaderText=Statystyki
+
[ScreenCaution]
Caution=UWAGA!
CautionText=Zadbaj by mata taneczna znajdowała się w bezpiecznej odległości od monitora i mebli.\n\nZwraóć uwagę by podczas tańca nie skrzywdzić zwierząt, dzieci i obserwatorów
@@ -1581,6 +1595,7 @@ HelpTextTextEntry=Wpisz wartość przy użyciu klawiatury. Naciśnij Enter by za
HelpTextMapControllers=Użyj klawiszy strzałek do nawigacji, ENTER by przydzielić, SPACJĘ by wyczyścić pole::Naciśnij ESCAPE by zakończyć.
HelpTextOnline=setepmaniaonline.eu by połączyć sięz oficjalnym Europejskim Serwerem Stepmania Online.:: Sprawdź www.stepmaniaonline.eu w celu rejestracji konta.
HelpTextNetSelectMusic=Ctrl + Enter by wybrać pokój/piosenkę::&UP; Opcje Gracza
+HelpTextBookkeeping=Naciśnij &MENULEFT;&MENURIGHT; by przeglądać dane. Naciśnij ESCAPE by zakończyć.
[ScreenSelectGame]
HeaderText=Wybierz Grę
@@ -1621,6 +1636,7 @@ HeaderSubText=Zaczynajmy. Na pewno dasz radę.
%d edits cleared, %d errors.=%d edycji wyczyszczono, %d błędów.
%d failed=%d niewczytano
%d ignored=%d zignowowano
+Bookkeeping data cleared.=Statystyki wyczyszczone.
Copied from P%d card:=Skopiowane z karty P%d:
Copied to P%d card:=Skopiowane na kartę P%d:
Edits not cleared - No memory cards ready.=Edycje nieusunięte - Brak karty.
diff --git a/Themes/_fallback/base._ini b/Themes/_fallback/base._ini
index 07f7273042..07f875edf4 100644
--- a/Themes/_fallback/base._ini
+++ b/Themes/_fallback/base._ini
@@ -2217,6 +2217,27 @@ Fallback="ScreenOptionsServiceChild"
NextScreen=NextNetworkScreen()
PrevScreen=NextNetworkScreen()
+[ScreenBookkeeping]
+Class="ScreenBookkeeping"
+Fallback="ScreenOptionsServiceChild"
+NextScreen="ScreenOptionsService"
+PrevScreen="ScreenOptionsService"
+HelpText=ScreenString("HelpTextBookkeeping")
+ShowSongPlays=true
+ShowLastDays=true
+ShowLastWeeks=true
+ShowDayOfWeek=true
+ShowHourOfDay=true
+AllTimeX=SCREEN_CENTER_X
+AllTimeY=110
+AllTimeOnCommand=zoom,0.7;diffuseshift;effectcolor1,0.5,0.5,0.5,1
+TitleX=SCREEN_CENTER_X
+TitleY=140
+TitleOnCommand=zoom,0.8
+DataX=0
+DataY=SCREEN_CENTER_Y+16
+DataOnCommand=
+
[ScreenPackages]
Class="ScreenPackages"
PackagesBGY=SCREEN_CENTER_Y
diff --git a/Themes/_portKit-sm4/metrics.ini b/Themes/_portKit-sm4/metrics.ini
index 9faae82c0d..9bd0f54a35 100644
--- a/Themes/_portKit-sm4/metrics.ini
+++ b/Themes/_portKit-sm4/metrics.ini
@@ -2250,6 +2250,27 @@ Fallback="ScreenOptionsServiceChild"
NextScreen=NextNetworkScreen()
PrevScreen=NextNetworkScreen()
+[ScreenBookkeeping]
+Class="ScreenBookkeeping"
+Fallback="ScreenOptionsServiceChild"
+NextScreen="ScreenOptionsService"
+PrevScreen="ScreenOptionsService"
+HelpText=ScreenString("HelpTextBookkeeping")
+ShowSongPlays=true
+ShowLastDays=true
+ShowLastWeeks=true
+ShowDayOfWeek=true
+ShowHourOfDay=true
+AllTimeX=SCREEN_CENTER_X
+AllTimeY=110
+AllTimeOnCommand=zoom,0.7;diffuseshift;effectcolor1,color("0.5,0.5,0.5,1")
+TitleX=SCREEN_CENTER_X
+TitleY=140
+TitleOnCommand=zoom,0.8
+DataX=0
+DataY=SCREEN_CENTER_Y+16
+DataOnCommand=
+
[ScreenPackages]
Class="ScreenPackages"
PackagesBGY=SCREEN_CENTER_Y
diff --git a/Xcode/stepmania_xcode4.3.xcodeproj/project.pbxproj b/Xcode/stepmania_xcode4.3.xcodeproj/project.pbxproj
index cfa3e28389..7fa3ac33e4 100644
--- a/Xcode/stepmania_xcode4.3.xcodeproj/project.pbxproj
+++ b/Xcode/stepmania_xcode4.3.xcodeproj/project.pbxproj
@@ -401,7 +401,9 @@
AA29CE310558741A00961A51 /* PercentageDisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAD620A5052EC78B00D02EE9 /* PercentageDisplay.cpp */; };
AA29CE320558741A00961A51 /* ScoreDisplayPercentage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AA6DAF0805300B3D00D02EE9 /* ScoreDisplayPercentage.cpp */; };
AA29CE340558741A00961A51 /* ScreenTestInput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAC622FA05389A0500D02EE9 /* ScreenTestInput.cpp */; };
+ AA29CE350558741A00961A51 /* ScreenBookkeeping.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AADBE360053D5F8A00D02EE9 /* ScreenBookkeeping.cpp */; };
AA29CE360558741A00961A51 /* ScreenNameEntryTraditional.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AADBE362053D5F8A00D02EE9 /* ScreenNameEntryTraditional.cpp */; };
+ AA29CE370558741A00961A51 /* Bookkeeper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AADBE368053DA38C00D02EE9 /* Bookkeeper.cpp */; };
AA29CE380558741A00961A51 /* GraphDisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAFF551D0549F39700D02EE9 /* GraphDisplay.cpp */; };
AA29CE390558741A00961A51 /* ComboGraph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAFF55210549F43A00D02EE9 /* ComboGraph.cpp */; };
AA29CE3A0558741A00961A51 /* Attack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAFF5541054E736D00D02EE9 /* Attack.cpp */; };
@@ -616,7 +618,9 @@
AA40D28E09A08D650068C0D5 /* PercentageDisplay.h in Headers */ = {isa = PBXBuildFile; fileRef = AAD620A6052EC78B00D02EE9 /* PercentageDisplay.h */; };
AA40D28F09A08D650068C0D5 /* ScoreDisplayPercentage.h in Headers */ = {isa = PBXBuildFile; fileRef = AA6DAF0905300B3D00D02EE9 /* ScoreDisplayPercentage.h */; };
AA40D29109A08D650068C0D5 /* ScreenTestInput.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC622FB05389A0500D02EE9 /* ScreenTestInput.h */; };
+ AA40D29209A08D650068C0D5 /* ScreenBookkeeping.h in Headers */ = {isa = PBXBuildFile; fileRef = AADBE361053D5F8A00D02EE9 /* ScreenBookkeeping.h */; };
AA40D29309A08D650068C0D5 /* ScreenNameEntryTraditional.h in Headers */ = {isa = PBXBuildFile; fileRef = AADBE363053D5F8A00D02EE9 /* ScreenNameEntryTraditional.h */; };
+ AA40D29409A08D650068C0D5 /* Bookkeeper.h in Headers */ = {isa = PBXBuildFile; fileRef = AADBE369053DA38C00D02EE9 /* Bookkeeper.h */; };
AA40D29509A08D650068C0D5 /* GraphDisplay.h in Headers */ = {isa = PBXBuildFile; fileRef = AAFF551E0549F39700D02EE9 /* GraphDisplay.h */; };
AA40D29609A08D650068C0D5 /* ComboGraph.h in Headers */ = {isa = PBXBuildFile; fileRef = AAFF55220549F43A00D02EE9 /* ComboGraph.h */; };
AA40D29709A08D650068C0D5 /* Attack.h in Headers */ = {isa = PBXBuildFile; fileRef = AAFF5542054E736D00D02EE9 /* Attack.h */; };
@@ -932,7 +936,9 @@
AA40D44409A08D650068C0D5 /* PercentageDisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAD620A5052EC78B00D02EE9 /* PercentageDisplay.cpp */; };
AA40D44509A08D650068C0D5 /* ScoreDisplayPercentage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AA6DAF0805300B3D00D02EE9 /* ScoreDisplayPercentage.cpp */; };
AA40D44709A08D650068C0D5 /* ScreenTestInput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAC622FA05389A0500D02EE9 /* ScreenTestInput.cpp */; };
+ AA40D44809A08D650068C0D5 /* ScreenBookkeeping.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AADBE360053D5F8A00D02EE9 /* ScreenBookkeeping.cpp */; };
AA40D44909A08D650068C0D5 /* ScreenNameEntryTraditional.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AADBE362053D5F8A00D02EE9 /* ScreenNameEntryTraditional.cpp */; };
+ AA40D44A09A08D650068C0D5 /* Bookkeeper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AADBE368053DA38C00D02EE9 /* Bookkeeper.cpp */; };
AA40D44B09A08D650068C0D5 /* GraphDisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAFF551D0549F39700D02EE9 /* GraphDisplay.cpp */; };
AA40D44C09A08D650068C0D5 /* ComboGraph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAFF55210549F43A00D02EE9 /* ComboGraph.cpp */; };
AA40D44D09A08D650068C0D5 /* Attack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAFF5541054E736D00D02EE9 /* Attack.cpp */; };
@@ -3057,8 +3063,12 @@
AADB4E8C04D50FB900D02EE9 /* SignalHandler.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; path = SignalHandler.h; sourceTree = ""; };
AADB4E8F04D5263200D02EE9 /* arch_setup.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; path = arch_setup.h; sourceTree = ""; };
AADB4F5904D9220700D02EE9 /* Crash.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; path = Crash.h; sourceTree = ""; };
+ AADBE360053D5F8A00D02EE9 /* ScreenBookkeeping.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; name = ScreenBookkeeping.cpp; path = ../src/ScreenBookkeeping.cpp; sourceTree = ""; };
+ AADBE361053D5F8A00D02EE9 /* ScreenBookkeeping.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; name = ScreenBookkeeping.h; path = ../src/ScreenBookkeeping.h; sourceTree = ""; };
AADBE362053D5F8A00D02EE9 /* ScreenNameEntryTraditional.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; name = ScreenNameEntryTraditional.cpp; path = ../src/ScreenNameEntryTraditional.cpp; sourceTree = ""; };
AADBE363053D5F8A00D02EE9 /* ScreenNameEntryTraditional.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; name = ScreenNameEntryTraditional.h; path = ../src/ScreenNameEntryTraditional.h; sourceTree = ""; };
+ AADBE368053DA38C00D02EE9 /* Bookkeeper.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; name = Bookkeeper.cpp; path = ../src/Bookkeeper.cpp; sourceTree = ""; };
+ AADBE369053DA38C00D02EE9 /* Bookkeeper.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; name = Bookkeeper.h; path = ../src/Bookkeeper.h; sourceTree = ""; };
AADD1CC2095C233E0088C9DF /* LocalizedString.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; name = LocalizedString.cpp; path = ../src/LocalizedString.cpp; sourceTree = ""; };
AADD1CC3095C233F0088C9DF /* LocalizedString.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; name = LocalizedString.h; path = ../src/LocalizedString.h; sourceTree = ""; };
AAE2D6D30A67481E00071546 /* ScoreKeeper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScoreKeeper.cpp; path = ../src/ScoreKeeper.cpp; sourceTree = ""; };
@@ -3631,6 +3641,8 @@
AA6E000B047711F3005F316C /* Screen.h */,
AA6E0010047711F3005F316C /* ScreenAttract.cpp */,
AA6E0011047711F3005F316C /* ScreenAttract.h */,
+ AADBE360053D5F8A00D02EE9 /* ScreenBookkeeping.cpp */,
+ AADBE361053D5F8A00D02EE9 /* ScreenBookkeeping.h */,
AA2CA89D0BB745BD002441E9 /* ScreenContinue.cpp */,
AA2CA89E0BB745BD002441E9 /* ScreenContinue.h */,
AA07A5550843E72B00E33D21 /* ScreenDebugOverlay.cpp */,
@@ -3788,6 +3800,8 @@
children = (
AA6E00FF0477128A005F316C /* AnnouncerManager.cpp */,
AA6E01000477128A005F316C /* AnnouncerManager.h */,
+ AADBE368053DA38C00D02EE9 /* Bookkeeper.cpp */,
+ AADBE369053DA38C00D02EE9 /* Bookkeeper.h */,
AA77E74508B64B1400FA24CA /* CharacterManager.cpp */,
AA77E74608B64B1400FA24CA /* CharacterManager.h */,
AAC0BFDF0E2951EC00F56EEB /* CryptHelpers.cpp */,
@@ -5628,7 +5642,9 @@
AA40D28E09A08D650068C0D5 /* PercentageDisplay.h in Headers */,
AA40D28F09A08D650068C0D5 /* ScoreDisplayPercentage.h in Headers */,
AA40D29109A08D650068C0D5 /* ScreenTestInput.h in Headers */,
+ AA40D29209A08D650068C0D5 /* ScreenBookkeeping.h in Headers */,
AA40D29309A08D650068C0D5 /* ScreenNameEntryTraditional.h in Headers */,
+ AA40D29409A08D650068C0D5 /* Bookkeeper.h in Headers */,
AA40D29509A08D650068C0D5 /* GraphDisplay.h in Headers */,
AA40D29609A08D650068C0D5 /* ComboGraph.h in Headers */,
AA40D29709A08D650068C0D5 /* Attack.h in Headers */,
@@ -6614,7 +6630,9 @@
AA29CE310558741A00961A51 /* PercentageDisplay.cpp in Sources */,
AA29CE320558741A00961A51 /* ScoreDisplayPercentage.cpp in Sources */,
AA29CE340558741A00961A51 /* ScreenTestInput.cpp in Sources */,
+ AA29CE350558741A00961A51 /* ScreenBookkeeping.cpp in Sources */,
AA29CE360558741A00961A51 /* ScreenNameEntryTraditional.cpp in Sources */,
+ AA29CE370558741A00961A51 /* Bookkeeper.cpp in Sources */,
AA29CE380558741A00961A51 /* GraphDisplay.cpp in Sources */,
AA29CE390558741A00961A51 /* ComboGraph.cpp in Sources */,
AA29CE3A0558741A00961A51 /* Attack.cpp in Sources */,
@@ -7015,7 +7033,9 @@
AA40D44409A08D650068C0D5 /* PercentageDisplay.cpp in Sources */,
AA40D44509A08D650068C0D5 /* ScoreDisplayPercentage.cpp in Sources */,
AA40D44709A08D650068C0D5 /* ScreenTestInput.cpp in Sources */,
+ AA40D44809A08D650068C0D5 /* ScreenBookkeeping.cpp in Sources */,
AA40D44909A08D650068C0D5 /* ScreenNameEntryTraditional.cpp in Sources */,
+ AA40D44A09A08D650068C0D5 /* Bookkeeper.cpp in Sources */,
AA40D44B09A08D650068C0D5 /* GraphDisplay.cpp in Sources */,
AA40D44C09A08D650068C0D5 /* ComboGraph.cpp in Sources */,
AA40D44D09A08D650068C0D5 /* Attack.cpp in Sources */,
diff --git a/src/Bookkeeper.cpp b/src/Bookkeeper.cpp
new file mode 100644
index 0000000000..e1137f52f5
--- /dev/null
+++ b/src/Bookkeeper.cpp
@@ -0,0 +1,261 @@
+#include "global.h"
+#include "Bookkeeper.h"
+#include "RageUtil.h"
+#include "RageLog.h"
+#include "IniFile.h"
+#include "GameConstantsAndTypes.h"
+#include "SongManager.h"
+#include "RageFile.h"
+#include "XmlFile.h"
+#include "XmlFileUtil.h"
+#include
+
+Bookkeeper* BOOKKEEPER = NULL; // global and accessable from anywhere in our program
+
+static const RString COINS_DAT = "Save/Coins.xml";
+
+Bookkeeper::Bookkeeper()
+{
+ ClearAll();
+ ReadFromDisk();
+}
+
+Bookkeeper::~Bookkeeper()
+{
+ WriteToDisk();
+}
+
+#define WARN_AND_RETURN { LOG->Warn("Error parsing at %s:%d",__FILE__,__LINE__); return; }
+
+void Bookkeeper::ClearAll()
+{
+ m_mapCoinsForHour.clear();
+}
+
+bool Bookkeeper::Date::operator<( const Date &rhs ) const
+{
+ if( m_iYear != rhs.m_iYear )
+ return m_iYear < rhs.m_iYear;
+ if( m_iDayOfYear != rhs.m_iDayOfYear )
+ return m_iDayOfYear < rhs.m_iDayOfYear;
+ return m_iHour < rhs.m_iHour;
+}
+
+void Bookkeeper::Date::Set( time_t t )
+{
+ tm ltime;
+ localtime_r( &t, <ime );
+
+ Set( ltime );
+}
+
+void Bookkeeper::Date::Set( tm pTime )
+{
+ m_iHour = pTime.tm_hour;
+ m_iDayOfYear = pTime.tm_yday;
+ m_iYear = pTime.tm_year + 1900;
+}
+
+void Bookkeeper::LoadFromNode( const XNode *pNode )
+{
+ if( pNode->GetName() != "Bookkeeping" )
+ {
+ LOG->Warn( "Error loading bookkeeping: unexpected \"%s\"", pNode->GetName().c_str() );
+ return;
+ }
+
+ const XNode *pData = pNode->GetChild( "Data" );
+ if( pData == NULL )
+ {
+ LOG->Warn( "Error loading bookkeeping: Data node missing" );
+ return;
+ }
+
+ FOREACH_CONST_Child( pData, day )
+ {
+ Date d;
+ if( !day->GetAttrValue( "Hour", d.m_iHour ) ||
+ !day->GetAttrValue( "Day", d.m_iDayOfYear ) ||
+ !day->GetAttrValue( "Year", d.m_iYear ) )
+ {
+ LOG->Warn( "Incomplete date field" );
+ continue;
+ }
+
+ int iCoins;
+ day->GetTextValue( iCoins );
+
+ m_mapCoinsForHour[d] = iCoins;
+ }
+}
+
+XNode* Bookkeeper::CreateNode() const
+{
+ XNode *xml = new XNode( "Bookkeeping" );
+
+ {
+ XNode* pData = xml->AppendChild("Data");
+
+ for( map::const_iterator it = m_mapCoinsForHour.begin(); it != m_mapCoinsForHour.end(); ++it )
+ {
+ int iCoins = it->second;
+ XNode *pDay = pData->AppendChild( "Coins", iCoins );
+
+ const Date &d = it->first;
+ pDay->AppendAttr( "Hour", d.m_iHour );
+ pDay->AppendAttr( "Day", d.m_iDayOfYear );
+ pDay->AppendAttr( "Year", d.m_iYear );
+ }
+ }
+
+ return xml;
+}
+
+void Bookkeeper::ReadFromDisk()
+{
+ if( !IsAFile(COINS_DAT) )
+ return;
+
+ XNode xml;
+ if( !XmlFileUtil::LoadFromFileShowErrors(xml, COINS_DAT) )
+ return;
+
+ LoadFromNode( &xml );
+}
+
+void Bookkeeper::WriteToDisk()
+{
+ // Write data. Use SLOW_FLUSH, to help ensure that we don't lose coin data.
+ RageFile f;
+ if( !f.Open(COINS_DAT, RageFile::WRITE|RageFile::SLOW_FLUSH) )
+ {
+ LOG->Warn( "Couldn't open file \"%s\" for writing: %s", COINS_DAT.c_str(), f.GetError().c_str() );
+ return;
+ }
+
+ auto_ptr xml( CreateNode() );
+ XmlFileUtil::SaveToFile( xml.get(), f );
+}
+
+void Bookkeeper::CoinInserted()
+{
+ Date d;
+ d.Set( time(NULL) );
+
+ ++m_mapCoinsForHour[d];
+}
+
+// Return the number of coins between [beginning,ending).
+int Bookkeeper::GetNumCoinsInRange( map::const_iterator begin, map::const_iterator end ) const
+{
+ int iCoins = 0;
+
+ while( begin != end )
+ {
+ iCoins += begin->second;
+ ++begin;
+ }
+
+ return iCoins;
+}
+
+int Bookkeeper::GetNumCoins( Date beginning, Date ending ) const
+{
+ return GetNumCoinsInRange( m_mapCoinsForHour.lower_bound( beginning ),
+ m_mapCoinsForHour.lower_bound( ending ) );
+}
+
+int Bookkeeper::GetCoinsTotal() const
+{
+ return GetNumCoinsInRange( m_mapCoinsForHour.begin(), m_mapCoinsForHour.end() );
+}
+
+void Bookkeeper::GetCoinsLastDays( int coins[NUM_LAST_DAYS] ) const
+{
+ time_t lOldTime = time(NULL);
+ tm time;
+ localtime_r( &lOldTime, &time );
+
+ time.tm_hour = 0;
+
+ for( int i=0; i::const_iterator it = m_mapCoinsForHour.begin(); it != m_mapCoinsForHour.end(); ++it )
+ {
+ const Date &d = it->first;
+ int iDayOfWeek = GetDayInYearAndYear( d.m_iDayOfYear, d.m_iYear ).tm_wday;
+ coins[iDayOfWeek] += it->second;
+ }
+}
+
+void Bookkeeper::GetCoinsByHour( int coins[HOURS_IN_DAY] ) const
+{
+ memset( coins, 0, sizeof(int) * HOURS_IN_DAY );
+ for( map::const_iterator it = m_mapCoinsForHour.begin(); it != m_mapCoinsForHour.end(); ++it )
+ {
+ const Date &d = it->first;
+
+ if( d.m_iHour >= HOURS_IN_DAY )
+ {
+ LOG->Warn( "Hour %i >= %i", d.m_iHour, HOURS_IN_DAY );
+ continue;
+ }
+
+ coins[d.m_iHour] += it->second;
+ }
+}
+
+/*
+ * (c) 2003-2005 Chris Danford, Glenn Maynard
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons to
+ * whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
+ * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
diff --git a/src/Bookkeeper.h b/src/Bookkeeper.h
new file mode 100644
index 0000000000..cddef0b9f6
--- /dev/null
+++ b/src/Bookkeeper.h
@@ -0,0 +1,93 @@
+#ifndef Bookkeeper_H
+#define Bookkeeper_H
+
+#include "DateTime.h"
+#include