Better Pop'n Music Peace support
This commit is contained in:
parent
c64efa5860
commit
1f5b0368ca
@ -219,7 +219,7 @@ This should be given the same config file as "api", "frontend" and "services".
|
||||
Development version of an eAmusement protocol server using flask and the protocol
|
||||
libraries also used in "bemanishark" and "trafficgen". Currently it lets most modern
|
||||
BEMANI games boot and supports full profile and events for Beatmania IIDX 20-26,
|
||||
Pop'n Music 19-24, Jubeat Saucer, Saucer Fulfill, Prop, Qubell and Clan, Sound Voltex
|
||||
Pop'n Music 19-25, Jubeat Saucer, Saucer Fulfill, Prop, Qubell and Clan, Sound Voltex
|
||||
1, 2, 3 Season 1/2 and 4, Dance Dance Revolution X2, X3, 2013, 2014 and Ace, MÚSECA 1,
|
||||
MÚSECA 1+1/2, MÚSECA Plus, Reflec Beat, Limelight, Colette, groovin'!! Upper, Volzza
|
||||
1 and Volzza 2, Metal Gear Arcade, and finally The\*BishiBashi.
|
||||
@ -251,7 +251,7 @@ this will run through and attempt to verify simple operation of that service. No
|
||||
guarantees are made on the accuracy of the emulation though I've strived to be
|
||||
correct. In some cases, I will verify the response, and in other cases I will
|
||||
simply verify that certain things exist so as not to crash a real client. This
|
||||
currently generates traffic emulating Beatmania IIDX 20-26, Pop'n Music 19-24, Jubeat
|
||||
currently generates traffic emulating Beatmania IIDX 20-26, Pop'n Music 19-25, Jubeat
|
||||
Saucer, Fulfill, Prop, Qubell and Clan, Sound Voltex 1, 2, 3 Season 1/2 and 4, Dance
|
||||
Dance Revolution X2, X3, 2013, 2014 and Ace, The\*BishiBashi, MÚSECA 1 and MÚSECA 1+1/2,
|
||||
Reflec Beat, Reflec Beat Limelight, Reflec Beat Colette, groovin'!! Upper, Volzza 1 and
|
||||
@ -398,7 +398,7 @@ do that.
|
||||
### Pop'n Music
|
||||
|
||||
For Pop'n Music, get the game DLL from the version of the game you want to import and
|
||||
run a command like so. This network supports versions 19-24 so you will want to run this
|
||||
run a command like so. This network supports versions 19-25 so you will want to run this
|
||||
command once for every version, giving the correct DLL file:
|
||||
|
||||
```
|
||||
|
@ -1,13 +1,74 @@
|
||||
# vim: set fileencoding=utf-8
|
||||
from typing import Dict
|
||||
|
||||
from bemani.backend.popn.base import PopnMusicBase
|
||||
from bemani.backend.popn.usaneko import PopnMusicUsaNeko
|
||||
from bemani.common import VersionConstants
|
||||
|
||||
|
||||
class PopnMusicPeace(PopnMusicBase):
|
||||
class PopnMusicPeace(PopnMusicUsaNeko):
|
||||
|
||||
name = "Pop'n Music peace"
|
||||
version = VersionConstants.POPN_MUSIC_PEACE
|
||||
|
||||
# Biggest ID in the music DB
|
||||
GAME_MAX_MUSIC_ID = 1877
|
||||
|
||||
def previous_version(self) -> PopnMusicBase:
|
||||
return PopnMusicUsaNeko(self.data, self.config, self.model)
|
||||
|
||||
def get_phases(self) -> Dict[int, int]:
|
||||
# Event phases
|
||||
# TODO: Hook event mode settings up to the front end.
|
||||
return {
|
||||
# Default song phase availability (0-23)
|
||||
0: 23,
|
||||
# Unknown event (0-2)
|
||||
1: 2,
|
||||
# Unknown event (0-2)
|
||||
2: 2,
|
||||
# Unknown event (0-4)
|
||||
3: 4,
|
||||
# Unknown event (0-1)
|
||||
4: 1,
|
||||
# Enable Net Taisen, including win/loss display on song select (0-1)
|
||||
5: 1,
|
||||
# Enable NAVI-kun shunkyoku toujou, allows song 1608 to be unlocked (0-1)
|
||||
6: 1,
|
||||
# Unknown event (0-1)
|
||||
7: 1,
|
||||
# Unknown event (0-2)
|
||||
8: 2,
|
||||
# Daily Mission (0-2)
|
||||
9: 2,
|
||||
# NAVI-kun Song phase availability (0-30)
|
||||
10: 30,
|
||||
# Unknown event (0-1)
|
||||
11: 1,
|
||||
# Unknown event (0-2)
|
||||
12: 2,
|
||||
# Enable Pop'n Peace preview song (0-1)
|
||||
13: 1,
|
||||
# Unknown event (0-39)
|
||||
14: 39,
|
||||
# Unknown event (0-2)
|
||||
15: 2,
|
||||
# Unknown event (0-3)
|
||||
16: 3,
|
||||
# Unknown event (0-8)
|
||||
17: 8,
|
||||
# Unknown event (0-1)
|
||||
28: 1,
|
||||
# Unknown event (0-1)
|
||||
19: 1,
|
||||
# Unknown event (0-13)
|
||||
20: 13,
|
||||
# Pop'n event archive song phase availability (0-20)
|
||||
21: 20,
|
||||
# Unknown event (0-2)
|
||||
22: 2,
|
||||
# Unknown event (0-1)
|
||||
23: 1,
|
||||
# Unknown event (0-1)
|
||||
24: 1,
|
||||
}
|
@ -126,10 +126,10 @@ class PopnMusicUsaNeko(PopnMusicBase):
|
||||
self.update_machine_name(request.child_value('pcb_setting/name'))
|
||||
return Node.void('pcb24')
|
||||
|
||||
def __construct_common_info(self, root: Node) -> None:
|
||||
def get_phases(self) -> Dict[int, int]:
|
||||
# Event phases
|
||||
# TODO: Hook event mode settings up to the front end.
|
||||
phases = {
|
||||
return {
|
||||
# Default song phase availability (0-11)
|
||||
0: 11,
|
||||
# Unknown event (0-2)
|
||||
@ -160,11 +160,12 @@ class PopnMusicUsaNeko(PopnMusicBase):
|
||||
13: 1,
|
||||
}
|
||||
|
||||
for phaseid in phases:
|
||||
def __construct_common_info(self, root: Node) -> None:
|
||||
for phaseid in self.get_phases():
|
||||
phase = Node.void('phase')
|
||||
root.add_child(phase)
|
||||
phase.add_child(Node.s16('event_id', phaseid))
|
||||
phase.add_child(Node.s16('phase', phases[phaseid]))
|
||||
phase.add_child(Node.s16('phase', self.get_phases()[phaseid]))
|
||||
|
||||
# Gather course informatino and course ranking for users.
|
||||
course_infos, achievements, profiles = Parallel.execute([
|
||||
|
@ -371,6 +371,7 @@ class ImportPopn(ImportBase):
|
||||
'22': VersionConstants.POPN_MUSIC_LAPISTORIA,
|
||||
'23': VersionConstants.POPN_MUSIC_ECLALE,
|
||||
'24': VersionConstants.POPN_MUSIC_USANEKO,
|
||||
'25': VersionConstants.POPN_MUSIC_PEACE,
|
||||
}.get(version, -1)
|
||||
|
||||
if actual_version == VersionConstants.POPN_MUSIC_TUNE_STREET:
|
||||
@ -382,7 +383,7 @@ class ImportPopn(ImportBase):
|
||||
# Newer pop'n has charts for easy, normal, hyper, another
|
||||
self.charts = [0, 1, 2, 3]
|
||||
else:
|
||||
raise Exception("Unsupported Pop'n Music version, expected one of the following: 19, 20, 21, 22, 23, 24!")
|
||||
raise Exception("Unsupported Pop'n Music version, expected one of the following: 19, 20, 21, 22, 23, 24, 25!")
|
||||
|
||||
super().__init__(config, GameConstants.POPN_MUSIC, actual_version, no_combine, update)
|
||||
|
||||
@ -957,6 +958,104 @@ class ImportPopn(ImportBase):
|
||||
'I'
|
||||
)
|
||||
|
||||
# Decoding function for chart masks
|
||||
def available_charts(mask: int) -> Tuple[bool, bool, bool, bool, bool, bool]:
|
||||
return (
|
||||
mask & 0x0080000 > 0, # Easy chart bit
|
||||
True, # Always a normal chart
|
||||
mask & 0x1000000 > 0, # Hyper chart bit
|
||||
mask & 0x2000000 > 0, # Ex chart bit
|
||||
True, # Always a battle normal chart
|
||||
mask & 0x4000000 > 0, # Battle hyper chart bit
|
||||
)
|
||||
|
||||
elif self.version == VersionConstants.POPN_MUSIC_PEACE:
|
||||
# Based on M39:J:A:A:2020092800
|
||||
|
||||
# Normal offset for music DB, size
|
||||
offset = 0x2C7C78
|
||||
step = 172
|
||||
length = 1877
|
||||
|
||||
# Offset and step of file DB
|
||||
file_offset = 0x2B8010
|
||||
file_step = 32
|
||||
|
||||
# Standard lookups
|
||||
genre_offset = 0
|
||||
title_offset = 1
|
||||
artist_offset = 2
|
||||
comment_offset = 3
|
||||
english_title_offset = 4
|
||||
english_artist_offset = 5
|
||||
extended_genre_offset = -1
|
||||
charts_offset = 8
|
||||
folder_offset = 9
|
||||
|
||||
# Offsets for normal chart difficulties
|
||||
easy_offset = 12
|
||||
normal_offset = 13
|
||||
hyper_offset = 14
|
||||
ex_offset = 15
|
||||
|
||||
# Offsets for battle chart difficulties
|
||||
battle_normal_offset = 16
|
||||
battle_hyper_offset = 17
|
||||
|
||||
# Offsets into which offset to seek to for file lookups
|
||||
easy_file_offset = 18
|
||||
normal_file_offset = 19
|
||||
hyper_file_offset = 20
|
||||
ex_file_offset = 21
|
||||
battle_normal_file_offset = 22
|
||||
battle_hyper_file_offset = 23
|
||||
|
||||
packedfmt = (
|
||||
'<'
|
||||
'I' # Genre
|
||||
'I' # Title
|
||||
'I' # Artist
|
||||
'I' # Comment
|
||||
'I' # English Title
|
||||
'I' # English Artist
|
||||
'H' # ??
|
||||
'H' # ??
|
||||
'I' # Available charts mask
|
||||
'I' # Folder
|
||||
'I' # Event unlocks?
|
||||
'I' # Event unlocks?
|
||||
'B' # Easy difficulty
|
||||
'B' # Normal difficulty
|
||||
'B' # Hyper difficulty
|
||||
'B' # EX difficulty
|
||||
'B' # Battle normal difficulty
|
||||
'B' # Battle hyper difficulty
|
||||
'xx' # Unknown pointer
|
||||
'H' # Easy chart pointer
|
||||
'H' # Normal chart pointer
|
||||
'H' # Hyper chart pointer
|
||||
'H' # EX chart pointer
|
||||
'H' # Battle normal pointer
|
||||
'H' # Battle hyper pointer
|
||||
'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
|
||||
)
|
||||
|
||||
# Offsets into file DB for finding file and folder.
|
||||
file_folder_offset = 0
|
||||
file_name_offset = 1
|
||||
|
||||
filefmt = (
|
||||
'<'
|
||||
'I' # Folder
|
||||
'I' # Filename
|
||||
'I'
|
||||
'I'
|
||||
'I'
|
||||
'I'
|
||||
'I'
|
||||
'I'
|
||||
)
|
||||
|
||||
# Decoding function for chart masks
|
||||
def available_charts(mask: int) -> Tuple[bool, bool, bool, bool, bool, bool]:
|
||||
return (
|
||||
|
@ -94,6 +94,12 @@ def get_client(proto: ClientProtocol, pcbid: str, game: str, config: Dict[str, A
|
||||
pcbid,
|
||||
config,
|
||||
)
|
||||
if game == 'pnm-peace':
|
||||
return PopnMusicUsaNekoClient(
|
||||
proto,
|
||||
pcbid,
|
||||
config,
|
||||
)
|
||||
if game == 'jubeat-saucer':
|
||||
return JubeatSaucerClient(
|
||||
proto,
|
||||
@ -322,6 +328,12 @@ def mainloop(address: str, port: int, configfile: str, action: str, game: str, c
|
||||
'old_profile_model': "M39:J:B:A",
|
||||
'avs': "2.15.8 r6631",
|
||||
},
|
||||
'pnm-peace': {
|
||||
'name': "Pop'n Music peace",
|
||||
'model': "M39:J:B:A:2020092800",
|
||||
'old_profile_model': "M39:J:B:A",
|
||||
'avs': "2.15.8 r6631",
|
||||
},
|
||||
'jubeat-saucer': {
|
||||
'name': "Jubeat Saucer",
|
||||
'model': "L44:J:A:A:2014012802",
|
||||
@ -534,6 +546,7 @@ def main() -> None:
|
||||
'pnm-22': 'pnm-lapistoria',
|
||||
'pnm-23': 'pnm-eclale',
|
||||
'pnm-24': 'pnm-usaneko',
|
||||
'pnm-25': 'pnm-peace',
|
||||
'iidx-20': 'iidx-tricoro',
|
||||
'iidx-21': 'iidx-spada',
|
||||
'iidx-22': 'iidx-pendual',
|
||||
|
Loading…
Reference in New Issue
Block a user