├── BUGS ├── CREDITS ├── ChangeLog ├── HACKING ├── INSTALL ├── LICENSE ├── Makefile.general ├── Makefile.posix ├── README ├── TODO ├── announcer.py ├── arrows.py ├── colors.py ├── combos.py ├── config.py ├── constants.py ├── courses.py ├── courseselect.py ├── dance.py ├── desktop.pydance ├── docs ├── dance-spec.txt ├── dwi-hall-of-shame.txt ├── generate-toc.rb ├── images │ ├── cheappad.jpg │ ├── diff-indicator.jpg │ ├── emsusb2.jpg │ ├── endless.jpg │ ├── gameselect.jpg │ ├── joe-sis.jpg │ ├── keymap.jpg │ ├── menu.jpg │ ├── nonstop-picks.jpg │ ├── nonstop.jpg │ ├── options.jpg │ ├── ss-folder.jpg │ └── ss-song.jpg ├── ksf-format.txt ├── man │ ├── findbpm.1 │ └── pydance.6 └── manual.html ├── endless.py ├── error.py ├── fileparsers.py ├── fontfx.py ├── fonttheme.py ├── games.py ├── gameselect.py ├── gfxtheme.py ├── grades.py ├── gradescreen.py ├── i18n.py ├── icon.png ├── image-src ├── courseselect.xcf.bz2 ├── endless-bg.xcf.bz2 ├── gameselect.xcf.bz2 ├── go_ca.xcf ├── gradescreen.xcf.bz2 ├── new-pad-color.png.bz2 ├── new-pad.png.bz2 ├── options.xcf.bz2 ├── ready_ca.xcf ├── songinfoscreen.xcf.bz2 └── songselect.xcf.bz2 ├── images ├── bg.png ├── button.png ├── courseselect-bg.png ├── endless-bg.png ├── error-bg.png ├── gameselect-bg.png ├── go.png ├── go_ca.png ├── grade-bg.png ├── indicator.png ├── menu-bg.png ├── newss-bg.png ├── no-banner.png ├── option-bg.png ├── rating-a.png ├── rating-aa.png ├── rating-aaa.png ├── rating-b.png ├── rating-c.png ├── rating-d.png ├── rating-ee.png ├── rating-f.png ├── ready.png ├── ready_ca.png ├── select-3p.png ├── select-4p.png ├── select-5p.png ├── select-6p.png ├── select-8p.png ├── select-9p.png ├── select-dmx.png ├── select-endless.png ├── select-ez2.png ├── select-ez2real.png ├── select-nonstop.png ├── select-normal.png ├── select-panel.png ├── select-para.png └── songinfoscreen-bg.png ├── interface.py ├── judge.py ├── lifebars.py ├── listener.py ├── lyrics.py ├── macosx ├── English.lproj │ └── InfoPlist.strings ├── main.c ├── pyddr.pbproj │ └── project.pbxproj └── pyddr_Prefix.h ├── menudriver.py ├── menus.py ├── options.py ├── pad.py ├── player.py ├── po ├── Makefile └── ca.po ├── profile-pydance.sh ├── pydance.posix.cfg ├── pydance.py ├── pydance.win32.cfg ├── records.py ├── scores.py ├── setup.py ├── songselect.py ├── sound ├── assist-d.ogg ├── assist-l.ogg ├── assist-r.ogg ├── assist-u.ogg ├── back.ogg ├── clicked.ogg ├── loselife.ogg ├── menu.ogg └── move.ogg ├── stats.py ├── stepfilters.py ├── steps.py ├── themes ├── dj │ ├── djenzay │ │ ├── djtheme.cfg │ │ ├── negative │ │ │ ├── awful.ogg │ │ │ ├── dayjob.ogg │ │ │ ├── everyone.ogg │ │ │ ├── flailing.ogg │ │ │ ├── programming.ogg │ │ │ ├── rubber.ogg │ │ │ └── shameus.ogg │ │ ├── neutral │ │ │ ├── blur.ogg │ │ │ ├── moves.ogg │ │ │ └── way.ogg │ │ ├── positive │ │ │ ├── flow.ogg │ │ │ ├── harder.ogg │ │ │ ├── respect.ogg │ │ │ ├── scene.ogg │ │ │ └── sunshine.ogg │ │ └── rankings │ │ │ ├── aaa.ogg │ │ │ ├── better.ogg │ │ │ ├── disaster.ogg │ │ │ ├── doing.ogg │ │ │ ├── double.ogg │ │ │ ├── effort.ogg │ │ │ ├── fail.ogg │ │ │ ├── flawless.ogg │ │ │ ├── flawless2.ogg │ │ │ ├── gettingit.ogg │ │ │ ├── high.ogg │ │ │ ├── impressive.ogg │ │ │ ├── respectible.ogg │ │ │ ├── secondchances.ogg │ │ │ ├── sure.ogg │ │ │ └── tobe.ogg │ └── none │ │ └── djtheme.cfg ├── font │ ├── VL PGothic.cfg │ ├── VL-PGothic-Regular.ttf │ └── default.cfg └── gfx │ ├── 32x32 │ ├── ddresque.zip │ ├── default │ │ ├── arr_c_c_0.png │ │ ├── arr_c_c_1.png │ │ ├── arr_c_c_2.png │ │ ├── arr_c_k_0.png │ │ ├── arr_c_k_1.png │ │ ├── arr_c_k_2.png │ │ ├── arr_c_l_0.png │ │ ├── arr_c_l_1.png │ │ ├── arr_c_l_2.png │ │ ├── arr_n_c_0.png │ │ ├── arr_n_k_0.png │ │ ├── arr_n_l_0.png │ │ ├── arr_s_c_4.png │ │ ├── arr_s_k_4.png │ │ ├── arr_s_l_4.png │ │ ├── is-theme │ │ ├── lifebar.png │ │ ├── oni-bar.png │ │ └── oni-empty.png │ ├── dmxesque │ │ ├── arr_c_k_0.png │ │ ├── arr_c_l_0.png │ │ ├── arr_c_r_0.png │ │ ├── arr_c_z_0.png │ │ ├── arr_n_k_0.png │ │ ├── arr_n_l_0.png │ │ ├── arr_n_z_0.png │ │ ├── arr_s_k_4.png │ │ ├── arr_s_l_4.png │ │ ├── arr_s_z_4.png │ │ ├── is-theme │ │ ├── lifebar.png │ │ ├── oni-bar.png │ │ └── oni-empty.png │ └── ez2 │ │ ├── arr_c_d_0.png │ │ ├── arr_c_g_0.png │ │ ├── arr_c_k_0.png │ │ ├── arr_c_l_0.png │ │ ├── arr_c_r_0.png │ │ ├── arr_c_w_0.png │ │ ├── arr_c_z_0.png │ │ ├── arr_n_d_0.png │ │ ├── arr_n_g_0.png │ │ ├── arr_n_k_0.png │ │ ├── arr_n_l_0.png │ │ ├── arr_n_r_0.png │ │ ├── arr_n_w_0.png │ │ ├── arr_n_z_0.png │ │ ├── arr_s_d_4.png │ │ ├── arr_s_g_4.png │ │ ├── arr_s_k_4.png │ │ ├── arr_s_l_4.png │ │ ├── arr_s_r_4.png │ │ ├── arr_s_w_4.png │ │ ├── arr_s_z_4.png │ │ ├── is-theme │ │ ├── lifebar.png │ │ ├── oni-bar.png │ │ └── oni-empty.png │ ├── 48x48 │ ├── ddresque.zip │ └── default │ │ ├── arr_c_c_0.png │ │ ├── arr_c_c_1.png │ │ ├── arr_c_c_2.png │ │ ├── arr_c_k_0.png │ │ ├── arr_c_k_1.png │ │ ├── arr_c_k_2.png │ │ ├── arr_c_l_0.png │ │ ├── arr_c_l_1.png │ │ ├── arr_c_l_2.png │ │ ├── arr_n_c_0.png │ │ ├── arr_n_k_0.png │ │ ├── arr_n_l_0.png │ │ ├── arr_s_c_4.png │ │ ├── arr_s_k_4.png │ │ ├── arr_s_l_4.png │ │ ├── is-theme │ │ ├── lifebar.png │ │ ├── oni-bar.png │ │ └── oni-empty.png │ ├── 56x56 │ ├── default │ │ ├── arr_c_c_0.png │ │ ├── arr_c_c_1.png │ │ ├── arr_c_c_2.png │ │ ├── arr_c_k_0.png │ │ ├── arr_c_k_1.png │ │ ├── arr_c_k_2.png │ │ ├── arr_n_c_0.png │ │ ├── arr_n_k_0.png │ │ ├── arr_s_c_4.png │ │ ├── arr_s_k_4.png │ │ ├── is-theme │ │ ├── lifebar.png │ │ ├── oni-bar.png │ │ └── oni-empty.png │ ├── ez2 │ │ ├── arr_c_d_0.png │ │ ├── arr_c_g_0.png │ │ ├── arr_c_k_0.png │ │ ├── arr_c_l_0.png │ │ ├── arr_c_r_0.png │ │ ├── arr_c_w_0.png │ │ ├── arr_c_z_0.png │ │ ├── arr_n_d_0.png │ │ ├── arr_n_g_0.png │ │ ├── arr_n_k_0.png │ │ ├── arr_n_l_0.png │ │ ├── arr_n_r_0.png │ │ ├── arr_n_w_0.png │ │ ├── arr_n_z_0.png │ │ ├── arr_s_d_4.png │ │ ├── arr_s_g_4.png │ │ ├── arr_s_k_4.png │ │ ├── arr_s_l_4.png │ │ ├── arr_s_r_4.png │ │ ├── arr_s_w_4.png │ │ ├── arr_s_z_4.png │ │ ├── is-theme │ │ ├── lifebar.png │ │ ├── oni-bar.png │ │ └── oni-empty.png │ └── pumpesque.zip │ └── 64x64 │ ├── bryan.zip │ ├── ddresque.zip │ ├── default │ ├── arr_c_c_0.png │ ├── arr_c_c_1.png │ ├── arr_c_c_2.png │ ├── arr_c_k_0.png │ ├── arr_c_k_1.png │ ├── arr_c_k_2.png │ ├── arr_c_u_0.png │ ├── arr_c_u_1.png │ ├── arr_c_u_2.png │ ├── arr_n_c_0.png │ ├── arr_n_k_0.png │ ├── arr_n_u_0.png │ ├── arr_s_c_4.png │ ├── arr_s_d_4.png │ ├── arr_s_k_4.png │ ├── arr_s_l_4.png │ ├── arr_s_r_4.png │ ├── arr_s_u_4.png │ ├── is-theme │ ├── lifebar.png │ ├── oni-bar.png │ └── oni-empty.png │ ├── oldschool │ ├── arr_c_d_0.png │ ├── arr_c_d_1.png │ ├── arr_c_d_2.png │ ├── arr_c_g_0.png │ ├── arr_c_g_1.png │ ├── arr_c_g_2.png │ ├── arr_c_k_0.png │ ├── arr_c_k_1.png │ ├── arr_c_k_2.png │ ├── arr_c_l_0.png │ ├── arr_c_l_1.png │ ├── arr_c_l_2.png │ ├── arr_c_r_0.png │ ├── arr_c_r_1.png │ ├── arr_c_r_2.png │ ├── arr_c_u_0.png │ ├── arr_c_u_1.png │ ├── arr_c_u_2.png │ ├── arr_c_w_0.png │ ├── arr_c_w_1.png │ ├── arr_c_w_2.png │ ├── arr_c_z_0.png │ ├── arr_c_z_1.png │ ├── arr_c_z_2.png │ ├── arr_n_d_0.png │ ├── arr_n_d_1.png │ ├── arr_n_d_2.png │ ├── arr_n_d_3.png │ ├── arr_n_g_0.png │ ├── arr_n_g_1.png │ ├── arr_n_g_2.png │ ├── arr_n_g_3.png │ ├── arr_n_k_0.png │ ├── arr_n_k_1.png │ ├── arr_n_k_2.png │ ├── arr_n_k_3.png │ ├── arr_n_l_0.png │ ├── arr_n_l_1.png │ ├── arr_n_l_2.png │ ├── arr_n_l_3.png │ ├── arr_n_r_0.png │ ├── arr_n_r_1.png │ ├── arr_n_r_2.png │ ├── arr_n_r_3.png │ ├── arr_n_u_0.png │ ├── arr_n_u_1.png │ ├── arr_n_u_2.png │ ├── arr_n_u_3.png │ ├── arr_n_w_0.png │ ├── arr_n_w_1.png │ ├── arr_n_w_2.png │ ├── arr_n_w_3.png │ ├── arr_n_z_0.png │ ├── arr_n_z_1.png │ ├── arr_n_z_2.png │ ├── arr_n_z_3.png │ ├── arr_s_d_4.png │ ├── arr_s_d_5.png │ ├── arr_s_d_6.png │ ├── arr_s_d_7.png │ ├── arr_s_l_4.png │ ├── arr_s_l_5.png │ ├── arr_s_l_6.png │ ├── arr_s_l_7.png │ ├── arr_s_r_4.png │ ├── arr_s_r_5.png │ ├── arr_s_r_6.png │ ├── arr_s_r_7.png │ ├── arr_s_u_4.png │ ├── arr_s_u_5.png │ ├── arr_s_u_6.png │ ├── arr_s_u_7.png │ ├── is-theme │ ├── lifebar.png │ ├── oni-bar.png │ └── oni-empty.png │ ├── soloesque.zip │ └── vividesque.zip ├── ui.py ├── util.py └── utils ├── findbpm.py └── pyjoy.py /BUGS: -------------------------------------------------------------------------------- 1 | See the TODO file for information on what misfeatures have to be fixed. 2 | -------------------------------------------------------------------------------- /CREDITS: -------------------------------------------------------------------------------- 1 | http://icculus.org/pyddr/index.php 2 | Design & Programming by: 3 | Joe "piman" Wreschnig 4 | Brendan "P2E" Becker 5 | Pavel N. Krivitsky 6 | Music by: 7 | Brendan "theGREENzebra" Becker 8 | Emmett "Pajama Crisis" Plant 9 | Graphics by: Joe & Brendan 10 | Additional Code / Porting / Graphics: 11 | Brandon Bremen - www.raboof.net 12 | John Bafford - www.dshadow.com 13 | xsdg - www.cuodan.net/~xsdg 14 | Shandy Brown - sjbrown.users.geeky.net 15 | Stephane Bakhos - www.nuitari.org 16 | Daniel Rowell Faulkner - www.dftech.cwc.net 17 | Paul Crowley, Jon Åslund 18 | Colin Bennett, Nat Budin 19 | Bob Ippolito, Alex Malinovich 20 | Pete Shinners, Michael Urman 21 | David Young, Ben Zeigler 22 | David Dodge, Tom Grimes 23 | Brett Smith, Torbjörn Andersson 24 | Frank Foeth 25 | Stefan Kloe 26 | Carles Pina i Estany and Catux LUG 27 | Special Thanks: 28 | Pete Shinners - www.pygame.org 29 | Xiph.Org - www.xiph.org 30 | Icculus - www.icculus.org 31 | Testing / Evangelism / Ideas: 32 | Mathieu Doidy, Josh Franklin, 33 | Benjamin Geiger, Bryon Gill 34 | Alex Golden, Kevin Hemenway 35 | Kelli Ireland, Emily Nester 36 | Jeremy Nickurak, Dave Oftedal 37 | Matthew Sachs, Bryon Vandiver 38 | Philip Walls, Sam Yatchmenoff 39 | Catie Flick, Curtis Hogg 40 | Andrea Landaker, William Reading 41 | -------------------------------------------------------------------------------- /HACKING: -------------------------------------------------------------------------------- 1 | This is a rough outline of the pydance source code. It is not 2 | authoritative, and everything in it should checked against the real 3 | source code and comments. 4 | 5 | Basic Design Philosophies 6 | ------------------------- 7 | Everything should be strongly object-oriented. Code and data should be 8 | moved as much as possible into common parent classes. We should not 9 | sacrifice code clarity for speed except in extreme cases. 10 | 11 | Overview of Program Flow 12 | ------------------------ 13 | First pydance.py is started. constants.py is imported, and constants and 14 | some top-level variables are defined, such as the event handlers 15 | and the configuration files. 16 | 17 | From there pydance.py loads all files it finds it finds in the 'songdir' 18 | variable, using fileparsers.py. From there it calls menudriver.py, which 19 | instantiates the game's main menu. 20 | 21 | "Play Game" runs gameselect.py, which in turns runs songselect.py or 22 | endless.py. From there the code in optionscreen.py may be executed to 23 | change options, or dance.py will be run to start a game. 24 | 25 | dance.play takes the list of songs to play and the relevant configuration 26 | settings. It then instantiates the players (players.py) and has them 27 | play through the list of songs, calling dance.dance on each one. 28 | 29 | The players are in charge of managing their sprite groups, as well as 30 | creating and updating all the sprites in them. The dance.dance loop 31 | hands keypresses off to player, which in turn hands them off to Judge 32 | (judge.py). The judge rates the steps, and then the player sends the 33 | step rating and related information to all its "listeners" -- the lifebar, 34 | score, and so on. 35 | 36 | After the song list is over dance.play makes the grade screen, and 37 | then passes control back to endless/songselect. 38 | 39 | Exiting the main menu returns control to pydance.py, which writes the 40 | configuration file out and then exits the program. 41 | 42 | Naming Conventions 43 | ------------------ 44 | Class names LookLikeThis. Local variables and functions look_like_this, 45 | although short ones may for convenience looklikethis, or llt. 46 | 47 | Exceptions are to be used for exceptional circumstances only. They 48 | should not be used where an 'if' condition would suffice. 49 | 50 | Class names should begin with Abstract iff they are not to be instantiated, 51 | but are to provide functionality for subclasses. 52 | 53 | Private functions and variables should begin with _. Variables that 54 | begin with _ must be private. 55 | 56 | Use GvR's tuple/list distinction rather than the immutable vs. mutable one. 57 | This means sequences with different types in them should be tuples, and 58 | sequences with the same types should be lists (this means x,y coordinate 59 | pairs should be lists). 60 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | pydance INSTALLATION INSTRUCTIONS 2 | --------------------------------- 3 | 4 | pydance currently is known to run on Windows, Unix and GNU/Linux, and 5 | Mac OS X systems. In theory, it will run anywhere Pygame and Python do. 6 | pydance can be gotten from http://www.icculus.org/pyddr/get.php. 7 | 8 | This is the short version of the installation instructions. More detailed 9 | help (like how to install all the strange kinds of files pydance supports) 10 | can be found in docs/manual.html. 11 | 12 | In all installations, you need the following things: 13 | - A sufficiently recent SDL. 14 | - The [currently] latest SDL_mixer (1.2.5), with Vorbis support. 15 | - SMPEG, if you want bad MP3 support. 16 | - Libvorbis. 17 | - Python 2.3 or higher. 18 | - Pygame 1.5.6 or higher (1.5.5 is acceptable but may crash on some files). 19 | 20 | If you are running a Unix distribution, all these probably come with 21 | your OS. Otherwise, you can find them at http://www.libsdl.org, 22 | http://www.xiph.org, http://www.python.org, and http://www.pygame.org. 23 | 24 | Installing under Unix or GNU/Linux 25 | ---------------------------------- 26 | $ python setup.py 27 | $ su -c 'make install' 28 | 29 | The first step checks to make sure you have appropriate versions of 30 | Python and Pygame installed. The second one copies files into the 31 | appropriate places on your system (according to the GNU/Linux FHS). 32 | 33 | If you need to install it somewhere else, you can set DESTDIR (to 34 | install to an alternate root entirely), or PREFIX (which is /usr/local 35 | by default). 36 | 37 | The default configuration file looks in /usr/share/games/pydance/songs, 38 | /usr/local/share/games/pydance/songs, and ~/.pydance/songs for Ogg/MP3 39 | and step files. 40 | 41 | Installing under Windows 42 | ------------------------ 43 | X:\pydance> python setup.py 44 | 45 | That's it. Copy your song and step files to the same directory as pydance, 46 | or to a ..\songs directory. 47 | 48 | Optional Stuff 49 | -------------- 50 | pydance needs to convert a few odd encodings, like CP949, that aren't 51 | in the base Python installation. pydance will run without it, but your fonts 52 | will render incorrectly (they probably will anyway, since good free 53 | Korean/Japanese fonts are lacking). This means you should install 54 | http://sourceforge.net/projects/koco, which contains the CP949 iconv 55 | codec. 56 | 57 | If you have the Psyco optimizing compiler installed (http://psyco.sf.net), 58 | pydance will use it by default. Set 'usepsyco' to 0 to turn it off, which 59 | you'll need to do to report bugs. Psyco may give pydance a good speed boost, 60 | but it is IA32-only currently. 61 | 62 | Troubleshooting 63 | --------------- 64 | If you are having trouble with pydance, first check your OS distributor 65 | for updates. Debian and Gentoo GNU/Linux both have packages for pydance, 66 | and this is the recommended installation method for these systems. 67 | Also, visit http://www.icculus.org/pyddr/get.php and see if a new version 68 | has been released, or if there is a package for your platform. If that 69 | fails, drop by #pyddr on irc.freenode.net and see if anyone knows how 70 | to help you. However, if you ask for help, expect to answer a lot of 71 | questions about your OS and the software on it. In addition, if your 72 | OS is non-free (Microsoft Windows, Mac OS X, BeOS, or any of the non-free 73 | Linux distributions), and the problem is OS-specific, we won't be able to 74 | help. 75 | -------------------------------------------------------------------------------- /Makefile.general: -------------------------------------------------------------------------------- 1 | MANPAGES += docs/man 2 | UTILS += utils/findbpm.py 3 | ZIPMODS += config.py announcer.py fontfx.py menus.py menudriver.py gfxtheme.py songselect.py fileparsers.py colors.py player.py endless.py gradescreen.py lyrics.py steps.py util.py error.py options.py games.py judge.py dance.py stepfilters.py gameselect.py lifebars.py scores.py combos.py listener.py grades.py stats.py arrows.py pad.py ui.py courses.py records.py interface.py courseselect.py fonttheme.py i18n.py 4 | ALLMODS += $(ZIPMODS) constants.py 5 | 6 | DATA += themes images sound CREDITS 7 | 8 | clean: 9 | rm -f *.pyc pydance.zip 10 | 11 | distclean: clean 12 | rm -f pydance.cfg Makefile po/pydance.pot 13 | 14 | pydance.zip: 15 | zip pydance.zip $(ZIPMODS) 16 | 17 | uptrans: 18 | xgettext *.py -o po/pydance.pot 19 | -------------------------------------------------------------------------------- /Makefile.posix: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env make -f 2 | 3 | PREFIX ?= /usr/local 4 | 5 | LOCALESDIR ?= /share/locale 6 | 7 | all: 8 | 9 | include Makefile.general 10 | 11 | mo-generate: 12 | @(cd po/ && env LOCALESDIR=$(DESTDIR)$(PREFIX)$(LOCALESDIR) $(MAKE) generate) 13 | 14 | 15 | install: install-core install-data install-utils 16 | install -m 644 $(ALLMODS) $(DESTDIR)$(PREFIX)/share/games/pydance 17 | install -m 755 pydance.py $(DESTDIR)$(PREFIX)/share/games/pydance 18 | ln -sf ../share/games/pydance/pydance.py $(DESTDIR)$(PREFIX)/games/pydance 19 | @(cd po/ && env LOCALESDIR=$(DESTDIR)$(PREFIX)$(LOCALESDIR) $(MAKE) $@) 20 | 21 | install-core: 22 | install -d $(DESTDIR)$(PREFIX)/bin $(DESTDIR)$(PREFIX)/games $(DESTDIR)$(PREFIX)/share/games/pydance 23 | install -d $(DESTDIR)$(PREFIX)/share/games/pydance/songs 24 | install -d $(DESTDIR)$(PREFIX)/share/man/man1 $(DESTDIR)$(PREFIX)/share/man/man6 25 | 26 | install-utils: install-core 27 | for U in $(UTILS); do\ 28 | install -m 755 $$U `echo $(DESTDIR)$(PREFIX)/bin/$$U | sed 's/\.py//' | sed 's/utils\///'`;\ 29 | done 30 | 31 | install-data: install-core 32 | cp -R $(DATA) $(DESTDIR)$(PREFIX)/share/games/pydance 33 | cp docs/man/*.1 $(DESTDIR)$(PREFIX)/share/man/man1 34 | cp docs/man/*.6 $(DESTDIR)$(PREFIX)/share/man/man6 35 | cp pydance.posix.cfg pydance.cfg 36 | install -D -m 644 pydance.cfg $(DESTDIR)$(PREFIX)/etc/pydance.cfg 37 | 38 | install-zip: pydance.zip install-core install-data install-utils 39 | install -m 644 constants.py pydance.zip $(DESTDIR)$(PREFIX)/share/games/pydance 40 | install -m 755 pydance.py $(DESTDIR)$(PREFIX)/share/games/pydance 41 | ln -sf ../share/games/pydance/pydance.py $(DESTDIR)$(PREFIX)/games/pydance 42 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | About pydance -- http://icculus.org/pyddr/ 2 | ------------------------------------------ 3 | Have you ever gone to an arcade and seen some crazy girl busting moves 4 | on some sort of metal panel of sorts, or a guy making a fool of 5 | himself trying to dance without watching the screen? Well, that game 6 | is probably Dance Dance Revolution, or DDR for short, which has been a 7 | hit in Asian countries for awhile and is finally getting popular in 8 | Europe and North America. It might also have been a similar game, such 9 | as Pump It Up, or EZ2 Dancer. 10 | 11 | pydance lets you play these games, and others like them, on your 12 | computer, either with the keyboard or with a custom controller. What 13 | you do is watch the screen as colored arrows move up the screen. As 14 | soon as they cover up stationary arrows at the top, you step (or 15 | press) the corresponding direction, in time with the beat of the 16 | music. 17 | 18 | You don't need a dance mat to play pydance! It's a lot more fun if you 19 | do, but you can also use your keyboard or gamepad. 20 | 21 | System Requirements 22 | ------------------- 23 | These are rough guidelines. Depending on your graphical theme, 24 | operating system, and so on, these requirements can differ. Although 25 | it is possible to install and play pydance on systems slower than 26 | this, the frame rate (and input latency) will be high enough that it 27 | won't be much fun. 28 | 29 | Operating System 30 | GNU/Linux (Debian is the easiest to use with pydance), Mac OS X, 31 | or Windows 2000 or higher. If Windows is your OS of choice, we can't 32 | help you debug. If Mac OS X is your OS of choice, we'll have plenty of 33 | trouble as well, but it's likely to work in the end. 34 | Video Card 35 | A video card capable of doing 640x480x16bpp, which is most video 36 | cards made since 1995. More recent cards will be faster, but many old 37 | cards (ATI Radeon 7000, Matrox G200, nVidia TNT1) will be able to run 38 | pydance acceptably. 39 | Processor 40 | We recommend a 1 GHz IA32 or 600 MHz PPC processor, or better, for 41 | pydance. However, pydance will run acceptably on a P3-500 or 42 | equivalent. 43 | RAM 44 | At least 64MB is required. 128MB is very strongly 45 | recommended. pydance uses RAM to cache graphics, so more RAM means the 46 | UI will respond faster. 47 | Hard Disk Space 48 | pydance requires about 5MB (around 50MB if you don't already have 49 | Python, SDL, or Pygame installed) of hard drive space to 50 | install. Songs take 1MB to 6MB each, on average. If your RAM is low, 51 | you will also need hard drive space for swap. 52 | 53 | Getting pydance 54 | --------------- 55 | To get the latest version of pydance, visit the pydance download 56 | page at http://icculus.org/pyddr/get.php. It is available as a .zip or 57 | a .tar.gz file. The site also contains information about installing 58 | from packages for Debian, Mandrake, and Gentoo GNU/Linux, and also has 59 | a disk image for Mac OS X users. 60 | 61 | Otherwise, to run pydance, you can often just download the source, 62 | unpack it, and double click on pydance.py (or run ./pydance.py). The 63 | INSTALL file included with pydance has detailed installation 64 | instructions for Unix. 65 | 66 | Complete documentation is available in docs/manual.html. 67 | 68 | Contact 69 | ------- 70 | Two mailing lists exist for pydance, pyddr-discuss@lists.debian.org 71 | and pyddr-devel@lists.debian.org. The pydance manual has more 72 | information about them. 73 | 74 | If you don't want to sign up for a mailing list but do want to report 75 | a bug, you can email the Debian Bug Tracking System at 76 | submit@bugs.debian.org. The first line of your email should be 77 | "Package: pydance". 78 | 79 | pydance has an IRC channel, #pyddr, on irc.freenode.net. It is usually 80 | active, and can help you fix problems with pydance (if you've already 81 | tried the instructions in the manual, and the ones in the official 82 | FAQ). The main developers are in the channel as "Pavel" (Pavel 83 | Krivitsky) and "P2E" (Brendan Becker). This is not, however, a good 84 | place to report bugs, since they can get lost easily. 85 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | Required for 1.0 2 | ---------------- 3 | Empty "Bugs" section of BUGS file. 4 | No crashes or major bugs for 5 days after the last CVS check in. 5 | 6 | A Comprehensive List of Features for pydance 1.2 7 | (with ideas on how to do them) 8 | ------------------------------------------------ 9 | 10 | * UI Rework 11 | Not really the extent that I reworked it between 0.8 and 0.9, 12 | but tweak the existing ones, space them better, add more 13 | animation/fading/etc. This is kind of a vague goal, but I 14 | think at this point the UI should be developed iteratively. 15 | 16 | * Testing 17 | pydance has no regression or unit tests. It could. 18 | 19 | * Records in courses 20 | Your record in a course should be stored (best and "best passed"). 21 | 22 | * MP3 Support 23 | Pyxine, pymad, or waiting for libavcodec support in Pygame are 24 | all options here. Note that Pyxine doesn't give enough timing 25 | resolution by itself. 26 | 27 | * Hold Arrow Behavior 28 | You should have to start holding arrows roughly when they start; in 29 | the current version, you can just hold them down starting any time, 30 | and it counts. 31 | 32 | * Automatic handling of different step ratings 33 | This needs changes to the grading screen (to display them) and to 34 | the JudgingDisplay code, to handle them. 35 | 36 | * Hold Arrow Drawing 37 | Hold arrows should be split into three images, the top, the 38 | repeating/stretched part, and the bottom. This requires some 39 | big changes to all the themes, though. 40 | 41 | * Cleanup & Port to Python 2.3 42 | - See if "string" in otherstring will help anywhere. 43 | - Port pydance.log hackery to a Logger object! 44 | 45 | * Different game types for each player 46 | This is the biggest feature I want. Have a game type list (rather 47 | than single argument) passed to dance.play, probably in the 48 | playlist itself. The real trick is making a sane UI for this. 49 | 50 | * Modifiers in courses 51 | This requires players to reevaluate their modifiers between songs, 52 | which shouldn't be too difficult. It might even half-work for some 53 | modifiers already, but I haven't tested anything. 54 | 55 | * Combat (Disney-style / Dance Magic / Magic Dance) versus 56 | This needs basically the same as the above, but player modifiers 57 | need to be able to change even within songs (of course, if that 58 | works, so does the above). 59 | 60 | * Challenge mode 61 | This can probably be done in lifebars for various forms, or strange 62 | Stats objects that will affect gameplay. 63 | 64 | * Song Library 65 | Sort of like DDR Max 2 USA, the idea is to have a database of songs 66 | where you can just listen to them, or view information (like 67 | DESCRIPTION) about them. Bonus points if you can watch the step 68 | charts in the background or something. 69 | 70 | * No pad-based UI 71 | (Pavel) piman: Here's a minor feature request, before I forget: a 72 | menu option to disable the DDR mat for navigating through 73 | songs, leaving only the keyboard for that, and activating 74 | the mat only when actually "dancing". 75 | 76 | This might be better served by decoupling UI events and pad events 77 | entirely, and having two separate configurations. 78 | 79 | * Event rewrite 80 | We should use Pygame's Event objects internally, for all the events 81 | (UI, pad, and Listener). This is much better than the crap I wrote 82 | before, and means (esp. for Listeners) that we can add more information 83 | without having to rewrite many objects. 84 | 85 | * BG Animation 86 | This is probably a Sprite like BGMovie is now, but with complicated 87 | timing information about when to change. For good support of 88 | existing SM/DWI animations, we'll need avcodec support. 89 | 90 | * 4 Player Mode 91 | A lot of things in the pydance code assume 2 players. I like to 92 | think a lot doesn't too (I tried to generalize where possible), but 93 | it's all untested and I know there's a lot of work to do here. 94 | 95 | * Fix main menu code 96 | 390 lines of code are spent on the main menu, which is a million 97 | times simpler than any other UI in the game. 98 | 99 | * BMS parsing 100 | The BMS file format sucks to parse. However, many DDR steps come 101 | in it. We should be able to load it. Since its grammar is nothing 102 | like any other format, it will be a whole new section in fileparsers. 103 | We don't need keysounding support for 1.2. 104 | 105 | * Dynamic course creation 106 | pydance used to let you make a course in the song selector and play 107 | it. That's a good idea. 108 | 109 | * Configurable UI events 110 | The directions of a pad are configurable, but the UI events should be 111 | too (especially, at least, cancel and confirm). 112 | 113 | * Use a rational number for beat counting 114 | We should use rational numbers (i.e. (num, denom)) when generating 115 | Step objects, for accuracy. 116 | 117 | * MSD parsing 118 | The MSD format is a lot like the DWI format I think. pyDDR had an 119 | old msd2step.py. 120 | 121 | * Finish KSF parser. 122 | Specifically, do BPM changes. Though, KSF files thankfully are 123 | becomming less popular. 124 | 125 | * vFolders? 126 | (Pavel) piman: By the way, here is a feature idea: have a menu that 127 | controls which songs are displayed on the list. E.g. "don't 128 | display any songs that don't have steps with difficulty less 129 | than 6", or something like that. 130 | 131 | A good way to do this would be something like Evolution's vFolders 132 | that let you search for arbitrary criteria. It would also fit okay 133 | into the pydance UI ("New Folder", "Add Criteria"...) and current 134 | song selector. 135 | 136 | This would require arbitrary nesting of subfolders, maybe. 137 | 138 | (Pavel) piman: Makes sense... So an interesting possibility might be 139 | to have folders nested to a depth of 3 or so, with top-level 140 | folders being what "S" key does right now. 141 | 142 | * Song installer 143 | We should have a song package format that pydance should either be 144 | able to load directly, or have an install-dance-package.sh that 145 | does it. Similar things could exist for (trickier to install) DWI 146 | or SM files. 147 | 148 | * Metadata from songs 149 | The title, subtitle (VERSION), and artist can be gotten from the 150 | audio file itself. It might also be possible to embed a DWI-like 151 | syntax into an Ogg comment directly, and load that. But that's probably 152 | a bad idea. 153 | 154 | * File format convertor 155 | There should be something to convert DWI and SM files to .dance, and 156 | maybe the other way around. 157 | 158 | * Fix endless mode 159 | The UI is so ugly, and there should be more selection criteria. 160 | Maybe we should merge this with Nonstop mode and have a "Loop" 161 | checkbox. 162 | 163 | * FIXME: There are a lot of FIXMEs in the code. Some of them get 164 | obsoleted over time, but most will still need fixing. 165 | 166 | * Dynamic grade in the corner of the screen as you play. 167 | 168 | * Halfass step generator, record steps as you play and do best-fit. 169 | 170 | * Ability to skip songs during Endless. 171 | -------------------------------------------------------------------------------- /announcer.py: -------------------------------------------------------------------------------- 1 | import os, random, dircache 2 | import pygame 3 | 4 | from listener import Listener 5 | 6 | from constants import * 7 | 8 | class Announcer(Listener): 9 | 10 | def themes(cls): 11 | theme_list = [] 12 | for path in search_paths: 13 | checkpath = os.path.join(path, "themes", "dj") 14 | if os.path.isdir(checkpath): 15 | for name in dircache.listdir(checkpath): 16 | if os.path.isfile(os.path.join(checkpath, name, "djtheme.cfg")): 17 | theme_list.append(name) 18 | return theme_list 19 | 20 | themes = classmethod(themes) 21 | 22 | def __init__(self, name): 23 | self.sections = {} 24 | self.name = None 25 | self.author = None 26 | self.rev = None 27 | self.date = None 28 | filename = None 29 | for path in search_paths: 30 | if os.path.isfile(os.path.join(path,"themes","dj",name,"djtheme.cfg")): 31 | filename = os.path.join(path, "themes", "dj", name) 32 | if filename == None: 33 | raise SystemExit(_("E: Cannot load announcer theme '%s'.") % name) 34 | 35 | fi = file(os.path.join(filename, "djtheme.cfg"), "r") 36 | sec = "" 37 | self.lasttime = -1000000 38 | for line in fi: 39 | if line.isspace() or len(line) == 0 or line[0] == '#': pass 40 | elif line[0] == "[" and line.strip()[-1] == "]": 41 | sec = line.strip()[1:-1].lower() 42 | self.sections[sec] = [] 43 | elif sec == "announcer": 44 | key, val = line[:line.find(' ')], line[line.find(' ')+1:].strip() 45 | if key == "name": self.name = val 46 | elif key == "author": self.author = val 47 | elif key == "rev": self.rev = val 48 | elif key == "date": self.date = val 49 | else: 50 | self.sections[sec].append(os.path.join(filename, line.strip())) 51 | 52 | def __play(self, filename): 53 | if not os.path.isfile(filename): return 54 | if (pygame.time.get_ticks() - self.lasttime > 6000): 55 | snd = pygame.mixer.Sound(filename) 56 | snd.play() 57 | self.lasttime = pygame.time.get_ticks() 58 | 59 | def stepped(self, pid, dir, curtime, etime, rating, combo): 60 | if random.randrange(15) != 1: return 61 | rng = { "V": [80, 100], "P": [80, 100], 62 | "G": [70, 94], "O": [40, 69], 63 | "B": [20, 30], "M": [0, 19] }.get(rating, [0, 100]) 64 | self.say('ingame', rng) 65 | 66 | def say(self, sec, mood=(0, 100)): 67 | if not self.sections.has_key(sec) or len(self.sections[sec]) == 0: return 68 | l = len(self.sections[sec]) 69 | # Normalize mood wrt the number of choices 70 | try: 71 | mood = (int(mood[0] / 100.0 * l), min(int(mood[1] / 100.0 * l), l - 1)) 72 | except TypeError: 73 | # Use a random variance of 10% if a scalar is given 74 | mood = (int(max(mood / 100.0 - 0.1, 0) * l), # don't < 0 75 | int(min(mood / 100.0 + 0.1, 0.999) * l)) # don't == l 76 | 77 | self.__play(self.sections[sec][random.randint(mood[0], mood[1])]) 78 | -------------------------------------------------------------------------------- /colors.py: -------------------------------------------------------------------------------- 1 | # Colors and functions for working with colors 2 | 3 | color = { 4 | _('red'): [255, 0, 0], 5 | _('pink'): [255, 127, 127], 6 | _('yellow'): [255, 255, 0], 7 | _('green'): [0, 255, 0], 8 | _('cyan'): [0, 255, 255], 9 | _('blue'): [0, 0, 255], 10 | _('purple'): [255, 0, 255], 11 | _('orange'): [255, 127, 0], 12 | _('aqua'): [0, 255, 127], 13 | _('white'): [255, 255, 255], 14 | _('black'): [0, 0, 0], 15 | _('gray'): [127, 127, 127] 16 | } 17 | 18 | # We use these a lot, so save lookup time 19 | WHITE = color[_("white")] 20 | BLACK = color[_("black")] 21 | 22 | def brighten(color, diff = 64): 23 | return [min(x + diff, 255) for x in color] 24 | 25 | def darken(color, diff = 64): 26 | return [max(x - diff, 0) for x in color] 27 | 28 | def darken_div(color, div = 3.5): 29 | return [x / div for x in color] 30 | 31 | def average(clr1, clr2, w = 0.5): 32 | return [int((c1 * w + c2 * (1 - w))) for c1, c2 in zip(clr1, clr2)] 33 | -------------------------------------------------------------------------------- /combos.py: -------------------------------------------------------------------------------- 1 | # Combo counting. 2 | 3 | import pygame 4 | 5 | from listener import Listener 6 | from constants import * 7 | from fonttheme import FontTheme 8 | 9 | class AbstractCombo(Listener, pygame.sprite.Sprite): 10 | 11 | def __init__(self, playernum, game): 12 | pygame.sprite.Sprite.__init__(self) 13 | self._sticky = mainconfig['stickycombo'] 14 | self._lowcombo = mainconfig['lowestcombo'] 15 | self.combo = 0 16 | self._laststep = 0 17 | self._centerx = game.sprite_center + (game.player_offset * playernum) 18 | self._top = 320 19 | 20 | fonts = [] 21 | fontfn, basesize = FontTheme.Dance_combo_display 22 | for x in range(11, 0, -1): 23 | fonts.append(pygame.font.Font(fontfn, basesize+int(x*1.82/28*basesize))) 24 | 25 | # Store each digit individually, to avoid long text rendering 26 | # times in the middle of the game. FIXME: This breaks above 9999 27 | # combo currently; the PCR has code for the same trick that scales 28 | # infinitely. 29 | self._words = [] 30 | for f in fonts: 31 | render = [] 32 | for w in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'x COMBO']: 33 | img1 = f.render(w, 1, [16, 16, 16]) 34 | img2 = f.render(w, 1, [224, 224, 224]) 35 | img3 = pygame.Surface(img1.get_size()) 36 | img3.blit(img1, [-2, 2]) 37 | img3.blit(img1, [2, -2]) 38 | img3.blit(img2, [0, 0]) 39 | img3.set_colorkey(img3.get_at([0, 0]), RLEACCEL) 40 | render.append(img3) 41 | self._words.append(render) 42 | self._space = pygame.surface.Surface([0, 0]) 43 | self.image = self._space 44 | 45 | def update(self, curtime): 46 | self._laststep = min(curtime, self._laststep) 47 | steptimediff = curtime - self._laststep 48 | 49 | if steptimediff < 0.36 or self._sticky: 50 | self._drawcount = self.combo 51 | drawsize = min(int(steptimediff * 50), len(self._words) - 1) 52 | if drawsize < 0: drawsize = 0 53 | else: 54 | self._drawcount = 0 55 | 56 | if self._drawcount >= self._lowcombo: 57 | render = self._words[drawsize] 58 | width = render[-1].get_width() 59 | thousands = self._drawcount / 1000 60 | hundreds = self._drawcount / 100 61 | tens = self._drawcount / 10 62 | ones = self._drawcount % 10 63 | if thousands: 64 | thousands = render[thousands % 10] 65 | width += thousands.get_width() 66 | if hundreds: 67 | hundreds = render[hundreds % 10] 68 | width += hundreds.get_width() 69 | if tens: 70 | tens = render[tens % 10] 71 | width += tens.get_width() 72 | ones = render[ones] 73 | width += ones.get_width() 74 | height = render[-1].get_height() 75 | self.image = pygame.surface.Surface([width, height]) 76 | self.image.set_colorkey(ones.get_at([0, 0]), RLEACCEL) 77 | left = 0 78 | if thousands: 79 | self.image.blit(thousands, [left, 0]) 80 | left+= thousands.get_width() 81 | if hundreds: 82 | self.image.blit(hundreds, [left, 0]) 83 | left += hundreds.get_width() 84 | if tens: 85 | self.image.blit(tens, [left, 0]) 86 | left += tens.get_width() 87 | self.image.blit(ones, [left, 0]) 88 | left += ones.get_width() 89 | r = self.image.blit(render[-1], [left, 0]) 90 | else : 91 | self.image = self._space 92 | 93 | self.rect = self.image.get_rect() 94 | self.rect.top = self._top 95 | self.rect.centerx = self._centerx 96 | 97 | # Breaks the combo on anything not a marvelous, perfect, or great. 98 | class NormalCombo(AbstractCombo): 99 | def stepped(self, pid, dir, curtime, etime, rating, combo): 100 | if rating is None: return 101 | self._laststep = curtime 102 | self.combo += { "V": 1, "P": 1, "G": 1 }.get(rating, -self.combo) 103 | 104 | # Breaks the combo on anything less than a great, but also doesn't 105 | # increase it for great. 106 | class OniCombo(AbstractCombo): 107 | def stepped(self, pid, dir, curtime, etime, rating, combo): 108 | if rating is None: return 109 | self._laststep = curtime 110 | self.combo += { "V": 1, "P": 1, "G": 0 }.get(rating, -self.combo) 111 | 112 | # Pump It Up-style combo; okays add to your combo too. 113 | class PumpCombo(AbstractCombo): 114 | def stepped(self, pid, dir, curtime, etime, rating, combo): 115 | if rating is None: return 116 | self._laststep = curtime 117 | self.combo += { "V": 1, "P": 1, "G": 1, "O": 1 }.get(rating, -self.combo) 118 | 119 | combos = [NormalCombo, OniCombo, PumpCombo] 120 | combo_opt = [ 121 | (0, _("Normal"), _("Greats or better increase a combo")), 122 | (1, _("Oni-style"), _("Greats don't increase a combo, but also don't break it")), 123 | (2, _("Pump It Up"), _("Okays or better increase a combo"))] 124 | -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | # A generic configuration file parser 2 | 3 | import os 4 | 5 | # master vs user: 6 | # the 'user' hash (~/.foorc) overrides the master hash (/etc/foorc), 7 | # if a value is present in the user hash. 8 | 9 | # When writing out, only things *not* equal to the master hash (or only 10 | # in the master hash) are written back out. 11 | 12 | class Config(object): 13 | # Start a config file, based off a hash - this hash is always a master set 14 | def __init__(self, data = None): 15 | self.user = {} 16 | self.master = {} 17 | if data != None: self.update(data, True) 18 | 19 | # Update with a dict object, instead of a file. 20 | def update(self, data, master = False): 21 | if master: self.master.update(data) 22 | else: self.user.update(data) 23 | 24 | def __getitem__(self, key): 25 | if key in self.user: return self.user[key] 26 | else: return self.master.get(key) 27 | 28 | def __setitem__(self, key, value, master = False): 29 | if master: self.master[key] = value 30 | else: self.user[key] = value 31 | 32 | def __delitem__(self, key): 33 | if key in self.master: del(self.master[key]) 34 | if key in self.user: del(self.user[key]) 35 | 36 | def get(self, key, value = None): 37 | if key in self.user: return self.user[key] 38 | else: return self.master.get(key, value) 39 | 40 | # Update the config data with a 'key value' filename. 41 | # If should_exist is true, raise exceptions if the file doesn't exist. 42 | # Otherwise, we silently ignore it. 43 | def load(self, filename, master = False, should_exist = False): 44 | d = self.user 45 | if master: d = self.master 46 | 47 | if not os.path.isfile(filename) and not should_exist: return 48 | 49 | fi = file(filename, "r") 50 | for line in fi: 51 | line = line.strip() 52 | if not line or line[0] == '#': pass # comment 53 | else: 54 | key = line[0:line.find(' ')] 55 | val = line[line.find(' ') + 1:].strip() 56 | # Try to cast the input to a nicer type 57 | try: d[key] = int(val) 58 | except ValueError: 59 | try: d[key] = float(val) 60 | except ValueError: d[key] = val 61 | 62 | fi.close() 63 | 64 | # Write the filename back out to disk. 65 | def write(self, filename): 66 | fi = file(filename, "w") 67 | keys = self.user.keys() 68 | keys.sort() 69 | for key in keys: 70 | if key not in self.master or self.master[key] != self.user[key]: 71 | fi.write("%s %s\n" % (key, self.user[key])) 72 | fi.close() 73 | -------------------------------------------------------------------------------- /constants.py: -------------------------------------------------------------------------------- 1 | # Constants used in the game and some simple initialization routines 2 | # This file should be kept as small as possible, probably. (But I seem 3 | # to be failing at doing that.) 4 | 5 | import sys 6 | import os 7 | import locale 8 | from string import maketrans 9 | 10 | from i18n import * 11 | 12 | VERSION = "1.1.0" 13 | 14 | try: locale.setlocale(locale.LC_ALL, '') 15 | except locale.Error: pass 16 | 17 | # Detect the name of the OS - Mac OS X is not really UNIX. 18 | osname = None 19 | if os.name == "nt": osname = "win32" 20 | elif os.name == "posix": 21 | if os.path.islink("/System/Library/CoreServices/WindowServer"): 22 | osname = "macosx" 23 | elif "HOME" in os.environ: 24 | osname = "posix" 25 | else: 26 | raise SystemExit( 27 | "Your platform is not supported by pydance. In particular, it\n" + 28 | "doesn't seem to be Win32, Mac OS X, or a Unix that sets $HOME.") 29 | 30 | # Find out our real directory - resolve symlinks, etc 31 | pydance_path = sys.argv[0] 32 | if osname == "posix": 33 | pydance_path = os.path.split(os.path.realpath(pydance_path))[0] 34 | else: pydance_path = os.path.split(os.path.abspath(pydance_path))[0] 35 | sys.path.insert(0, pydance_path) 36 | 37 | if os.path.exists(os.path.join(pydance_path, "pydance.zip")): 38 | sys.path.insert(0, os.path.join(pydance_path, "pydance.zip")) 39 | 40 | # Set up some names for commonly referenced directories 41 | image_path = os.path.join(pydance_path, "images") 42 | sound_path = os.path.join(pydance_path, "sound") 43 | 44 | # Set a name for our savable resource directory 45 | rc_path = None 46 | if osname == "posix": 47 | rc_path = os.path.join(os.environ["HOME"], ".pydance") 48 | elif osname == "macosx": 49 | rc_path = os.path.join(os.environ["HOME"], "Library", 50 | "Preferences", "pydance") 51 | elif osname == "win32": rc_path = "." 52 | 53 | if not os.path.isdir(rc_path): os.mkdir(rc_path) 54 | 55 | search_paths = (pydance_path, rc_path) 56 | 57 | if not sys.stdout.isatty(): 58 | sys.stdout = file(os.path.join(rc_path, "pydance.log"), "w") 59 | sys.stderr = sys.stdout 60 | 61 | import pygame 62 | import games 63 | import config 64 | import colors 65 | 66 | from pygame.locals import * 67 | 68 | # SDL_mixer is the bane of my existance. 69 | if osname == 'posix': # We need to force stereo in many cases. 70 | try: pygame.mixer.pre_init(44100, -16, 2) 71 | except pygame.error: pass 72 | 73 | # Set up the configuration file 74 | default_conf = { 75 | "fonttheme": "default", 76 | "djtheme": "djenzay", 77 | "songdir": os.pathsep.join([os.path.join(rc_path, "songs"), 78 | os.path.join(pydance_path, "songs")]), 79 | "coursedir": os.pathsep.join([os.path.join(rc_path, "courses"), 80 | os.path.join(pydance_path, "courses")]), 81 | "stickycombo": 1, "lowestcombo": 4, "stickyjudge": 1, 82 | "lyriccolor": "cyan/aqua", 83 | "onboardaudio": 0, "masteroffset": 0, 84 | "explodestyle": 3, "vesacompat": 0, "fullscreen": 0, 85 | "sortmode": 0, 86 | "folders": 1, 87 | "previewmusic": 1, 88 | "showbackground": 1, "bgbrightness": 127, 89 | "gratuitous": 1, 90 | "assist": 0, 91 | "fpsdisplay": 1, "showlyrics": 1, 92 | "showcombo": 1, 93 | "autofail": 1, 94 | "animation": 1, 95 | "grading": 1, 96 | "saveinput": 1, 97 | "strobe": 0, 98 | "usepsyco": 1, 99 | "autogen": 1, 100 | "centerconfirm": 1, 101 | "songinfoscreen": 1, 102 | 103 | # Player config 104 | "spin": 0, 105 | "accel": 0, 106 | "transform": 0, 107 | "scale": 1, 108 | "speed": 1.0, 109 | "fade": 0, 110 | "size": 0, 111 | "dark": 0, 112 | "jumps": 1, 113 | "holds": 1, 114 | "colortype": 4, 115 | "scrollstyle": 0, 116 | 117 | # Game options 118 | "battle": 0, 119 | "scoring": 0, 120 | "combo": 0, 121 | "grade": 0, 122 | "judge": 0, 123 | "judgescale": 1.0, 124 | "life": 1.0, 125 | "secret": 1, 126 | "lifebar": 0, 127 | "onilives": 3, 128 | } 129 | 130 | for game in games.GAMES.values(): 131 | default_conf["%s-theme" % game.theme] = game.theme_default 132 | 133 | mainconfig = config.Config(default_conf) 134 | 135 | if osname == "posix": 136 | mainconfig.load("/etc/pydance.cfg", True) 137 | elif osname == "macosx": 138 | mainconfig.load("/Library/Preferences/pydance/pydance.cfg", True) 139 | 140 | mainconfig.load("pydance.cfg") 141 | mainconfig.load(os.path.join(rc_path, "pydance.cfg")) 142 | mainconfig["sortmode"] %= 6 143 | 144 | player_config = dict([(k, mainconfig[k]) for k in 145 | ["spin", "accel", "transform", "scale", "speed", 146 | "fade", "size", "dark", "jumps", "holds", "colortype", 147 | "scrollstyle"]]) 148 | 149 | game_config = dict([(k, mainconfig[k]) for k in 150 | ["battle", "scoring", "combo", "grade", "judge", 151 | "judgescale", "life", "secret", "lifebar", "onilives"]]) 152 | 153 | 154 | # The list of options that are safe to change between songs on a 155 | # playlist 156 | # Each tuple has the following entries: 157 | # 0. Option "key", like the one used in the options.OPTIONS dictionary 158 | # 1. A dictionary of option values that require special displaying: 159 | # the key is the value of the option and the value is a string that 160 | # should be shown on the song info screen if that option is 161 | # selected. If there is no key for a particular option, the string 162 | # that is displayed for that value in the option menu is used. 163 | # E.g. for the "jumps" option, value 0 will map to "No Jumps" while 164 | # value 2 is not in the dictionary so will display "Wide". 165 | 166 | changeable_between = [('speed', {}), 167 | ('transform', {}), 168 | ('size', {}), 169 | ('fade', {}), 170 | ('accel', {}), 171 | ('scale', {}), 172 | ('scrollstyle', {}), 173 | ('jumps', {0:"No Jumps"}), 174 | ('spin', {1:"Spin"}), 175 | ('colortype', {}), 176 | ('dark', {1:"Dark"}), 177 | ('holds', {0:"No Holds"}) 178 | ] 179 | 180 | 181 | pygame.init() 182 | 183 | # The different colors pydance uses for difficulties in the UI. 184 | DIFF_COLORS = { "BEGINNER": colors.color[_("white")], 185 | "LIGHT": colors.color[_("orange")], 186 | "EASY": colors.color[_("orange")], 187 | "BASIC": colors.color[_("orange")], 188 | "STANDARD": colors.color[_("red")], 189 | "STANDER": colors.color[_("red")], # Shit you not, 3 people. 190 | "TRICK": colors.color[_("red")], 191 | "MEDIUM": colors.color[_("red")], 192 | "DOUBLE": colors.color[_("red")], 193 | "ANOTHER": colors.color[_("red")], 194 | "PARA": colors.color[_("blue")], 195 | "NORMAL": colors.color[_("red")], 196 | "MANIAC": colors.color[_("green")], 197 | "HARD": colors.color[_("green")], 198 | "HEAVY": colors.color[_("green")], 199 | "HARDCORE": colors.color[_("purple")], 200 | "SMANIAC": colors.color[_("purple")], 201 | "S-MANIAC": colors.color[_("purple")], # Very common typo 202 | "CHALLENGE": colors.color[_("purple")], 203 | "CRAZY": colors.color[_("purple")], 204 | "EXPERT": colors.color[_("purple")] 205 | } 206 | 207 | ZERO_ALPHA = maketrans(''.join([chr(x) for x in range(ord("a"),ord("z")+1)+range(ord("A"),ord("Z")+1)]),'0'*26*2) 208 | -------------------------------------------------------------------------------- /desktop.pydance: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Version=1.0 3 | Type=Application 4 | Encoding=UTF-8 5 | Name=pydance 6 | Icon=pydance.png 7 | GenericName=Dancing Game 8 | Exec=pydance 9 | Categories=Application;Game;ArcadeGame;Music 10 | -------------------------------------------------------------------------------- /docs/dwi-hall-of-shame.txt: -------------------------------------------------------------------------------- 1 | For those of us who hate the DWI format (which is everyone who ever 2 | tried to write a parser for it), I present the DWI Hall of Shame, 3 | where I mention personal information about people who write the 4 | stupidest possible files ever. 5 | 6 | TournaMix 2, "Peanuts Theme" by Eithug , AIM 7 | E1rt4u9. This file contains the phrase '...B!(60...'. What does this 8 | mean? Jump and then a 16th note later start to hold? Jump and then 9 | hold the left parenthesis? It's nonsense. 10 | 11 | DJ Taka's "M" by Christopher Emirzian , which 12 | contains a BPM change at the beat "894.8.3". The hell? 13 | 14 | Chris Danford, for the oh-so-classic Stepmania editor bug. This 15 | results in holds like '0!B' for a left+right jump and hold, or '4!6' 16 | for only holding the right arrow, which makes even less sense. 17 | 18 | And of course, SimWolf , for inventing a 19 | format that's so braindead. Thanks for the lack of a formal grammar, 20 | no encoding information, and double meanings of : and #, and writing 21 | proprietary code that somehow manages to parse all the absolute 22 | *SHIT* above. 23 | 24 | Oh, and for totally changing the meaning of <...> between versions to 25 | make it backwards and forwards incompatible. 26 | -------------------------------------------------------------------------------- /docs/generate-toc.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | level = 0 4 | toc_output = "" 5 | 6 | pre_toc = "" 7 | post_toc = "" 8 | 9 | pos = :pre_toc 10 | 11 | File.new("manual.html").each_line { |line| 12 | case pos 13 | when :pre_toc 14 | if line.include? '
' 15 | pos = :toc 16 | else 17 | pre_toc << line 18 | end 19 | when :toc 20 | if line.include? '
' 21 | pos = :post_toc 22 | end 23 | when :post_toc 24 | md = /(.*)<\/h/.match(line) 25 | if md 26 | l = md[1].to_i 27 | i = md[2] 28 | t = md[3] 29 | 30 | if level < l 31 | while level < l 32 | toc_output << "
    \n" 33 | level +=1 34 | end 35 | else 36 | while level > l 37 | toc_output << "\n
\n" 38 | level -=1 39 | end 40 | (toc_output.length > 0) and (toc_output << "\n") 41 | end 42 | toc_output << "
  • #{t}" 43 | end 44 | post_toc << line 45 | end 46 | } 47 | 48 | while level != 0 49 | level -= 1 50 | toc_output << "
  • \n" 51 | end 52 | 53 | f2 = File.open("manual.html", "w") 54 | 55 | f2.puts pre_toc 56 | f2.puts "
    \n" + toc_output + "\n
    " 57 | f2.puts post_toc 58 | f2.close 59 | -------------------------------------------------------------------------------- /docs/images/cheappad.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/docs/images/cheappad.jpg -------------------------------------------------------------------------------- /docs/images/diff-indicator.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/docs/images/diff-indicator.jpg -------------------------------------------------------------------------------- /docs/images/emsusb2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/docs/images/emsusb2.jpg -------------------------------------------------------------------------------- /docs/images/endless.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/docs/images/endless.jpg -------------------------------------------------------------------------------- /docs/images/gameselect.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/docs/images/gameselect.jpg -------------------------------------------------------------------------------- /docs/images/joe-sis.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/docs/images/joe-sis.jpg -------------------------------------------------------------------------------- /docs/images/keymap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/docs/images/keymap.jpg -------------------------------------------------------------------------------- /docs/images/menu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/docs/images/menu.jpg -------------------------------------------------------------------------------- /docs/images/nonstop-picks.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/docs/images/nonstop-picks.jpg -------------------------------------------------------------------------------- /docs/images/nonstop.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/docs/images/nonstop.jpg -------------------------------------------------------------------------------- /docs/images/options.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/docs/images/options.jpg -------------------------------------------------------------------------------- /docs/images/ss-folder.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/docs/images/ss-folder.jpg -------------------------------------------------------------------------------- /docs/images/ss-song.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/docs/images/ss-song.jpg -------------------------------------------------------------------------------- /docs/ksf-format.txt: -------------------------------------------------------------------------------- 1 | Documentation on the KSF Format 2 | ------------------------------- 3 | The KSF format is designed for representing steps for 5 panel diagonal 4 | dancing games, such as Pump It Up. It was originally used in the Kick It Up 5 | simulator, but can also be parsed by other programs. However, this seems 6 | to be the only actual format description available. 7 | 8 | The intention of this document is not to encourage creation of KSF files. 9 | I believe the format to be broken, and provide this reference only for 10 | people wishing to implement legacy file readers. Any new 5 panel dancing 11 | patterns should use a well-defined format such as .dance or .sm. 12 | 13 | Directory Layout 14 | ---------------- 15 | KSF filenames are case-insensitive. 16 | 17 | A KSF directory contains the following files: 18 | 19 | - At least one file matching *.KSF, containing the step data. 20 | - A file named SONG.MP3, SONG.WAV, or SONG.OGG. 21 | - A file named INTRO.MP3, INTRO.WAV, or INTRO.OGG, containing a sound clip, 22 | used to preview the song in song selectors. 23 | - Disc.bmp, a 300x200 image used in song selectors. 24 | - Back.bmp or Title.bmp, a 640x480 image used as a background during the song. 25 | 26 | KSF directories may not have a special naming format, but some simulators 27 | will use the directory name to get the artist and title name, if it's not 28 | available in the KSF files themseleves. The format is "Title", 29 | "Title - Artist", or "Title - Artist - Difficulty". Difficulty can be 30 | ignored here, as it can be gotten from the KSF filename. Using the path 31 | name to determine the metadata for the song should only be used if it's 32 | not available in #TITLE. 33 | 34 | Concievably other audio or image formats could be used. None have been 35 | seen in the wild. 36 | 37 | KSF Filenames 38 | ------------- 39 | KSF filenames describe the game type and difficulty. Each file holds the 40 | data for only one level of difficulty. There are two possible forms of 41 | the name: **.ksf, or *_*.ksf. 42 | 43 | The first type is used for double mode, and half-double mode. Double.ksf 44 | contains the steps for "Double" mode, where one player uses both paths. 45 | Stepmania supports Halfdouble.ksf, which ignores the outer 4 panels. 46 | 47 | The latter type is used for single ("unison", which is not the same 48 | as Dance Dance Revolution's Unison mode in early mixes) steps, where both 49 | players have the same steps, and couple steps, where players have different 50 | ones. If the player number is 1, they are single steps; if it's 2, they're 51 | couple steps. Difficulty is a difficulty name. 52 | 53 | KSF Headers 54 | ----------- 55 | The basic KSF format is similar to DWI, SM, and MSD. Metadata is given 56 | in the format of: 57 | #TAGNAME:VALUE; 58 | 59 | The exception being the #STEPS tag, which has a newline between the ":" 60 | and the first line of steps, and ends in "2222222222222" on a line by 61 | itself instead of ";". 62 | 63 | KSF files seem to use CRLF (Windows-style) line termination. The vast 64 | majority of KSF files are in CP942/KSC 5601 encoding, but some are 65 | in EUC-KR. If ASCII alternatives are needed for these encodings, the 66 | path name must be checked as above. 67 | 68 | Common headers in KSF files are as follows: 69 | 70 | #TITLE: The artist and title of the song, and sometimes the difficulty. 71 | These are separated by " - "s, so the format is either "Title", 72 | "Artist - Title", or "Artist - Title - Difficulty". Information missing 73 | from this line can be filled in via path or file names. 74 | 75 | #BPM: The BPM of the song. This is analogous to the BPM value for every other 76 | dance format. 77 | 78 | #STARTTIME: The time into the song to offset events, in centiseconds. This 79 | is the opposite of .dance's gap and .sm's offset, and the same as .dwi's 80 | gap (although they use different units). 81 | 82 | #TICKCOUNT: Each step line specifies 1/TICKCOUNT beats. That is, if 83 | TICKCOUNT is 1, each line is the equivalent of a 'q' in .dance. If it's 84 | 2, each line is the same as a normal length note in DWI (an 'e' in .dance). 85 | 86 | #STEP: Until a line of "2222222222222" is encountered, each line after this 87 | one represents a set of steps. 88 | 89 | Step Lines 90 | ---------- 91 | Each line in the step section represents one "line" of steps, like SM 92 | or .dance. Each line is 13 digits long; in single (unison) modes, only the 93 | first 5 are used; in couple and double, the first 10 are used. 94 | 95 | The order of the steps is Down Left, Up Left, Center, Up Right, Down Right. 96 | The second player's (or second pad in double) steps are the same order, 97 | but in positions 6-10 instead of 1-5. 98 | 99 | A 0 in a position indicates no step. A 1 indicates a regular step. A 4 100 | indicates a hold, for as long as a 4 is found in that column. The hold 101 | ends on the beat of the last 4, not on the first 0. 102 | 103 | Some files have been seen with repeated '1's in this manner as well; 104 | it is unknown if any dance simulator supports this use of KSF, and since 105 | a perfectly good non-ambiguous means of representing holds is available, 106 | its use is not recommended. 107 | 108 | A 2 (or a line of 13 2s) indicates the end of the step pattern. 109 | 110 | BPM Changes 111 | ----------- 112 | BPM changes are handled by header values; they are specified by a pair 113 | of values #BPMx and #BUNKIx, where x is an integer. An example is: 114 | 115 | #BPM:146.10; 116 | #BPM2:180.20; 117 | #BPM3:195.00; 118 | #TICKCOUNT:2; 119 | #STARTTIME:0; 120 | #BUNKI:4200; 121 | #BUNKI2:10000; 122 | 123 | BPMn+1 starts at the time specified in centiseconds by BUNKIn (where n 124 | is omitted if it is 1). In the above, 42 seconds (4200 centiseconds) 125 | into the song, the BPM changes from its initial 146.1 to 180.2, and 126 | then 100 seconds into the song, from 180.2 to 195. 127 | 128 | BUNKIs can be a decimal value. 129 | 130 | Syntax Exceptions 131 | ----------------- 132 | Unlike DWI files, KSF files seem to have few exceptions or violations of 133 | their syntax in the files seen in the wild. This may be because the format 134 | is so mind-numbingly stupid. 135 | 136 | Still Unknown 137 | ------------- 138 | Some files contain a #STARTTIMEx (like #BPMx or #BUNKIx). 139 | 140 | KSF step lines are 13 digits wide; only 10 digits appear to specify steps, 141 | but the last 3 are not always 0. They probably represent something. 142 | 143 | Author 144 | ------ 145 | This document was written by Joe Wreschnig . It is 146 | released into the public domain. 147 | 148 | Changes 149 | ------- 150 | 2003.08.15 151 | - Initial check in / release. 152 | 153 | Acknowledgements 154 | ---------------- 155 | This document is based primarily off of extensive work done by Matt Reppert. 156 | The Stepmania KSF loader source code (src/NotesLoaderKSF.cpp) also proved 157 | useful in verifying some information. 158 | -------------------------------------------------------------------------------- /docs/man/findbpm.1: -------------------------------------------------------------------------------- 1 | .TH findbpm 1 "June 26th, 2003" 2 | .SH NAME 3 | findbpm \- average keypresses over the length of a song to find the BPM 4 | .SH SYNOPSIS 5 | \fBfindbpm \fIsong.ogg\fR 6 | .SH DESCRIPTION 7 | This script plays a song file (in Ogg Vorbis or MP3 format) and lets you 8 | tap along on the spacebar, calculating the BPM (beats per minute) in the 9 | song as you go. It also gives you an offset in milliseconds of when 10 | you started tapping, compared to when the song started. You can then 11 | use these two values to create a step file for that song. 12 | .SH BUGS 13 | This is only as accurate as your sense of rhythm. :) 14 | .SH AUTHORS 15 | Brendan Becker and Joe Wreschnig . 16 | .SH SEE ALSO 17 | \fBpydance\fR(6) 18 | -------------------------------------------------------------------------------- /docs/man/pydance.6: -------------------------------------------------------------------------------- 1 | .TH pydance 6 "June 2nd, 2003" 2 | .SH NAME 3 | pydance \- a dancing simulator game 4 | .SH SYNOPSIS 5 | \fBpydance\fR [\fB\-\-filename \fIfilename \fR[ \fB\-\-mode\fI mode \fB\-\-difficulty\fI difficulty\fR ] ] 6 | .SH OPTIONS 7 | .IP \-\-help,\ \-h 8 | Display a brief summary of command line options. 9 | .IP \-\-version,\ \-v 10 | Display the version of pydance (and features found, e.g. Psyco). 11 | .IP \-\-filename\, \-f 12 | Load and play a single file, then quit. By default, this is in 13 | SINGLE (4 panel) mode, on BASIC difficulty. 14 | .IP \-\-mode,\ \-m 15 | Use a particular mode (e.g. VERSUS, 6PANEL, DMX). This only has an effect 16 | when you also use \fB\-\-filename\fR. 17 | .IP \-\-difficulty,\ \-d 18 | Use a particular difficulty (e.g. TRICK, SMANIAC). This only has an effect 19 | when you also use \fB\-\-filename\fR. 20 | .SH DESCRIPTION 21 | pydance is much like the popular arcade game "Dance Dance Revolution", in 22 | which you stand on a mat on the floor, with 4 buttons pointing forward, 23 | backwards, left, and right. Arrows scroll across the screen, and you must 24 | step on the arrows on the mat when they reach the top. These steps 25 | happen in time with music in the background, causing a rough approximation 26 | of dancing. 27 | .PP 28 | However, pydance also plays more than DDR - it can simulate games like 29 | Technomotion, Pop'n'Stage, Pump It Up, Para Para Paradise, and Dance ManiaX 30 | (also called Dance Freaks).a 31 | .PP 32 | pydance supports most of the features of these games, such as background 33 | and banner images for each song, multiple difficulty levels, freeze 34 | arrows (arrows you have to remain standing on for a length of time), BPM 35 | changes and stops, lyric displays, and so on. pydance also allows you to 36 | use a real DDR mat if you have a Playstation to PC joystick adapter supported 37 | by the ddrmat kernel module for Linux (which is a modified version of the 38 | gamecon kernel module), or a Playstation to USB joystick adapter and the USB 39 | joystick driver, for any OS. If you lack a mat, you can play on the 40 | keyboard, but it's much less fun. 41 | .PP 42 | You can also make your own step files to new music, in pydance's \fB.dance\fR 43 | format. \fIdance-spec.txt\fR included with pydance documents this format. 44 | pydance can also read the popular Windows \fB.dwi\fR and \fB.sm\fR formats. 45 | .SH USAGE 46 | The first player's arrows and settings are controlled by the I, J, ,, and L 47 | keys, and the second player's by the arrow keys. Enter starts a song or 48 | activates a menu item. 49 | .PP 50 | pydance is documented more completely in the \fIREADME.html\fR file included 51 | with it. 52 | .SH FILES 53 | .IP /usr/share/games/pydance/songs,\ /usr/local/share/games/pydance/songs,\ ~/.pydance/songs 54 | By default, pydance will look in these directories for your songs, step files, 55 | and other game data. You can configure this with the \fBsongdir\fR 56 | option in your pydance.cfg file. 57 | .IP 58 | Note that for DWI files, you will need to put everything (the music file, 59 | lyric file, background, and banner) in its own separate directory, and 60 | that directory inside \fIanother\fR subdirectory in the \fIsongs\fR 61 | folder. This is a limitation of the DWI format; it uses its path name 62 | and files in the same directory, rather than specifying things in the 63 | file itself like .dance files do. 64 | .IP /usr/share/games/pydance/courses,\ /usr/local/share/games/pydance/courses,\ ~/.pydance/courses 65 | Similar to above, but for course files. You can use \fBcoursedir\fR to 66 | override this. 67 | .IP /etc/pydance.cfg,\ ~/.pydance/pydance.cfg 68 | pydance configuration files. The settings in your local one override 69 | the system-wide settings. 70 | .IP ~/.pydance/records 71 | Your top scores for each song. This is a pickled Python file. It can be 72 | safely deleted to reset your scores. 73 | .IP ~/.pydance/input.cfg 74 | Your input settings. This is a pickled Python file. It can be safely 75 | deleted to reset your input configuration. 76 | .IP /usr/share/games/pydance 77 | Various data needed by pydance, such as background music and Python modules. 78 | .SH AUTHORS 79 | Brendan Becker , Joe Wreschnig , and Pavel Krivitsky , with help from many others. 80 | .PP 81 | Many of the other dancing games mentioned here are trademarks of their 82 | respective owners. 83 | .SH SEE ALSO 84 | \fBfindbpm\fR(1), 85 | README included with pydance, 86 | manual.html included with pydance, 87 | dance-spec.txt included with pydance. 88 | -------------------------------------------------------------------------------- /error.py: -------------------------------------------------------------------------------- 1 | # Put up a pretty error message. 2 | 3 | from interface import * 4 | from constants import mainconfig 5 | import fontfx 6 | import ui 7 | from fonttheme import FontTheme 8 | 9 | class ErrorMessage(InterfaceWindow): 10 | def __init__(self, screen, line): 11 | InterfaceWindow.__init__(self, screen, "error-bg.png") 12 | text = fontfx.shadow("Error!", FontTheme.error_message, [255, 255, 255], offset = 2) 13 | text_rect = text.get_rect() 14 | text_rect.center = [320, 50] 15 | screen.blit(text, text_rect) 16 | 17 | # FIXME: Remove this when I'm sure that nothing uses the old calling 18 | # method. (Pre-1.0) 19 | if isinstance(line, list): lines = " ".join(line) 20 | 21 | font = fontfx.WrapFont(FontTheme.error_message, 440) 22 | b = font.render(line, shdw = True, centered = True) 23 | r = b.get_rect() 24 | r.center = [320, 240] 25 | screen.blit(b, r) 26 | 27 | text = fontfx.shadow("Press Enter/Start/Escape", FontTheme.error_message, [160, 160, 160]) 28 | textpos = text.get_rect() 29 | textpos.center = [320, 440] 30 | screen.blit(text, textpos) 31 | 32 | pygame.display.update() 33 | ui.ui.clear() 34 | 35 | pid, ev = (0, ui.PASS) 36 | while ev not in [ui.START, ui.CONFIRM, ui.QUIT]: 37 | if ev == ui.FULLSCREEN: 38 | pygame.display.toggle_fullscreen() 39 | mainconfig["fullscreen"] ^= 1 40 | pid, ev = ui.ui.wait() 41 | -------------------------------------------------------------------------------- /fonttheme.py: -------------------------------------------------------------------------------- 1 | # Define and precompute font themes. 2 | 3 | import pygame 4 | from ConfigParser import * 5 | import os, dircache 6 | from constants import * 7 | 8 | # Find the appropriate font size to fit string into max_width pixels, 9 | # that's at most max_size, and at least 6. 10 | def max_size(font, string, max_width, max_size): 11 | for size in range(max_size, 0, -1): 12 | f = pygame.font.Font(font, size) 13 | if f.size(string)[0] < max_width: return f 14 | return pygame.font.Font(font, 6) 15 | 16 | class FontTheme: 17 | _themes = {} 18 | # These "purposes" only ever appear in one size, set by the theme. 19 | _FIXED_SIZE = ['help', 'SongSel_list', 'loading_screen', 20 | 'Menu_button_no_sub', 'Menu_button_if_sub', 21 | 'Menu_button_sub', 'Menu_rotating_top', 22 | 'BannerDisp_BPM', 'GameSel_list', 23 | 'GameSel_description', 'Opts_list', 24 | 'Opts_description', 'Opts_choices', 25 | 'Opts_choice_description', 'Crs_list', 26 | 'Crs_song_title', 'Crs_song_subtitle', 27 | 'error_message', 'Dance_lifebar_text', 28 | 'Dance_score_display', 'Dance_lyrics_display', 29 | 'Dance_FPS_display', 'Dance_elapsed_time', 30 | 'MapKeys_message', 'MapKeys_player', 31 | 'MapKeys_input_type', 'MapKeys_entries', 32 | 'Dance_step_judgment', 'Dance_hold_judgment', 33 | 'SongInfo_countdown', 'SongInfo_player', 34 | 'SongInfo_current_options', 'GrScr_text', 35 | 'GrScr_tocontinue', 'Endless_player', 36 | 'Endless_filter_by', 'Endless_filter_range', 37 | 'diffbox', 'Menu_credits'] 38 | # These "purposes" are resized to fit a particular total string length. 39 | _VAR_SIZE = ['BannerDisp_title', 'BannerDisp_artist', 40 | 'BannerDisp_subtitle', 'SongSel_sort_mode', 41 | 'GameSel_screen_title', 'GameSel_selected_title', 42 | 'Crs_course_list_head', 'Crs_course_name', 43 | 'SongInfo_controls','SongInfo_screen_title'] 44 | # These "purposes" have scaling handled by the actual rendering code. 45 | _SCALE_SIZE=['Dance_title_artist','Dance_combo_display'] 46 | 47 | def load_themes(cls): 48 | for path in search_paths: 49 | fontdir = os.path.join(path, 'themes', 'font') 50 | if os.path.exists(fontdir) and os.path.isdir(fontdir): 51 | for fontcfg in dircache.listdir(fontdir): 52 | if fontcfg.endswith('.cfg'): 53 | theme = FontTheme(os.path.join(fontdir,fontcfg)) 54 | cls._themes[theme.title] = theme 55 | 56 | load_themes = classmethod(load_themes) 57 | 58 | def themes(cls): 59 | if cls._themes == {}: cls.load_themes() 60 | return cls._themes.keys() 61 | 62 | themes = classmethod(themes) 63 | 64 | def set(cls,title): 65 | if cls._themes == {}: cls.load_themes() 66 | 67 | cls._current = title 68 | 69 | for purpose in cls._FIXED_SIZE: 70 | fontfn,fontsize = cls._themes[title].fonts[purpose] 71 | cls.__dict__[purpose] = pygame.font.Font(fontfn,fontsize) 72 | 73 | for purpose in cls._SCALE_SIZE: 74 | cls.__dict__[purpose] = cls._themes[title].fonts[purpose] 75 | 76 | set = classmethod(set) 77 | 78 | def font(cls, purpose, string='', max_width=None, size=None): 79 | if purpose in cls._FIXED_SIZE: 80 | return cls.__dict__[purpose] 81 | 82 | elif purpose in cls._VAR_SIZE: 83 | if max_width is not None: 84 | fontfn, maxsize = cls._themes[cls._current].fonts[purpose] 85 | return max_size(fontfn, string, max_width, maxsize) 86 | elif size is not None: 87 | fontfn = cls._themes[cls._current].fonts[purpose][0] 88 | return pygame.font.Font(fontfn, size) 89 | else: 90 | return cls._themes[cls._current].fonts[purpose][0] 91 | 92 | elif purpose in cls._SCALE_SIZE: 93 | return cls._themes[cls._current].fonts[purpose] 94 | 95 | else: raise Exception("Requested font purpose not found.") 96 | 97 | font=classmethod(font) 98 | 99 | def __init__(self,path): 100 | fontconf = ConfigParser() 101 | fontconf.read(path) 102 | 103 | self.fonts = {} 104 | 105 | self.title = fontconf.get('global', 'title') 106 | 107 | if fontconf.has_option('global','font'): 108 | defFont = os.path.join(os.path.dirname(path),fontconf.get('global','font')) 109 | else: 110 | defFont = None 111 | 112 | for purpose in FontTheme._FIXED_SIZE + FontTheme._VAR_SIZE + FontTheme._SCALE_SIZE: 113 | if fontconf.has_option(purpose,'font'): 114 | fontfn = os.path.join(os.path.dirname(path), fontconf.get(purpose,'font')) 115 | else: 116 | fontfn = defFont 117 | fontsize = fontconf.getint(purpose,'size') 118 | self.fonts[purpose] = (fontfn, fontsize) 119 | 120 | 121 | FontTheme.load_themes() 122 | FontTheme.set(mainconfig['fonttheme']) 123 | -------------------------------------------------------------------------------- /grades.py: -------------------------------------------------------------------------------- 1 | from listener import Listener 2 | 3 | # This will *probably* never have anything in it... 4 | class AbstractGrade(Listener): pass 5 | 6 | # DDR 6th-8th mix "dance points" grading. This is IMO one of the 7 | # fairest grading algorithms and definitely one of the most common. 8 | class DancePointsGrade(AbstractGrade): 9 | def grade_by_rank(cls, rank): 10 | if rank >= 1.00: return "AAA" 11 | elif rank >= 0.93: return "AA" 12 | elif rank >= 0.80: return "A" 13 | elif rank >= 0.65: return "B" 14 | elif rank >= 0.45: return "C" 15 | elif rank == -2: return "F" 16 | elif rank == -1: return "?" 17 | else: return "D" 18 | 19 | grade_by_rank = classmethod(grade_by_rank) 20 | 21 | def __init__(self): 22 | self.score = 0 23 | self.arrow_count = 0 24 | self.hold_count = 0 25 | self.inc = { "V": 2, "P": 2, "G": 1, "B": -4, "M": -8 } 26 | 27 | def ok_hold(self, pid, curtime, dir, whichone): 28 | self.hold_count += 1 29 | self.score += 6 30 | 31 | def broke_hold(self, pid, curtime, dir, whichone): 32 | self.hold_count += 1 33 | 34 | def stepped(self, pid, dir, cur_time, etime, rating, combo): 35 | self.arrow_count += 1 36 | self.score += self.inc.get(rating, 0) 37 | 38 | def rank(self): 39 | max_score = float(2 * self.arrow_count + 6 * self.hold_count) 40 | if max_score == 0: return 0 41 | else: return (self.score / max_score) 42 | 43 | def grade(self, failed): 44 | if failed == True: return "F" 45 | else: return DancePointsGrade.grade_by_rank(self.rank()) 46 | 47 | # Appropriate for endless mode, it doesn't return E on failure (since 48 | # endless mode always ends in a failure). 49 | class EndlessGrade(DancePointsGrade): 50 | def grade(self, failed): return DancePointsGrade.grade(self, False) 51 | 52 | grades = [DancePointsGrade, EndlessGrade] 53 | grade_opt = [ 54 | (0, _("Dance Points"), ""), 55 | (1, _("Endless"), 56 | _("Like dance points, but failing doesn't result in an F.")), 57 | ] 58 | -------------------------------------------------------------------------------- /i18n.py: -------------------------------------------------------------------------------- 1 | import gettext 2 | import locale 3 | import os.path,sys 4 | 5 | def MyDir(): 6 | filename = sys.argv[0] 7 | return os.path.abspath(os.path.dirname(filename)) 8 | 9 | mydir=MyDir() 10 | 11 | directories=['/usr/share/locale','/usr/local/share/locale',mydir+'/../../locale',mydir+'/../share/locale',mydir+'/mo'] 12 | 13 | lang = None 14 | for dir in directories: 15 | try: 16 | lang=gettext.translation('pydance',dir) 17 | break 18 | except: 19 | pass 20 | 21 | 22 | if lang!=None: 23 | lang.install(True) 24 | 25 | else: 26 | gettext.install('pydance') 27 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/icon.png -------------------------------------------------------------------------------- /image-src/courseselect.xcf.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/image-src/courseselect.xcf.bz2 -------------------------------------------------------------------------------- /image-src/endless-bg.xcf.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/image-src/endless-bg.xcf.bz2 -------------------------------------------------------------------------------- /image-src/gameselect.xcf.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/image-src/gameselect.xcf.bz2 -------------------------------------------------------------------------------- /image-src/go_ca.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/image-src/go_ca.xcf -------------------------------------------------------------------------------- /image-src/gradescreen.xcf.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/image-src/gradescreen.xcf.bz2 -------------------------------------------------------------------------------- /image-src/new-pad-color.png.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/image-src/new-pad-color.png.bz2 -------------------------------------------------------------------------------- /image-src/new-pad.png.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/image-src/new-pad.png.bz2 -------------------------------------------------------------------------------- /image-src/options.xcf.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/image-src/options.xcf.bz2 -------------------------------------------------------------------------------- /image-src/ready_ca.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/image-src/ready_ca.xcf -------------------------------------------------------------------------------- /image-src/songinfoscreen.xcf.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/image-src/songinfoscreen.xcf.bz2 -------------------------------------------------------------------------------- /image-src/songselect.xcf.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/image-src/songselect.xcf.bz2 -------------------------------------------------------------------------------- /images/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/bg.png -------------------------------------------------------------------------------- /images/button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/button.png -------------------------------------------------------------------------------- /images/courseselect-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/courseselect-bg.png -------------------------------------------------------------------------------- /images/endless-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/endless-bg.png -------------------------------------------------------------------------------- /images/error-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/error-bg.png -------------------------------------------------------------------------------- /images/gameselect-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/gameselect-bg.png -------------------------------------------------------------------------------- /images/go.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/go.png -------------------------------------------------------------------------------- /images/go_ca.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/go_ca.png -------------------------------------------------------------------------------- /images/grade-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/grade-bg.png -------------------------------------------------------------------------------- /images/indicator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/indicator.png -------------------------------------------------------------------------------- /images/menu-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/menu-bg.png -------------------------------------------------------------------------------- /images/newss-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/newss-bg.png -------------------------------------------------------------------------------- /images/no-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/no-banner.png -------------------------------------------------------------------------------- /images/option-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/option-bg.png -------------------------------------------------------------------------------- /images/rating-a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/rating-a.png -------------------------------------------------------------------------------- /images/rating-aa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/rating-aa.png -------------------------------------------------------------------------------- /images/rating-aaa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/rating-aaa.png -------------------------------------------------------------------------------- /images/rating-b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/rating-b.png -------------------------------------------------------------------------------- /images/rating-c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/rating-c.png -------------------------------------------------------------------------------- /images/rating-d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/rating-d.png -------------------------------------------------------------------------------- /images/rating-ee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/rating-ee.png -------------------------------------------------------------------------------- /images/rating-f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/rating-f.png -------------------------------------------------------------------------------- /images/ready.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/ready.png -------------------------------------------------------------------------------- /images/ready_ca.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/ready_ca.png -------------------------------------------------------------------------------- /images/select-3p.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/select-3p.png -------------------------------------------------------------------------------- /images/select-4p.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/select-4p.png -------------------------------------------------------------------------------- /images/select-5p.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/select-5p.png -------------------------------------------------------------------------------- /images/select-6p.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/select-6p.png -------------------------------------------------------------------------------- /images/select-8p.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/select-8p.png -------------------------------------------------------------------------------- /images/select-9p.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/select-9p.png -------------------------------------------------------------------------------- /images/select-dmx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/select-dmx.png -------------------------------------------------------------------------------- /images/select-endless.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/select-endless.png -------------------------------------------------------------------------------- /images/select-ez2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/select-ez2.png -------------------------------------------------------------------------------- /images/select-ez2real.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/select-ez2real.png -------------------------------------------------------------------------------- /images/select-nonstop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/select-nonstop.png -------------------------------------------------------------------------------- /images/select-normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/select-normal.png -------------------------------------------------------------------------------- /images/select-panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/select-panel.png -------------------------------------------------------------------------------- /images/select-para.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/select-para.png -------------------------------------------------------------------------------- /images/songinfoscreen-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/images/songinfoscreen-bg.png -------------------------------------------------------------------------------- /judge.py: -------------------------------------------------------------------------------- 1 | from constants import * 2 | 3 | from util import toRealTime 4 | from announcer import Announcer 5 | from listener import Listener 6 | 7 | # The judge is responsible for correlating step times and arrows times, 8 | # and then rating them (V/P/G/O/B), as well as expiring arrows when 9 | # they're missed. Listener objects get their information from the judge, 10 | # which is also a Listener itself. 11 | 12 | class AbstractJudge(Listener): 13 | def __init__ (self, pid, songconf): 14 | self._pid = pid 15 | self._scale = songconf["judgescale"] 16 | self._ann = Announcer(mainconfig["djtheme"]) 17 | 18 | def set_song(self, pid, bpm, difficulty, count, holds, feet): 19 | self.holdsub = {} 20 | self._steps = {} 21 | # Hidden steps were first used in Technomotion. They count for points, 22 | # if you hit them, but you can't miss them. 23 | self._hidden_steps = {} 24 | 25 | def broke_hold(self, pid, curtime, dir, whichone): 26 | if pid != self._pid: return 27 | if self.holdsub.get(whichone) != -1: self.holdsub[whichone] = -1 28 | 29 | # Handle a key press and see if it can be associated with an upcoming 30 | # arrow; rate it if so. 31 | def handle_key(self, dir, curtime): 32 | times = self._steps.keys() 33 | times.sort() 34 | etime = 0.0 35 | done = 0 36 | rating = None 37 | off = -1 38 | for t in times: 39 | if dir in self._steps[t]: 40 | rating = self._get_rating(curtime, t) 41 | if rating != None: 42 | etime = t 43 | self._steps[etime] = self._steps[etime].replace(dir, "") 44 | if etime in self._hidden_steps: 45 | self._hidden_steps[etime].replace(dir, "") 46 | break 47 | 48 | return rating, dir, etime 49 | 50 | # Add an arrow to the list of steps to be checked on a keypress. 51 | def handle_arrow(self, key, etime, is_hidden): 52 | if etime in self._steps: self._steps[etime] += key 53 | else: self._steps[etime] = key 54 | 55 | if is_hidden: 56 | if etime in self._hidden_steps: self._hidden_steps[etime] += key 57 | else: self._hidden_steps[etime] = key 58 | 59 | # Mark arrows that are very old as misses. 60 | def expire_arrows(self, curtime): 61 | times = self._steps.keys() 62 | misses = "" 63 | for time in times: 64 | if self._is_miss(curtime, time) and self._steps[time]: 65 | for d in self._hidden_steps.get(time, ""): 66 | self._steps[time] = self._steps[time].replace(d, "") 67 | misses += self._steps[time] 68 | del(self._steps[time]) 69 | return misses 70 | 71 | # Check whether or not an arrow is a miss. 72 | def _is_miss(self, curtime, time): 73 | raise NotImplementedError("This class should not be instantiated.") 74 | 75 | # Rate a (possible) step. 76 | def _get_rating(self, curtime, time): 77 | raise NotImplementedError("This class should not be instantiated.") 78 | 79 | # This judge rates steps based on constant time offsets (although 80 | # multiplied by scale). 81 | class TimeJudge(AbstractJudge): 82 | 83 | def __init__ (self, pid, songconf): 84 | AbstractJudge.__init__(self, pid, songconf) 85 | self._v = self._scale * 0.0225 86 | self._p = self._scale * 0.045 87 | self._g = self._scale * 0.090 88 | self._o = self._scale * 0.135 89 | self._b = self._scale * 0.180 90 | self.ok_time = self._scale * 0.25 91 | 92 | def _get_rating(self, curtime, t): 93 | offset = abs(curtime - t) 94 | if offset < self._v: return "V" 95 | elif offset < self._p: return "P" 96 | elif offset < self._g: return "G" 97 | elif offset < self._o: return "O" 98 | elif offset < self._b: return "B" 99 | else: return None 100 | 101 | def _is_miss(self, curtime, time): return time < curtime - self._b 102 | 103 | # This judge rates steps based on what fraction of a beat they are from 104 | # the correct time, and therefore makes fast songs much harder, and slow 105 | # songs easier. 106 | class BeatJudge(AbstractJudge): 107 | 108 | def set_song(self, pid, bpm, difficulty, count, holds, feet): 109 | AbstractJudge.set_song(self, pid, bpm, difficulty, count, holds, feet) 110 | self._tick = toRealTime(bpm, 0.16666666666666666) 111 | self._v = self._scale * 1 112 | self._p = self._scale * 4 113 | self._g = self._scale * 7 114 | self._o = self._scale * 9 115 | self._b = self._scale * 12 116 | self.ok_time = toRealTime(bpm, 2) * self._scale 117 | self._b_ticks = self._b * self._tick 118 | 119 | def change_bpm(self, pid, curtime, bpm): 120 | if self._pid != pid: return 121 | if bpm >= 1: self._tick = toRealTime(bpm, 0.16666666666666666) 122 | self._v = self._scale * 1 123 | self._p = self._scale * 4 124 | self._g = self._scale * 7 125 | self._o = self._scale * 9 126 | self._b = self._scale * 12 127 | self.ok_time = toRealTime(bpm, 2) * self._scale 128 | self._b_ticks = self._b * self._tick 129 | 130 | def _get_rating(self, curtime, t): 131 | off = abs((curtime - t) / self._tick) 132 | if off <= self._v: return "V" 133 | elif off <= self._p: return "P" 134 | elif off <= self._g: return "G" 135 | elif off <= self._o: return "O" 136 | elif off < self._b: return "B" 137 | else: return None 138 | 139 | def _is_miss(self, curtime, time): return time < curtime - self._b 140 | 141 | judges = [TimeJudge, BeatJudge] 142 | judge_opt = [ 143 | (0, _("Time"), 144 | _("Judging is based on how many seconds you are from the correct time.")), 145 | (1, _("Beat"), 146 | _("Judging is based on how many beats you are from the correct time.")), 147 | ] 148 | -------------------------------------------------------------------------------- /listener.py: -------------------------------------------------------------------------------- 1 | # This is the base class for most of the active objects in the game. 2 | 3 | # It basically says that the object should do nothing on all the 4 | # events it might get. 5 | 6 | class Listener(object): 7 | def __init__(self): 8 | raise NotImplementedError("This class should never be instantiated.") 9 | 10 | # change_bpm, stepped, broke_hold, and ok_hold receive the player's 11 | # "virtual" pid number, which is not the same as the real pid in 12 | # doubled modes. set_song always receives the real pid number, because 13 | # a song is only set once, not once for each virtual pid. 14 | 15 | # This is received when a hold is sucessfully completed ("OK"). 16 | # dir is the direction of this hold. 17 | # whichone is a unique ID of the hold for this song. 18 | def ok_hold(self, pid, curtime, dir, whichone): pass 19 | 20 | # Received when a hold is broken ("NG") for the first time. 21 | def broke_hold(self, pid, curtime, dir, whichone): pass 22 | 23 | # Received when an arrow is stepped on or missed. 24 | # combo is the current combo count. rating is V (marvelous), P 25 | # (perfect), G (great), O (okay), B (boo), or M (miss), or None, 26 | # if no arrow was hit. 27 | 28 | # Note that since Combo objects are Listeners, the order Listeners 29 | # are called in *does* matter in that case. 30 | # etime is the "proper" time to step. 31 | def stepped(self, pid, dir, curtime, etime, rating, combo): pass 32 | 33 | # Received when a new song is started. difficulty is the name as a 34 | # string; count is the number of arrows in the song; feet is the 35 | # song rating. 36 | def set_song(self, pid, bpm, difficulty, count, holds, feet): pass 37 | 38 | # Received when the BPM of the song changes. The new BPM is given. 39 | def change_bpm(self, pid, curtime, bpm): pass 40 | -------------------------------------------------------------------------------- /lyrics.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | import colors 3 | 4 | from constants import * 5 | from fonttheme import FontTheme 6 | 7 | class LyricChannel(pygame.sprite.Sprite): 8 | def __init__(self, top, color): 9 | pygame.sprite.Sprite.__init__(self) 10 | self._lyrics = [] 11 | self._times = [] 12 | self._prender = [] 13 | self._lasttime = -1000 14 | 15 | self.image = pygame.surface.Surface([0, 0]) 16 | 17 | self._oldlyric = -1 18 | self._color = color 19 | self._darkcolor = colors.darken_div(color) 20 | self._top = top 21 | 22 | self.rect = self.image.get_rect() 23 | self.rect.top = self._top 24 | self.rect.centerx = 320 25 | 26 | def addlyric(self, time, lyric): 27 | self._lyrics.append(lyric) 28 | self._times.append(time) 29 | 30 | image1 = FontTheme.Dance_lyrics_display.render(lyric, True, self._darkcolor) 31 | image2 = FontTheme.Dance_lyrics_display.render(lyric, True, self._color) 32 | rimage = pygame.Surface(image1.get_size()) 33 | rimage.fill([64, 64, 64]) 34 | rimage.blit(image1, [-2, -2]) 35 | rimage.blit(image1, [2, 2]) 36 | rimage.blit(image2, [0, 0]) 37 | rimage.set_colorkey(rimage.get_at([0, 0]), RLEACCEL) 38 | 39 | self._prender.append(rimage) 40 | 41 | def update(self, curtime): 42 | current = -1 43 | timediff = curtime - self._lasttime 44 | for i in self._times: 45 | if curtime >= i: 46 | current = self._times.index(i) 47 | self._lasttime = i 48 | 49 | if current != self._oldlyric: 50 | self.image = self._prender[current] 51 | self.rect = self.image.get_rect() 52 | self.rect.top = self._top 53 | self.rect.centerx = 320 54 | 55 | if current != -1: 56 | holdtime = len(self._lyrics[current]) * 0.045 57 | alp = 255 58 | if timediff > holdtime: 59 | alp = 255 - (255 * (timediff - holdtime)) 60 | if alp < 0: alp = 0 61 | 62 | self.image.set_alpha(int(alp)) 63 | 64 | self._oldlyric = current 65 | 66 | class Lyrics(object): 67 | def __init__(self, clrs): 68 | self._channels = {} 69 | self._colors = clrs 70 | 71 | def addlyric(self, time, chan, lyric): 72 | if chan not in self._channels: 73 | color = self._colors[chan % len(self._colors)] 74 | self._channels[chan] = LyricChannel(480 - (chan + 1) * 32, color) 75 | self._channels[chan].addlyric(time, lyric) 76 | 77 | def channels(self): return self._channels.values() 78 | -------------------------------------------------------------------------------- /macosx/English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/macosx/English.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /macosx/main.c: -------------------------------------------------------------------------------- 1 | /* main.c */ 2 | 3 | #include 4 | 5 | #include 6 | 7 | #define PYTHON_BIN "/Library/Frameworks/Python.framework/Versions/2.3/bin/python" 8 | 9 | int main(int argc, char *argv[]) 10 | { 11 | CFBundleRef mainBundle; 12 | CFURLRef resourcesURL; 13 | char buf[4096]; 14 | 15 | char *const args[] = { 16 | "PyDDR", 17 | "./pyddr.py", 18 | NULL 19 | }; 20 | 21 | mainBundle = CFBundleGetMainBundle(); 22 | resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle); 23 | CFURLGetFileSystemRepresentation(resourcesURL, true, buf, 4096); 24 | CFRelease(resourcesURL); 25 | 26 | chdir(buf); 27 | 28 | return execv(PYTHON_BIN, args); 29 | } 30 | -------------------------------------------------------------------------------- /macosx/pyddr_Prefix.h: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'pyddr' target in the 'pyddr' project. 3 | // 4 | 5 | #include 6 | -------------------------------------------------------------------------------- /menus.py: -------------------------------------------------------------------------------- 1 | import pygame, colors, ui 2 | from constants import * 3 | from fontfx import TextZoomer 4 | from fonttheme import FontTheme 5 | 6 | # Hooray! Less magic numbers 7 | LIGHT_GRAY = (128, 128, 128) 8 | TOPLEFT = (0, 0) 9 | BUTTON_SIZE = (192, 48) 10 | BUTTON_WIDTH, BUTTON_HEIGHT = BUTTON_SIZE 11 | BUTTON_PADDING = 8 12 | LEFT_OFFSET, TOP_OFFSET = 425, 100 13 | TRANSPARENT, SOLID = 128, 255 14 | DISPLAYED_ITEMS = 6 15 | 16 | CREATE, SELECT, UNSELECT = 1000, 2000, 3000 17 | 18 | button_bg = pygame.image.load(os.path.join(image_path, "button.png")) 19 | 20 | class MenuItem(object): 21 | 22 | def __init__(self, text, callbacks, args): 23 | # Dict of callbacks by keycodes, also "initial", "select", "unselect" 24 | 25 | # This looks something like: 26 | # MenuItem({ 'initial': do_setup, START: do_change, 27 | # START: do_change }, (configdata, mystrings)) 28 | # When the button is pressed, do_change(configdata, mystrings) will be 29 | # called. 30 | self.callbacks = callbacks 31 | self.args = args 32 | self.bg = button_bg 33 | self.rgb = LIGHT_GRAY 34 | self.subtext = None 35 | self.alpha = TRANSPARENT 36 | self.text = text 37 | self.render() 38 | 39 | # Call an appropriate callback function, for the event given. 40 | # The function can return up to three arguments - the new 41 | # text to display on the button, the new subtext to display, and 42 | # the RGB value of the text. 43 | 44 | def activate(self, ev): # Note - event ID, not an event tuple 45 | if ev == SELECT: 46 | self.rgb = colors.WHITE 47 | self.alpha = SOLID 48 | self.render() 49 | elif ev == UNSELECT: 50 | self.rgb = LIGHT_GRAY 51 | self.alpha = TRANSPARENT 52 | self.render() 53 | elif self.callbacks == None: 54 | if ev in [ui.START, ui.RIGHT, ui.LEFT, ui.CONFIRM]: 55 | return ui.QUIT # This is a back button 56 | else: return ev # Shouldn't happen 57 | elif callable(self.callbacks.get(ev)): 58 | text, subtext = self.callbacks[ev](*self.args) 59 | if text != None: self.text = text #str(text) 60 | if subtext != None: self.subtext = subtext #str(subtext) 61 | self.render() 62 | return ev 63 | else: return ev 64 | 65 | # Render the image. If subtext is present, the main text gets smaller. 66 | def render(self): 67 | self.image = pygame.surface.Surface(BUTTON_SIZE) 68 | self.image.blit(self.bg, (0,0)) 69 | if self.subtext == None: 70 | text = FontTheme.Menu_button_no_sub.render(self.text, 1, self.rgb) 71 | self.image.blit(text, (BUTTON_WIDTH/2 - FontTheme.Menu_button_no_sub.size(self.text)[0] / 2, 72 | BUTTON_HEIGHT/2 - FontTheme.Menu_button_no_sub.size(self.text)[1]/2)) 73 | else: 74 | text = FontTheme.Menu_button_if_sub.render(self.text, 1, self.rgb) 75 | subtext = FontTheme.Menu_button_sub.render(self.subtext, 1, self.rgb) 76 | self.image.blit(text, (BUTTON_WIDTH/2 - FontTheme.Menu_button_if_sub.size(self.text)[0] / 2, 77 | BUTTON_HEIGHT/3 - FontTheme.Menu_button_if_sub.size(self.text)[1]/2)) 78 | self.image.blit(subtext, 79 | (BUTTON_WIDTH/2 - FontTheme.Menu_button_sub.size(self.subtext)[0] / 2, 80 | 2 * BUTTON_HEIGHT/3 - FontTheme.Menu_button_sub.size(self.text)[1] / 2)) 81 | self.image.set_alpha(self.alpha) 82 | 83 | class Menu(object): 84 | 85 | bgimage = pygame.image.load(os.path.join(image_path, "menu-bg.png")) 86 | try: 87 | click_sound = pygame.mixer.Sound(os.path.join(sound_path, "clicked.ogg")) 88 | click_sound.set_volume(0.45) 89 | except pygame.error: 90 | raise SystemExit("You need SDL_mixer 1.2.5 with Vorbis support.") 91 | move_sound = pygame.mixer.Sound(os.path.join(sound_path, "move.ogg")) 92 | back_sound = pygame.mixer.Sound(os.path.join(sound_path, "back.ogg")) 93 | 94 | # Menus are defined based on a tree of tuples (submenus) ending 95 | # in a list (the final item). The first item of the tuple is 96 | # a string of text which gets displayed. 97 | def __init__(self, name, itemlist, screen, sprites): 98 | self.items = [] 99 | self.sprites = sprites 100 | self.text = name 101 | self.rgb = LIGHT_GRAY 102 | self.bg = button_bg 103 | self.alpha = TRANSPARENT 104 | self.screen = screen 105 | self.render() 106 | for i in itemlist: 107 | if type(i) == type([]): # Menuitems are lists 108 | self.items.append(MenuItem(i[0], i[1], i[2])) 109 | self.items[-1].activate(CREATE) 110 | elif type(i) == type((0,0)): # New submenus are tuples 111 | self.items.append(Menu(i[0], i[1:], screen, sprites)) 112 | 113 | # Menu rendering is tons easier, since it never changes. 114 | def render(self): 115 | self.image = pygame.surface.Surface(BUTTON_SIZE) 116 | self.image.blit(self.bg, (0,0)) 117 | text = FontTheme.Menu_button_no_sub.render(self.text, 1, self.rgb) 118 | self.image.blit(text, (BUTTON_WIDTH/2 - FontTheme.Menu_button_no_sub.size(self.text)[0] / 2, 119 | BUTTON_HEIGHT/2 - FontTheme.Menu_button_no_sub.size(self.text)[1] / 2)) 120 | self.image.set_alpha(self.alpha) 121 | 122 | def activate(self, ev): 123 | if ev in [ui.START, ui.CONFIRM, ui.RIGHT]: 124 | self.display() 125 | elif ev == SELECT: 126 | self.rgb = colors.WHITE 127 | self.alpha = SOLID 128 | self.render() 129 | elif ev == UNSELECT: 130 | self.rgb = LIGHT_GRAY 131 | self.alpha = TRANSPARENT 132 | self.render() 133 | 134 | # Render and start navigating the menu. 135 | # Postcondition: Screen buffer is in an unknown state! 136 | def display(self): 137 | screen = self.screen 138 | clock = pygame.time.Clock() 139 | Menu.bgimage.set_alpha(256) 140 | pygame.display.update(screen.blit(Menu.bgimage, TOPLEFT)) 141 | curitem = 0 142 | topitem = 0 143 | changed = False 144 | toprotater = TextZoomer(self.text, FontTheme.Menu_rotating_top, (640, 64), 145 | (178, 110, 0), colors.WHITE) 146 | 147 | self.items[curitem].activate(SELECT) 148 | 149 | ev = ui.PASS 150 | while ev != ui.QUIT: 151 | r = [] 152 | ev = ui.ui.poll()[1] 153 | 154 | # Scroll down through the menu 155 | if ev == ui.DOWN: 156 | Menu.move_sound.play() 157 | ev = self.items[curitem].activate(UNSELECT) 158 | curitem += 1 159 | if curitem == len(self.items): # Loop at the bottom 160 | curitem = 0 161 | topitem = 0 162 | elif curitem >= topitem + DISPLAYED_ITEMS: # Advance the menu 163 | topitem += 1 164 | ev = self.items[curitem].activate(SELECT) 165 | 166 | # Same as above, but up 167 | elif ev == ui.UP: 168 | Menu.move_sound.play() 169 | ev = self.items[curitem].activate(UNSELECT) 170 | curitem -= 1 171 | if curitem < 0: 172 | curitem = len(self.items) - 1 173 | topitem = max(0, curitem - DISPLAYED_ITEMS + 1) 174 | elif curitem < topitem: 175 | topitem = curitem 176 | ev = self.items[curitem].activate(SELECT) 177 | 178 | elif ev == ui.FULLSCREEN: 179 | mainconfig["fullscreen"] ^= 1 180 | pygame.display.toggle_fullscreen() 181 | 182 | # Otherwise, if the event actually happened, pass it on to the button. 183 | elif ev != ui.PASS and ev != ui.QUIT: 184 | if ev in [ui.START, ui.CONFIRM]: Menu.click_sound.play() 185 | ev = self.items[curitem].activate(ev) 186 | ui.ui.clear() 187 | changed = True 188 | 189 | toprotater.iterate() 190 | if changed: r.append(screen.blit(Menu.bgimage, TOPLEFT)) 191 | else: screen.blit(Menu.bgimage, TOPLEFT) 192 | r.append(screen.blit(toprotater.tempsurface, TOPLEFT)) 193 | for i in range(DISPLAYED_ITEMS): 194 | if i + topitem < len(self.items): 195 | r.append(screen.blit(self.items[i + topitem].image, 196 | (LEFT_OFFSET, 197 | TOP_OFFSET + i * (BUTTON_HEIGHT + 198 | BUTTON_PADDING)))) 199 | 200 | self.sprites.update() 201 | r.extend(self.sprites.draw(screen)) 202 | pygame.display.update(r) 203 | #self.sprites.clear(screen, Menu.bgimage) 204 | clock.tick(30) 205 | 206 | if ev == ui.QUIT: 207 | Menu.back_sound.play() 208 | self.items[curitem].activate(UNSELECT) 209 | -------------------------------------------------------------------------------- /po/Makefile: -------------------------------------------------------------------------------- 1 | #Inspired from Powertop po/Makefile 2 | 3 | SRC=$(wildcard *.po) 4 | OBJ= $(SRC:.po=.mo) 5 | INST= $(SRC:.po=.inst) 6 | GENERATE= $(SRC:.po=.generate) 7 | 8 | translations: $(OBJ) 9 | 10 | %.mo: %.po 11 | msgfmt -o $@ $< 12 | 13 | clean: 14 | rm -f *.mo *~ 15 | 16 | install: $(OBJ) $(INST) 17 | 18 | generate: $(OBJ) $(GENERATE) 19 | 20 | %.inst: %.mo 21 | mkdir -p $(DESTDIR)$(LOCALESDIR)/$*/LC_MESSAGES/ 22 | cp -f $< $(DESTDIR)$(LOCALESDIR)/$*/LC_MESSAGES/pydance.mo 23 | 24 | # Just create and generate the files 25 | %.generate: %.mo 26 | mkdir -p ../mo/$*/LC_MESSAGES/ 27 | cp -f $< ../mo/$*/LC_MESSAGES/pydance.mo 28 | -------------------------------------------------------------------------------- /po/ca.po: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/po/ca.po -------------------------------------------------------------------------------- /profile-pydance.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | python /usr/lib/python2.3/profile.py pydance.py > /dev/null 4 | mv ~/.pydance/pydance.log Profile-`date +%s` 5 | -------------------------------------------------------------------------------- /pydance.posix.cfg: -------------------------------------------------------------------------------- 1 | songdir /usr/share/games/pydance/songs:~/.pydance/songs:/usr/local/share/games/pydance/songs 2 | coursedir /usr/share/games/pydance/courses:~/.pydance/courses:/usr/local/share/games/pydance/courses 3 | -------------------------------------------------------------------------------- /pydance.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # pydance - a dancing game written in Python 3 | 4 | import os 5 | import sys 6 | from getopt import getopt 7 | 8 | VERSION = "1.1.0" 9 | 10 | from i18n import * 11 | 12 | # fuck you, Python. 13 | def print_help(): 14 | print 15 | print _("Usage: %s [options]") % sys.argv[0] 16 | print _(" -h, --help display this help text and exit") 17 | print _(" -v, --version display the version and exit") 18 | print _(" -f, --filename load and play a step file") 19 | print _(" -m, --mode the mode to play the file in (default SINGLE)") 20 | print _(" -d, --difficulty the difficult to play the file (default BASIC)") 21 | raise SystemExit 22 | 23 | def print_version(): 24 | print _("pydance %s by Joe Wreschnig, Brendan Becker, and others") % VERSION 25 | print "pyddr-discuss@icculus.org - http://icculus.org/pyddr" 26 | raise SystemExit 27 | 28 | if len(sys.argv) < 2: pass 29 | elif sys.argv[1] in ["--help", "-h"]: print_help() 30 | elif sys.argv[1] in ["--version", "-v"]: print_version() 31 | 32 | # Don't import anything that initializes the joysticks or config until 33 | # after we're (reasonably) sure no one wants --help or --version. 34 | from constants import * # This needs to be here to set sys.path. 35 | 36 | import util 37 | import games 38 | import dance 39 | import pygame 40 | import courses 41 | import colors 42 | import records 43 | import menudriver 44 | 45 | from fileparsers import SongItem 46 | from pygame.mixer import music 47 | from fontfx import TextProgress 48 | from error import ErrorMessage 49 | from fonttheme import FontTheme 50 | 51 | from pad import pad 52 | 53 | # Set our required display paramters. Currently, this is nothing 54 | # strange on any platforms, but in the past and likely in the future 55 | # some platforms need other flags. 56 | def set_display_mode(): 57 | try: 58 | flags = 0 59 | if mainconfig["fullscreen"]: flags |= FULLSCREEN 60 | screen = pygame.display.set_mode([640, 480], flags, 16) 61 | except: 62 | raise SystemExit(_("E: Can't get a 16 bit display! pydance doesn't work in 8 bit mode.")) 63 | return screen 64 | 65 | # Load a single song (given the filename) and then play it on the 66 | # given difficulty. 67 | def play_and_quit(fn, mode, difficulty): 68 | print _("Entering debug (play-and-quit) mode.") 69 | screen = set_display_mode() 70 | pygame.display.set_caption("pydance " + VERSION) 71 | pygame.mouse.set_visible(0) 72 | pc = games.GAMES[mode].players 73 | dance.play(screen, [(fn, [difficulty] * pc)], 74 | [player_config] * pc, game_config, mode) 75 | raise SystemExit 76 | 77 | # Pass a list of files to a constructor (Ctr) that takes the filename 78 | # as the first argument, and the args tuple as the rest. 79 | def load_files(screen, files, type, Ctr, args): 80 | if len(files) == 0: return [] 81 | 82 | screen.fill(colors.BLACK) 83 | pct = 0 84 | inc = 100.0 / len(files) 85 | # Remove duplicates 86 | files = list(dict(map(None, files, [])).keys()) 87 | objects = [] 88 | message = _("Found %d %s. Loading...") % (len(files), _(type)) 89 | pbar = TextProgress(FontTheme.loading_screen, message, colors.WHITE, colors.BLACK) 90 | r = pbar.render(0).get_rect() 91 | r.center = [320, 240] 92 | for f in files: 93 | try: objects.append(Ctr(*((f,) + args))) 94 | except RuntimeError, message: 95 | print _("E:"), f 96 | print _("E:"), message 97 | print 98 | except Exception, message: 99 | print _("E: Unknown error loading"), f 100 | print _("E:"), message 101 | print _("E: Please contact the developers (pyddr-devel@icculus.org).") 102 | print 103 | pct += inc 104 | img = pbar.render(pct) 105 | pygame.display.update(screen.blit(img, r)) 106 | 107 | return objects 108 | 109 | # Support fullscreen on Win32 / OS X? 110 | if osname != "posix": pygame.display.toggle_fullscreen = set_display_mode 111 | else: pass 112 | 113 | # Actually start the program running. 114 | def main(): 115 | print "pydance", VERSION, " - irc.freenode.net/#pyddr" 116 | 117 | if mainconfig["usepsyco"]: 118 | try: 119 | import psyco 120 | print _("Psyco optimizing compiler found. Using psyco.full().") 121 | psyco.full() 122 | except ImportError: print _("W: Psyco optimizing compiler not found.") 123 | 124 | # default settings for play_and_quit. 125 | mode = "SINGLE" 126 | difficulty = "BASIC" 127 | test_file = None 128 | for opt, arg in getopt(sys.argv[1:], 129 | "hvf:d:m:", ["help", "version", "filename=", 130 | "difficulty=", "mode="])[0]: 131 | if opt in ["-h", _("--help")]: print_help() 132 | elif opt in ["-v", _("--version")]: print_version() 133 | elif opt in ["-f", _("--filename")]: test_file = arg 134 | elif opt in ["-m", _("--mode")]: mode = arg 135 | elif opt in ["-d", _("--difficulty")]: difficulty = arg 136 | 137 | if test_file: play_and_quit(test_file, mode, difficulty) 138 | 139 | song_list = [] 140 | course_list = [] 141 | for dir in mainconfig["songdir"].split(os.pathsep): 142 | print _("Searching for songs in"), dir 143 | song_list.extend(util.find(dir, ['*.dance', '*.dwi', '*.sm', '*/song.*'])) 144 | for dir in mainconfig["coursedir"].split(os.pathsep): 145 | print _("Searching for courses in"), dir 146 | course_list.extend(util.find(dir, ['*.crs'])) 147 | 148 | screen = set_display_mode() 149 | 150 | pygame.display.set_caption("pydance " + VERSION) 151 | pygame.mouse.set_visible(False) 152 | try: 153 | if os.path.exists("/usr/share/pixmaps/pydance.png"): 154 | icon = pygame.image.load("/usr/share/pixmaps/pydance.png") 155 | else: icon = pygame.image.load(os.path.join(pydance_path, "icon.png")) 156 | pygame.display.set_icon(icon) 157 | except: pass 158 | 159 | music.load(os.path.join(sound_path, "menu.ogg")) 160 | music.play(4, 0.0) 161 | 162 | songs = load_files(screen, song_list, _("songs"), SongItem, (False,)) 163 | 164 | # Construct the song and record dictionaries for courses. These are 165 | # necessary because courses identify songs by title and mix, rather 166 | # than filename. The recordkey dictionary is needed for player's 167 | # picks courses. 168 | song_dict = {} 169 | record_dict = {} 170 | for song in songs: 171 | mix = song.info["mix"].lower() 172 | title = song.info["title"].lower() 173 | if song.info["subtitle"]: title += " " + song.info["subtitle"].lower() 174 | if not song_dict.has_key(mix): song_dict[mix] = {} 175 | song_dict[mix][title] = song 176 | record_dict[song.info["recordkey"]] = song 177 | 178 | crs = load_files(screen, course_list, _("courses"), courses.CourseFile, 179 | (song_dict, record_dict)) 180 | crs.extend(courses.make_players(song_dict, record_dict)) 181 | records.verify(record_dict) 182 | 183 | # Let the GC clean these up if it needs to. 184 | song_list = None 185 | course_list = None 186 | record_dict = None 187 | pad.empty() 188 | 189 | if len(songs) < 1: 190 | ErrorMessage(screen, 191 | (_("You don't have any songs or step files. Check out " 192 | "http://icculus.org/pyddr/get.php#songs " 193 | "and download some free ones. " 194 | "If you already have some, make sure they're in ")) + 195 | mainconfig["songdir"]) 196 | raise SystemExit(_("You don't have any songs. Check http://icculus.org/pyddr/get.php#songs .")) 197 | 198 | menudriver.do(screen, (songs, crs, screen)) 199 | 200 | # Clean up shit. 201 | music.stop() 202 | pygame.quit() 203 | mainconfig.write(os.path.join(rc_path, "pydance.cfg")) 204 | # FIXME -- is this option a good idea? 205 | if mainconfig["saveinput"]: pad.write(os.path.join(rc_path, "input.cfg")) 206 | records.write() 207 | 208 | if __name__ == '__main__': main() 209 | -------------------------------------------------------------------------------- /pydance.win32.cfg: -------------------------------------------------------------------------------- 1 | songdir ..\songs;. 2 | coursedir ..\courses;. 3 | fullscreen 0 4 | previewmusic 2 5 | -------------------------------------------------------------------------------- /records.py: -------------------------------------------------------------------------------- 1 | # Store information about player records 2 | 3 | from constants import * 4 | import cPickle as pickle 5 | import grades 6 | import games 7 | 8 | record_fn = os.path.join(rc_path, "records") 9 | 10 | try: records = pickle.load(file(record_fn, "r")) 11 | except: records = {} 12 | bad_records = {} 13 | 14 | # Before starting, move any records we don't know about into a different hash, 15 | # so we don't try to load them for player's {best,worst}. 16 | # Do store them however, so when the songs appear again they'll be valid. 17 | def verify(recordkeys): 18 | for k in records.keys(): 19 | if k[0] not in recordkeys: 20 | bad_records[k] = records[k] 21 | del(records[k]) 22 | elif len(records[k]) < 3: records[k] += (1,) 23 | 24 | # records maps the title, mix, difficulty, and game onto a tuple 25 | # (rank, name) where rank is a floating point number from 0 to 1; and 26 | # name is the name of the player who made the score. 27 | 28 | # recordkey is a string of the mix, title, and subtitle, concatenated, 29 | # lowercased, with non-alphanumerics removed. 30 | 31 | # A score is considered "beaten" (and therefore deserving of a new name 32 | # value) when the new rank is greater than the old rank. 33 | 34 | # The actual "grade" is calculated via grades.py, from the rank. This is 35 | # done in the song selector. 36 | 37 | def add(recordkey, diff, game, rank, name): 38 | game = games.VERSUS2SINGLE.get(game, game) 39 | t = (recordkey, diff, game) 40 | if t in records: 41 | if rank > records[t][0]: 42 | records[t] = (rank, name, records[t][2] + 1) 43 | return True 44 | else: 45 | records[t] = records[t][:2] + (records[t][2] + 1,) 46 | return False 47 | else: 48 | records[t] = (rank, name, 1) 49 | return True 50 | 51 | def get(recordkey, diff, game): 52 | game = games.VERSUS2SINGLE.get(game, game) 53 | return records.get((recordkey, diff, game), (-1, "")) 54 | 55 | def write(): 56 | r = {} 57 | r.update(bad_records) 58 | r.update(records) 59 | pickle.dump(r, file(record_fn, "w"), 2) 60 | 61 | # Highest scores 62 | def best(index, diffs, game): 63 | game = games.VERSUS2SINGLE.get(game, game) 64 | if not isinstance(diffs, list): diffs = [diffs] 65 | index -= 1 66 | r = [(v[0], k[0]) for k, v in records.items() if 67 | (k[1] in diffs and k[2] == game)] 68 | if len(r) == 0: return None 69 | r.sort() 70 | r.reverse() 71 | index %= len(r) 72 | return r[index][1] 73 | 74 | # Lowest scores 75 | def worst(index, diffs, game): 76 | game = games.VERSUS2SINGLE.get(game, game) 77 | index -= 1 78 | if not isinstance(diffs, list): diffs = [diffs] 79 | r = [(v[0], k[0]) for k, v in records.items() if 80 | (k[1] in diffs and k[2] == game)] 81 | if len(r) == 0: return None 82 | r.sort() 83 | index %= len(r) 84 | return r[index][1] 85 | 86 | # Most-played songs 87 | def like(index, diffs, game): 88 | game = games.VERSUS2SINGLE.get(game, game) 89 | if not isinstance(diffs, list): diffs = [diffs] 90 | index -= 1 91 | r = [(v[2], k[0]) for k, v in records.items() if 92 | (k[1] in diffs and k[2] == game)] 93 | if len(r) == 0: return None 94 | r.sort() 95 | r.reverse() 96 | index %= len(r) 97 | return r[index][1] 98 | 99 | # Least-played songs 100 | def dislike(index, diffs, game): 101 | game = games.VERSUS2SINGLE.get(game, game) 102 | index -= 1 103 | if not isinstance(diffs, list): diffs = [diffs] 104 | r = [(v[2], k[0]) for k, v in records.items() if 105 | (k[1] in diffs and k[2] == game)] 106 | if len(r) == 0: return None 107 | r.sort() 108 | index %= len(r) 109 | return r[index][1] 110 | -------------------------------------------------------------------------------- /scores.py: -------------------------------------------------------------------------------- 1 | # Scoring algorithms. 2 | 3 | # Data on many algorithms taken from www.aaroninjapan.com/ddr2.html 4 | 5 | # N = Number of steps in the song. 6 | # H = Current song number (in a sequence of songs). 7 | # F = Feet rating of the song. 8 | # S(N) = N * (N + 1) / 2. 9 | # n = Current step number. 10 | # L(r) = Lookup function for the current step's rating. 11 | # C = Current combo count. 12 | # V(n) = The point value of the nth step. 13 | 14 | import colors 15 | import pygame 16 | import fontfx 17 | 18 | from listener import Listener 19 | from constants import * 20 | 21 | from i18n import * 22 | 23 | from fonttheme import FontTheme 24 | 25 | class AbstractScore(Listener, pygame.sprite.Sprite): 26 | def __init__(self, pid, text, game): 27 | pygame.sprite.Sprite.__init__(self) 28 | self.score = 0 29 | self._set_text(text) 30 | self.image = pygame.surface.Surface((160, 48)) 31 | self.rect = self.image.get_rect() 32 | self.rect.bottom = 484 33 | self.rect.centerx = game.sprite_center + pid * game.player_offset 34 | 35 | def _set_text(self, text): 36 | tx = FontTheme.Dance_score_display.size(text)[0] + 2 37 | txt = fontfx.embfade(text, FontTheme.Dance_score_display, 2, (tx, 24), colors.color[_("gray")]) 38 | basemode = pygame.transform.scale(txt, (tx, 48)) 39 | self.baseimage = pygame.surface.Surface((128, 48)) 40 | self.baseimage.blit(basemode, (64 - (tx / 2), 0)) 41 | self.oldscore = -1 # Force a refresh 42 | 43 | def set_song(self, pid, bpm, difficulty, count, holds, feet): 44 | self._set_text(_(difficulty)) 45 | 46 | def update(self, curtime): 47 | if self.score != self.oldscore: 48 | self.image.blit(self.baseimage, (0,0)) 49 | scoretext = FontTheme.Dance_score_display.render(str(int(self.score)), 1, (192,192,192)) 50 | self.image.blit(scoretext, (64 - (scoretext.get_rect().size[0] / 2), 13)) 51 | self.image.set_colorkey(self.image.get_at((0, 0)), RLEACCEL) 52 | self.oldscore = self.score 53 | 54 | # This is pydance's custom scoring algorithm. It's designed to make 55 | # scores "fair" between different difficulty modes and game types. 56 | 57 | # L(V) = 4, L(P) = 3.5, L(G) = 2.5, L(O) = 0.5 58 | # V(n) = L(r) * 10,000,000 / N + 10,000,000 / S(N) * C 59 | class PydanceScore(AbstractScore): 60 | def set_song(self, pid, bpm, text, count, hold, feet): 61 | AbstractScore.set_song(self, pid, bpm, text, count, hold, feet) 62 | if count == 0: count = 1 # Don't crash on empty songs. 63 | 64 | score_coeff = 10000000.0 / count 65 | self.combo_coeff = 10000000.0 / (count * (count + 1) / 2.0) 66 | self.inc = { "V": 4 * score_coeff, "P": 3.5 * score_coeff, 67 | "G": 2.5 * score_coeff, "O": 0.5 * score_coeff } 68 | 69 | def stepped(self, pid, dir, cur_time, etime, rating, combo): 70 | if rating == None: return 71 | self.score += self.inc.get(rating, 0) + combo * self.combo_coeff 72 | 73 | # M = floor(C / 4) 74 | # L(V) = L(P) = M * 300, L(G) = M * 100, L(O) = 100 75 | # V(n) = M * L(r) 76 | class FirstScore(AbstractScore): 77 | def __init__(self, pid, text, game): 78 | AbstractScore.__init__(self, pid, text, game) 79 | self.combo = 0 80 | 81 | def stepped(self, pid, dir, cur_time, etime, rating, combo): 82 | if rating == None: return 83 | if self.combo == combo == 0: return # No points when combo is 0. 84 | 85 | self.combo += 1 86 | 87 | if combo == 0: # The rating can't be great or better, since combo == 0. 88 | if rating == "O": self.score += self.combo / 4 * 100 89 | self.combo = 0 90 | else: 91 | if rating == "G": 92 | self.score += self.combo * self.combo / 4 * 100 93 | else: # Must be a better-than-great. 94 | self.score += self.combo * self.combo / 4 * 300 95 | 96 | # L(V) = L(P) = 10, L(G) = 5, L(O) = 1 97 | # V(n) = L(r) * 1,000,000 / S(N) * n 98 | 99 | # V(n) = L(r) * K / S(N) * n is common, and so many classes descend from 100 | # this one and override set_song. 101 | class ThirdScore(AbstractScore): 102 | def set_song(self, pid, bpm, text, count, hold, feet): 103 | AbstractScore.set_song(self, pid, bpm, text, count, hold, feet) 104 | if count == 0: count = 1 105 | self.arrow = 0 106 | 107 | p = 1000000.0 / (count * (count + 1) / 2) 108 | self.inc = { "V": p * 10, "P": p * 10, "G": p * 5, "O": p } 109 | 110 | def stepped(self, pid, dir, curtime, etime, rating, combo): 111 | if rating == None: return 112 | self.arrow += 1 113 | self.score += self.inc.get(rating, 0) * self.arrow 114 | 115 | # L(V) = L(P) = 777, L(G) = 555 116 | # V(n) = L(r) + C * 333 117 | class FourthScore(AbstractScore): 118 | def stepped(self, pid, dir, cur_time, etime, rating, combo): 119 | if rating == None: return 120 | base = {"V": 777, "P": 777, "G": 555 } 121 | self.score += base.get(rating, 0) + combo * 333 122 | 123 | # L(V) = L(P) = 10, L(G) = 5 124 | # V(n) = L(r) * 500,000 * (F + 1) / S(N) * n 125 | 126 | # The bonus for your combo or final grade is not implemented yet. 127 | # This would require a Listener event for the end of the song. 128 | class FifthScore(ThirdScore): 129 | def set_song(self, pid, bpm, text, count, hold, feet): 130 | AbstractScore.set_song(self, pid, bpm, text, count, hold, feet) 131 | self.arrow = 0 132 | s = 500000.0 * (feet + 1) / float((count * (count + 1)) / 2) 133 | self.inc = { "V": 10 * s, "P": 10 * s, "G": 5 * s } 134 | 135 | # Max's score algorithm relys on calculating the "groove radar" values, 136 | # which we don't do. So, it stays unimplemented. 137 | 138 | # L(V) = L(P) = 10, L(G) = 5 139 | # V(n) = L(r) * 1,000,000 * F / S(N) * n 140 | 141 | # In pydance's implementation, jumps are counted as two arrows; in 142 | # 8rd, they aren't. 143 | class ExtremeScore(ThirdScore): 144 | def set_song(self, pid, bpm, text, count, hold, feet): 145 | AbstractScore.set_song(self, pid, bpm, text, count, hold, feet) 146 | if count == 0: count = 1 # Don't crash on empty songs. 147 | 148 | self.arrow = 0 149 | score_coeff = (1000000.0 * feet) / ((count * (count + 1.0)) / 2.0) 150 | self.inc = { "V": 10 * score_coeff, "P": 10 * score_coeff, 151 | "G": 5 * score_coeff } 152 | 153 | # This is closer to the grading algorithm than to a scoring algorithm. 154 | class ExtremeOniScore(AbstractScore): 155 | def stepped(self, pid, dir, cur_time, etime, rating, combo): 156 | self.score += {"V": 3, "P": 2, "G": 1}.get(rating, 0) 157 | 158 | def ok_hold(self, pid, time, dir, whichone): self.score += 3 159 | 160 | # L(V) = 10, L(P) = 9, L(G) = 5 161 | # V(n) = L(r) * 1,000,000 * H / S(N) * n 162 | class ExtremeNonstopScore(ThirdScore): 163 | def __init__(self, pid, text, game): 164 | AbstractScore.__init__(self, pid, text, game) 165 | self.song = 0 166 | 167 | def set_song(self, pid, bpm, text, count, hold, feet): 168 | AbstractScore.set_song(self, pid, bpm, text, count, hold, feet) 169 | if count == 0: count = 1 # Don't crash on empty songs. 170 | self.song += 1 171 | 172 | self.arrow = 0 173 | score_coeff = (1000000.0 * self.song) / ((count * (count + 1.0)) / 2.0) 174 | self.inc = { "V": 10 * score_coeff, "P": 9 * score_coeff, 175 | "G": 5 * score_coeff } 176 | 177 | # EZ2Dancer scoring algorithm. 178 | # http://www.annie.ne.jp/~ken/S3C21/ez2d_score.html 179 | class EZ2DancerScore(ThirdScore): 180 | def set_song(self, pid, bpm, text, count, hold, feet): 181 | AbstractScore.set_song(self, pid, bpm, text, count, hold, feet) 182 | if count == 0: count = 1 183 | self.arrow = 0 184 | self.inc = { "V": 21, "P": 9, "G": 3 } 185 | 186 | scores = [PydanceScore, FirstScore, ThirdScore, FourthScore, 187 | FifthScore, ExtremeScore, ExtremeOniScore, ExtremeNonstopScore, 188 | EZ2DancerScore] 189 | score_opt = [(0, _("pydance"), ""), (1, _("DDR 1st/2nd Mix"), ""), 190 | (2, _("DDR 3rd Mix"), ""), (3, _("DDR 4th Mix"), ""), 191 | (4, _("DDR 5th Mix"), ""), (5, _("DDR 7th/8th"), ""), 192 | (6, _("DDR 8th Oni"), ""), (7, _("DDR 8th Nonstop"), ""), 193 | (8, _("EZ2 Dancer"), "")] 194 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Set up the appropriate pydance installation makefiles. 3 | 4 | import os, sys 5 | 6 | # Check for the presence of appropriate Python and Pygame versions. 7 | def sanity_check(): 8 | print "Checking for appropriate libraries." 9 | print "Checking Python version... ", 10 | print sys.version[:5] + "." 11 | if sys.version_info < (2, 4): 12 | print "Versions of Python less than 2.4 are not supported by pydance." 13 | print "Visit http://www.python.org to upgrade." 14 | sys.exit(1) 15 | 16 | try: 17 | print "Checking for Pygame... ", 18 | import pygame 19 | print pygame.version.ver + "." 20 | if pygame.version.vernum < (1, 8): 21 | print "You have pygame, but a version less than 1.8." 22 | print "Visit http://www.pygame.org to upgrade." 23 | sys.exit(1) 24 | except ImportError: 25 | print "You don't seem to have pygame installed." 26 | print "Visit http://www.pygame.org to install it." 27 | 28 | def detect_real_os(): 29 | print "Detecting your operating system... ", 30 | if os.name == "nt": 31 | print "Windows." 32 | return "win32" 33 | elif os.name == "posix": 34 | print "POSIX -", 35 | if os.path.islink("/System/Library/CoreServices/WindowServer"): 36 | print "MacOS X." 37 | return "macosx" 38 | elif os.environ.has_key("HOME") and os.path.isdir("/etc"): 39 | print "UNIX-like." 40 | return "posix" 41 | else: 42 | print "Unknown!" 43 | print "I'm all confused as to your OS. pydance will run pretending that you're" 44 | print "UNIX, but you'll have to force this setup step if you really want to." 45 | sys.exit(1) 46 | else: 47 | print "Unknown" 48 | print "Your platform isn't supported with this install system (yet)." 49 | sys.exit(1) 50 | 51 | sanity_check() 52 | osname = detect_real_os() 53 | 54 | print 55 | 56 | if os.path.isfile("pydance." + osname + ".cfg"): 57 | fin = open("pydance." + osname + ".cfg") 58 | fout = open("pydance.cfg", "w") 59 | for line in fin: fout.write(line) 60 | fout.close() 61 | fin.close() 62 | 63 | if os.path.isfile("Makefile." + osname): 64 | fin = open("Makefile." + osname) 65 | fout = open("Makefile", "w") 66 | for line in fin: fout.write(line) 67 | fout.close() 68 | fin.close() 69 | 70 | if osname == "win32": 71 | print "Configuration for Win32 systems complete. No installation is needed." 72 | print "Make sure your pydance.cfg file points to your song directory." 73 | elif osname == "macosx": 74 | print "You're on your own, for now." 75 | elif osname == "posix": 76 | print "Configuration for UNIX-like systems complete. 'make install' should" 77 | print "properly install pydance, by default into /usr/local. You can override" 78 | print "this by setting $PREFIX. You can also set $DESTDIR, which will be" 79 | print "prepended to all installation paths." 80 | -------------------------------------------------------------------------------- /sound/assist-d.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/sound/assist-d.ogg -------------------------------------------------------------------------------- /sound/assist-l.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/sound/assist-l.ogg -------------------------------------------------------------------------------- /sound/assist-r.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/sound/assist-r.ogg -------------------------------------------------------------------------------- /sound/assist-u.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/sound/assist-u.ogg -------------------------------------------------------------------------------- /sound/back.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/sound/back.ogg -------------------------------------------------------------------------------- /sound/clicked.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/sound/clicked.ogg -------------------------------------------------------------------------------- /sound/loselife.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/sound/loselife.ogg -------------------------------------------------------------------------------- /sound/menu.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/sound/menu.ogg -------------------------------------------------------------------------------- /sound/move.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/sound/move.ogg -------------------------------------------------------------------------------- /stats.py: -------------------------------------------------------------------------------- 1 | from math import sqrt 2 | from listener import Listener 3 | 4 | # Track statistics about the kind of steps being made. 5 | class Stats(Listener): 6 | def __init__(self): 7 | self.hold_count = 0 8 | self.bad_holds = 0 9 | self.good_holds = 0 10 | self.arrow_count = 0 11 | self.maxcombo = 0 12 | self.steps = { "V": 0, "P": 0, "G": 0, "O": 0, "B": 0, "M": 0 } 13 | self.early = self.late = self.ontime = 0 14 | self._times = [] 15 | 16 | def stepped(self, pid, dir, curtime, etime, rating, combo): 17 | if rating is None: return 18 | 19 | if combo > self.maxcombo: self.maxcombo = combo 20 | self.steps[rating] += 1 21 | self.arrow_count += 1 22 | 23 | if curtime > etime: self.late += 1 24 | elif etime > curtime: self.early += 1 25 | else: self.ontime += 1 26 | 27 | if rating != "M" and rating != None: 28 | self._times.append(etime - curtime) 29 | 30 | def times(self): 31 | s = sum(self._times) 32 | avg = s / len(self._times) 33 | s2 = sum([(i - avg)**2 for i in self._times]) 34 | stddev = sqrt(s2 / (len(self._times) - 1)) 35 | return avg, stddev 36 | 37 | def ok_hold(self, pid, time, dir, whichone): 38 | self.hold_count += 1 39 | self.good_holds += 1 40 | 41 | def broke_hold(self, pid, time, dir, whichone): 42 | self.hold_count += 1 43 | self.bad_holds += 1 44 | 45 | def __getitem__(self, item): return self.steps[item] 46 | -------------------------------------------------------------------------------- /themes/dj/djenzay/djtheme.cfg: -------------------------------------------------------------------------------- 1 | [announcer] 2 | name DJ EnZay 3 | author Sean Robinson 4 | rev 1.0 5 | date 2004/06/22 6 | 7 | [menu] 8 | /neutral/blur.ogg 9 | /neutral/moves.ogg 10 | /neutral/way.ogg 11 | positive/flow.ogg 12 | positive/respect.ogg 13 | positive/scene.ogg 14 | 15 | [ingame] 16 | negative/awful.ogg 17 | negative/dayjob.ogg 18 | negative/everyone.ogg 19 | negative/flailing.ogg 20 | negative/programming.ogg 21 | negative/rubber.ogg 22 | negative/shameus.ogg 23 | neutral/blur.ogg 24 | neutral/moves.ogg 25 | neutral/way.ogg 26 | positive/flow.ogg 27 | positive/harder.ogg 28 | positive/respect.ogg 29 | positive/scene.ogg 30 | positive/sunshine.ogg 31 | 32 | [rating-!!] 33 | rankings/flawless.ogg 34 | rankings/flawless2.ogg 35 | 36 | [rating-aaa] 37 | rankings/better.ogg 38 | rankings/aaa.ogg 39 | 40 | [rating-aa] 41 | rankings/high.ogg 42 | rankings/double.ogg 43 | 44 | [rating-a] 45 | rankings/impressive.ogg 46 | rankings/effort.ogg 47 | 48 | [rating-b] 49 | rankings/gettingit.ogg 50 | rankings/tobe.ogg 51 | 52 | [rating-c] 53 | rankings/respectible.ogg 54 | rankings/doing.ogg 55 | 56 | [rating-d] 57 | rankings/disaster.ogg 58 | rankings/sure.ogg 59 | 60 | [rating-f] 61 | rankings/secondchances.ogg 62 | rankings/fail.ogg 63 | -------------------------------------------------------------------------------- /themes/dj/djenzay/negative/awful.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/negative/awful.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/negative/dayjob.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/negative/dayjob.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/negative/everyone.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/negative/everyone.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/negative/flailing.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/negative/flailing.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/negative/programming.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/negative/programming.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/negative/rubber.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/negative/rubber.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/negative/shameus.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/negative/shameus.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/neutral/blur.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/neutral/blur.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/neutral/moves.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/neutral/moves.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/neutral/way.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/neutral/way.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/positive/flow.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/positive/flow.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/positive/harder.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/positive/harder.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/positive/respect.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/positive/respect.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/positive/scene.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/positive/scene.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/positive/sunshine.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/positive/sunshine.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/rankings/aaa.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/rankings/aaa.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/rankings/better.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/rankings/better.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/rankings/disaster.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/rankings/disaster.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/rankings/doing.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/rankings/doing.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/rankings/double.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/rankings/double.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/rankings/effort.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/rankings/effort.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/rankings/fail.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/rankings/fail.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/rankings/flawless.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/rankings/flawless.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/rankings/flawless2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/rankings/flawless2.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/rankings/gettingit.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/rankings/gettingit.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/rankings/high.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/rankings/high.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/rankings/impressive.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/rankings/impressive.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/rankings/respectible.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/rankings/respectible.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/rankings/secondchances.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/rankings/secondchances.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/rankings/sure.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/rankings/sure.ogg -------------------------------------------------------------------------------- /themes/dj/djenzay/rankings/tobe.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/dj/djenzay/rankings/tobe.ogg -------------------------------------------------------------------------------- /themes/dj/none/djtheme.cfg: -------------------------------------------------------------------------------- 1 | [announcer] 2 | name No Announcer 3 | author Nat Budin 4 | rev 0.1 5 | date 05/07/2002 6 | 7 | [menu] 8 | 9 | [ingame] 10 | -------------------------------------------------------------------------------- /themes/font/VL PGothic.cfg: -------------------------------------------------------------------------------- 1 | [global] 2 | title=VL PGothic (Asian) 3 | font=VL-PGothic-Regular.ttf 4 | 5 | [loading_screen] 6 | size=40 7 | [help] 8 | size=14 9 | [error_message] 10 | size=21 11 | [diffbox] 12 | size=16 13 | 14 | [BannerDisp_title] 15 | size=40 16 | [BannerDisp_artist] 17 | size=33 18 | [BannerDisp_subtitle] 19 | size=18 20 | [BannerDisp_BPM] 21 | size=18 22 | 23 | [GameSel_list] 24 | size=18 25 | [GameSel_description] 26 | size=20 27 | [GameSel_screen_title] 28 | size=18 29 | [GameSel_selected_title] 30 | size=32 31 | 32 | [Opts_list] 33 | size=16 34 | [Opts_description] 35 | size=18 36 | [Opts_choices] 37 | size=20 38 | [Opts_choice_description] 39 | size=14 40 | 41 | [SongSel_list] 42 | size=20 43 | [SongSel_sort_mode] 44 | size=30 45 | 46 | [Menu_button_no_sub] 47 | size=20 48 | [Menu_button_if_sub] 49 | size=16 50 | [Menu_button_sub] 51 | size=12 52 | [Menu_rotating_top] 53 | size=40 54 | [Menu_credits] 55 | size=10 56 | 57 | [SongInfo_screen_title] 58 | size=34 59 | [SongInfo_controls] 60 | size=20 61 | [SongInfo_countdown] 62 | size=34 63 | [SongInfo_player] 64 | size=34 65 | [SongInfo_current_options] 66 | size=20 67 | 68 | [Crs_course_name] 69 | size=18 70 | [Crs_course_list_head] 71 | size=20 72 | [Crs_song_title] 73 | size=18 74 | [Crs_song_subtitle] 75 | size=12 76 | [Crs_list] 77 | size=18 78 | 79 | [Dance_lifebar_text] 80 | size=18 81 | [Dance_score_display] 82 | size=18 83 | [Dance_combo_display] 84 | size=18 85 | [Dance_lyrics_display] 86 | size=21 87 | [Dance_FPS_display] 88 | size=10 89 | [Dance_title_artist] 90 | size=6 91 | [Dance_elapsed_time] 92 | size=21 93 | [Dance_step_judgment] 94 | size=32 95 | [Dance_hold_judgment] 96 | size=18 97 | 98 | [MapKeys_message] 99 | size=32 100 | [MapKeys_player] 101 | size=21 102 | [MapKeys_input_type] 103 | size=19 104 | [MapKeys_entries] 105 | size=18 106 | 107 | [GrScr_text] 108 | size=18 109 | [GrScr_tocontinue] 110 | size=16 111 | 112 | [Endless_player] 113 | size=40 114 | [Endless_filter_by] 115 | size=32 116 | [Endless_filter_range] 117 | size=26 118 | -------------------------------------------------------------------------------- /themes/font/VL-PGothic-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/font/VL-PGothic-Regular.ttf -------------------------------------------------------------------------------- /themes/font/default.cfg: -------------------------------------------------------------------------------- 1 | [global] 2 | title=default 3 | 4 | 5 | [loading_screen] 6 | size=60 7 | [help] 8 | size=22 9 | [error_message] 10 | size=32 11 | [diffbox] 12 | size=24 13 | 14 | [BannerDisp_title] 15 | size=60 16 | [BannerDisp_artist] 17 | size=40 18 | [BannerDisp_subtitle] 19 | size=24 20 | [BannerDisp_BPM] 21 | size=24 22 | 23 | [GameSel_list] 24 | size=26 25 | [GameSel_description] 26 | size=30 27 | [GameSel_screen_title] 28 | size=24 29 | [GameSel_selected_title] 30 | size=48 31 | 32 | [Opts_list] 33 | size=24 34 | [Opts_description] 35 | size=28 36 | [Opts_choices] 37 | size=30 38 | [Opts_choice_description] 39 | size=22 40 | 41 | [SongSel_list] 42 | size=26 43 | [SongSel_sort_mode] 44 | size=30 45 | 46 | [Menu_button_no_sub] 47 | size=32 48 | [Menu_button_if_sub] 49 | size=26 50 | [Menu_button_sub] 51 | size=20 52 | [Menu_rotating_top] 53 | size=60 54 | [Menu_credits] 55 | size=16 56 | 57 | [SongInfo_screen_title] 58 | size=50 59 | [SongInfo_controls] 60 | size=30 61 | [SongInfo_countdown] 62 | size=50 63 | [SongInfo_player] 64 | size=50 65 | [SongInfo_current_options] 66 | size=30 67 | 68 | [Crs_course_name] 69 | size=28 70 | [Crs_course_list_head] 71 | size=30 72 | [Crs_song_title] 73 | size=28 74 | [Crs_song_subtitle] 75 | size=18 76 | [Crs_list] 77 | size=28 78 | 79 | [Dance_lifebar_text] 80 | size=28 81 | [Dance_score_display] 82 | size=28 83 | [Dance_combo_display] 84 | size=28 85 | [Dance_lyrics_display] 86 | size=32 87 | [Dance_FPS_display] 88 | size=16 89 | [Dance_title_artist] 90 | size=9 91 | [Dance_elapsed_time] 92 | size=32 93 | [Dance_step_judgment] 94 | size=48 95 | [Dance_hold_judgment] 96 | size=28 97 | 98 | [MapKeys_message] 99 | size=32 100 | [MapKeys_player] 101 | size=32 102 | [MapKeys_input_type] 103 | size=28 104 | [MapKeys_entries] 105 | size=26 106 | 107 | [GrScr_text] 108 | size=28 109 | [GrScr_tocontinue] 110 | size=24 111 | 112 | [Endless_player] 113 | size=60 114 | [Endless_filter_by] 115 | size=48 116 | [Endless_filter_range] 117 | size=40 118 | -------------------------------------------------------------------------------- /themes/gfx/32x32/ddresque.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ddresque.zip -------------------------------------------------------------------------------- /themes/gfx/32x32/default/arr_c_c_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/default/arr_c_c_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/default/arr_c_c_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/default/arr_c_c_1.png -------------------------------------------------------------------------------- /themes/gfx/32x32/default/arr_c_c_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/default/arr_c_c_2.png -------------------------------------------------------------------------------- /themes/gfx/32x32/default/arr_c_k_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/default/arr_c_k_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/default/arr_c_k_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/default/arr_c_k_1.png -------------------------------------------------------------------------------- /themes/gfx/32x32/default/arr_c_k_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/default/arr_c_k_2.png -------------------------------------------------------------------------------- /themes/gfx/32x32/default/arr_c_l_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/default/arr_c_l_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/default/arr_c_l_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/default/arr_c_l_1.png -------------------------------------------------------------------------------- /themes/gfx/32x32/default/arr_c_l_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/default/arr_c_l_2.png -------------------------------------------------------------------------------- /themes/gfx/32x32/default/arr_n_c_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/default/arr_n_c_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/default/arr_n_k_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/default/arr_n_k_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/default/arr_n_l_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/default/arr_n_l_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/default/arr_s_c_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/default/arr_s_c_4.png -------------------------------------------------------------------------------- /themes/gfx/32x32/default/arr_s_k_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/default/arr_s_k_4.png -------------------------------------------------------------------------------- /themes/gfx/32x32/default/arr_s_l_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/default/arr_s_l_4.png -------------------------------------------------------------------------------- /themes/gfx/32x32/default/is-theme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/default/is-theme -------------------------------------------------------------------------------- /themes/gfx/32x32/default/lifebar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/default/lifebar.png -------------------------------------------------------------------------------- /themes/gfx/32x32/default/oni-bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/default/oni-bar.png -------------------------------------------------------------------------------- /themes/gfx/32x32/default/oni-empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/default/oni-empty.png -------------------------------------------------------------------------------- /themes/gfx/32x32/dmxesque/arr_c_k_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/dmxesque/arr_c_k_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/dmxesque/arr_c_l_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/dmxesque/arr_c_l_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/dmxesque/arr_c_r_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/dmxesque/arr_c_r_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/dmxesque/arr_c_z_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/dmxesque/arr_c_z_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/dmxesque/arr_n_k_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/dmxesque/arr_n_k_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/dmxesque/arr_n_l_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/dmxesque/arr_n_l_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/dmxesque/arr_n_z_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/dmxesque/arr_n_z_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/dmxesque/arr_s_k_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/dmxesque/arr_s_k_4.png -------------------------------------------------------------------------------- /themes/gfx/32x32/dmxesque/arr_s_l_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/dmxesque/arr_s_l_4.png -------------------------------------------------------------------------------- /themes/gfx/32x32/dmxesque/arr_s_z_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/dmxesque/arr_s_z_4.png -------------------------------------------------------------------------------- /themes/gfx/32x32/dmxesque/is-theme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/dmxesque/is-theme -------------------------------------------------------------------------------- /themes/gfx/32x32/dmxesque/lifebar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/dmxesque/lifebar.png -------------------------------------------------------------------------------- /themes/gfx/32x32/dmxesque/oni-bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/dmxesque/oni-bar.png -------------------------------------------------------------------------------- /themes/gfx/32x32/dmxesque/oni-empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/dmxesque/oni-empty.png -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/arr_c_d_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/arr_c_d_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/arr_c_g_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/arr_c_g_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/arr_c_k_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/arr_c_k_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/arr_c_l_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/arr_c_l_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/arr_c_r_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/arr_c_r_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/arr_c_w_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/arr_c_w_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/arr_c_z_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/arr_c_z_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/arr_n_d_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/arr_n_d_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/arr_n_g_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/arr_n_g_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/arr_n_k_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/arr_n_k_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/arr_n_l_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/arr_n_l_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/arr_n_r_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/arr_n_r_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/arr_n_w_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/arr_n_w_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/arr_n_z_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/arr_n_z_0.png -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/arr_s_d_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/arr_s_d_4.png -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/arr_s_g_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/arr_s_g_4.png -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/arr_s_k_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/arr_s_k_4.png -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/arr_s_l_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/arr_s_l_4.png -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/arr_s_r_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/arr_s_r_4.png -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/arr_s_w_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/arr_s_w_4.png -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/arr_s_z_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/arr_s_z_4.png -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/is-theme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/is-theme -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/lifebar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/lifebar.png -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/oni-bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/oni-bar.png -------------------------------------------------------------------------------- /themes/gfx/32x32/ez2/oni-empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/32x32/ez2/oni-empty.png -------------------------------------------------------------------------------- /themes/gfx/48x48/ddresque.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/48x48/ddresque.zip -------------------------------------------------------------------------------- /themes/gfx/48x48/default/arr_c_c_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/48x48/default/arr_c_c_0.png -------------------------------------------------------------------------------- /themes/gfx/48x48/default/arr_c_c_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/48x48/default/arr_c_c_1.png -------------------------------------------------------------------------------- /themes/gfx/48x48/default/arr_c_c_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/48x48/default/arr_c_c_2.png -------------------------------------------------------------------------------- /themes/gfx/48x48/default/arr_c_k_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/48x48/default/arr_c_k_0.png -------------------------------------------------------------------------------- /themes/gfx/48x48/default/arr_c_k_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/48x48/default/arr_c_k_1.png -------------------------------------------------------------------------------- /themes/gfx/48x48/default/arr_c_k_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/48x48/default/arr_c_k_2.png -------------------------------------------------------------------------------- /themes/gfx/48x48/default/arr_c_l_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/48x48/default/arr_c_l_0.png -------------------------------------------------------------------------------- /themes/gfx/48x48/default/arr_c_l_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/48x48/default/arr_c_l_1.png -------------------------------------------------------------------------------- /themes/gfx/48x48/default/arr_c_l_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/48x48/default/arr_c_l_2.png -------------------------------------------------------------------------------- /themes/gfx/48x48/default/arr_n_c_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/48x48/default/arr_n_c_0.png -------------------------------------------------------------------------------- /themes/gfx/48x48/default/arr_n_k_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/48x48/default/arr_n_k_0.png -------------------------------------------------------------------------------- /themes/gfx/48x48/default/arr_n_l_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/48x48/default/arr_n_l_0.png -------------------------------------------------------------------------------- /themes/gfx/48x48/default/arr_s_c_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/48x48/default/arr_s_c_4.png -------------------------------------------------------------------------------- /themes/gfx/48x48/default/arr_s_k_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/48x48/default/arr_s_k_4.png -------------------------------------------------------------------------------- /themes/gfx/48x48/default/arr_s_l_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/48x48/default/arr_s_l_4.png -------------------------------------------------------------------------------- /themes/gfx/48x48/default/is-theme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/48x48/default/is-theme -------------------------------------------------------------------------------- /themes/gfx/48x48/default/lifebar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/48x48/default/lifebar.png -------------------------------------------------------------------------------- /themes/gfx/48x48/default/oni-bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/48x48/default/oni-bar.png -------------------------------------------------------------------------------- /themes/gfx/48x48/default/oni-empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/48x48/default/oni-empty.png -------------------------------------------------------------------------------- /themes/gfx/56x56/default/arr_c_c_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/default/arr_c_c_0.png -------------------------------------------------------------------------------- /themes/gfx/56x56/default/arr_c_c_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/default/arr_c_c_1.png -------------------------------------------------------------------------------- /themes/gfx/56x56/default/arr_c_c_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/default/arr_c_c_2.png -------------------------------------------------------------------------------- /themes/gfx/56x56/default/arr_c_k_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/default/arr_c_k_0.png -------------------------------------------------------------------------------- /themes/gfx/56x56/default/arr_c_k_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/default/arr_c_k_1.png -------------------------------------------------------------------------------- /themes/gfx/56x56/default/arr_c_k_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/default/arr_c_k_2.png -------------------------------------------------------------------------------- /themes/gfx/56x56/default/arr_n_c_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/default/arr_n_c_0.png -------------------------------------------------------------------------------- /themes/gfx/56x56/default/arr_n_k_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/default/arr_n_k_0.png -------------------------------------------------------------------------------- /themes/gfx/56x56/default/arr_s_c_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/default/arr_s_c_4.png -------------------------------------------------------------------------------- /themes/gfx/56x56/default/arr_s_k_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/default/arr_s_k_4.png -------------------------------------------------------------------------------- /themes/gfx/56x56/default/is-theme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/default/is-theme -------------------------------------------------------------------------------- /themes/gfx/56x56/default/lifebar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/default/lifebar.png -------------------------------------------------------------------------------- /themes/gfx/56x56/default/oni-bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/default/oni-bar.png -------------------------------------------------------------------------------- /themes/gfx/56x56/default/oni-empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/default/oni-empty.png -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/arr_c_d_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/arr_c_d_0.png -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/arr_c_g_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/arr_c_g_0.png -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/arr_c_k_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/arr_c_k_0.png -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/arr_c_l_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/arr_c_l_0.png -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/arr_c_r_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/arr_c_r_0.png -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/arr_c_w_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/arr_c_w_0.png -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/arr_c_z_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/arr_c_z_0.png -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/arr_n_d_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/arr_n_d_0.png -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/arr_n_g_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/arr_n_g_0.png -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/arr_n_k_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/arr_n_k_0.png -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/arr_n_l_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/arr_n_l_0.png -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/arr_n_r_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/arr_n_r_0.png -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/arr_n_w_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/arr_n_w_0.png -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/arr_n_z_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/arr_n_z_0.png -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/arr_s_d_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/arr_s_d_4.png -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/arr_s_g_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/arr_s_g_4.png -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/arr_s_k_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/arr_s_k_4.png -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/arr_s_l_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/arr_s_l_4.png -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/arr_s_r_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/arr_s_r_4.png -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/arr_s_w_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/arr_s_w_4.png -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/arr_s_z_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/arr_s_z_4.png -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/is-theme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/is-theme -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/lifebar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/lifebar.png -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/oni-bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/oni-bar.png -------------------------------------------------------------------------------- /themes/gfx/56x56/ez2/oni-empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/ez2/oni-empty.png -------------------------------------------------------------------------------- /themes/gfx/56x56/pumpesque.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/56x56/pumpesque.zip -------------------------------------------------------------------------------- /themes/gfx/64x64/bryan.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/bryan.zip -------------------------------------------------------------------------------- /themes/gfx/64x64/ddresque.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/ddresque.zip -------------------------------------------------------------------------------- /themes/gfx/64x64/default/arr_c_c_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/default/arr_c_c_0.png -------------------------------------------------------------------------------- /themes/gfx/64x64/default/arr_c_c_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/default/arr_c_c_1.png -------------------------------------------------------------------------------- /themes/gfx/64x64/default/arr_c_c_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/default/arr_c_c_2.png -------------------------------------------------------------------------------- /themes/gfx/64x64/default/arr_c_k_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/default/arr_c_k_0.png -------------------------------------------------------------------------------- /themes/gfx/64x64/default/arr_c_k_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/default/arr_c_k_1.png -------------------------------------------------------------------------------- /themes/gfx/64x64/default/arr_c_k_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/default/arr_c_k_2.png -------------------------------------------------------------------------------- /themes/gfx/64x64/default/arr_c_u_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/default/arr_c_u_0.png -------------------------------------------------------------------------------- /themes/gfx/64x64/default/arr_c_u_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/default/arr_c_u_1.png -------------------------------------------------------------------------------- /themes/gfx/64x64/default/arr_c_u_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/default/arr_c_u_2.png -------------------------------------------------------------------------------- /themes/gfx/64x64/default/arr_n_c_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/default/arr_n_c_0.png -------------------------------------------------------------------------------- /themes/gfx/64x64/default/arr_n_k_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/default/arr_n_k_0.png -------------------------------------------------------------------------------- /themes/gfx/64x64/default/arr_n_u_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/default/arr_n_u_0.png -------------------------------------------------------------------------------- /themes/gfx/64x64/default/arr_s_c_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/default/arr_s_c_4.png -------------------------------------------------------------------------------- /themes/gfx/64x64/default/arr_s_d_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/default/arr_s_d_4.png -------------------------------------------------------------------------------- /themes/gfx/64x64/default/arr_s_k_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/default/arr_s_k_4.png -------------------------------------------------------------------------------- /themes/gfx/64x64/default/arr_s_l_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/default/arr_s_l_4.png -------------------------------------------------------------------------------- /themes/gfx/64x64/default/arr_s_r_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/default/arr_s_r_4.png -------------------------------------------------------------------------------- /themes/gfx/64x64/default/arr_s_u_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/default/arr_s_u_4.png -------------------------------------------------------------------------------- /themes/gfx/64x64/default/is-theme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/default/is-theme -------------------------------------------------------------------------------- /themes/gfx/64x64/default/lifebar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/default/lifebar.png -------------------------------------------------------------------------------- /themes/gfx/64x64/default/oni-bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/default/oni-bar.png -------------------------------------------------------------------------------- /themes/gfx/64x64/default/oni-empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/default/oni-empty.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_c_d_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_c_d_0.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_c_d_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_c_d_1.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_c_d_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_c_d_2.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_c_g_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_c_g_0.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_c_g_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_c_g_1.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_c_g_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_c_g_2.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_c_k_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_c_k_0.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_c_k_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_c_k_1.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_c_k_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_c_k_2.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_c_l_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_c_l_0.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_c_l_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_c_l_1.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_c_l_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_c_l_2.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_c_r_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_c_r_0.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_c_r_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_c_r_1.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_c_r_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_c_r_2.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_c_u_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_c_u_0.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_c_u_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_c_u_1.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_c_u_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_c_u_2.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_c_w_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_c_w_0.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_c_w_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_c_w_1.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_c_w_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_c_w_2.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_c_z_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_c_z_0.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_c_z_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_c_z_1.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_c_z_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_c_z_2.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_d_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_d_0.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_d_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_d_1.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_d_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_d_2.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_d_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_d_3.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_g_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_g_0.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_g_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_g_1.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_g_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_g_2.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_g_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_g_3.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_k_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_k_0.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_k_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_k_1.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_k_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_k_2.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_k_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_k_3.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_l_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_l_0.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_l_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_l_1.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_l_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_l_2.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_l_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_l_3.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_r_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_r_0.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_r_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_r_1.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_r_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_r_2.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_r_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_r_3.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_u_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_u_0.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_u_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_u_1.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_u_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_u_2.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_u_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_u_3.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_w_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_w_0.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_w_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_w_1.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_w_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_w_2.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_w_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_w_3.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_z_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_z_0.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_z_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_z_1.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_z_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_z_2.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_n_z_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_n_z_3.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_s_d_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_s_d_4.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_s_d_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_s_d_5.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_s_d_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_s_d_6.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_s_d_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_s_d_7.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_s_l_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_s_l_4.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_s_l_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_s_l_5.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_s_l_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_s_l_6.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_s_l_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_s_l_7.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_s_r_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_s_r_4.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_s_r_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_s_r_5.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_s_r_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_s_r_6.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_s_r_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_s_r_7.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_s_u_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_s_u_4.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_s_u_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_s_u_5.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_s_u_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_s_u_6.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/arr_s_u_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/arr_s_u_7.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/is-theme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/is-theme -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/lifebar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/lifebar.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/oni-bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/oni-bar.png -------------------------------------------------------------------------------- /themes/gfx/64x64/oldschool/oni-empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/oldschool/oni-empty.png -------------------------------------------------------------------------------- /themes/gfx/64x64/soloesque.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/soloesque.zip -------------------------------------------------------------------------------- /themes/gfx/64x64/vividesque.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asb/pydance/99725bb1112549dc205803cc3ee306e0a191ce1b/themes/gfx/64x64/vividesque.zip -------------------------------------------------------------------------------- /ui.py: -------------------------------------------------------------------------------- 1 | from pygame.locals import * 2 | from constants import mainconfig 3 | import pad, pygame 4 | 5 | (PASS, CANCEL, UP, DOWN, LEFT, RIGHT, START, SELECT, CONFIRM, 6 | PGUP, PGDN, FULLSCREEN, SORT, CLEAR) = range(14) 7 | 8 | QUIT = CANCEL 9 | SCREENSHOT = SORT 10 | 11 | non_player = [CANCEL, PASS] 12 | 13 | pad_defaults = { 14 | pad.QUIT: CANCEL, 15 | pad.UP: UP, 16 | pad.DOWN: DOWN, 17 | pad.LEFT: LEFT, 18 | pad.RIGHT: RIGHT, 19 | pad.START: START, 20 | pad.UPRIGHT: CONFIRM, 21 | pad.DOWNRIGHT: PGDN, 22 | pad.UPLEFT: CANCEL, 23 | pad.DOWNLEFT: PGUP, 24 | pad.SELECT: SELECT, 25 | pad.SCREENSHOT: SCREENSHOT, 26 | } 27 | 28 | if mainconfig["centerconfirm"]: pad_defaults[pad.CENTER] = CONFIRM 29 | 30 | key_defaults = { 31 | 100 * K_f: FULLSCREEN, 32 | 100 * K_BACKSPACE: SORT, 33 | 100 * K_TAB: SELECT, 34 | 100 * K_s: SORT, 35 | 100 * K_INSERT: CANCEL, 36 | 100 * K_F11: FULLSCREEN, 37 | 100 * K_RETURN: CONFIRM, 38 | 100 * K_PAGEDOWN: PGDN, 39 | 100 * K_PAGEUP: PGUP, 40 | } 41 | 42 | # This class wraps pad and maps pad events to UI events. 43 | class UI(object): 44 | def __init__(self, handler): 45 | self.handler = handler 46 | self.events = {} 47 | self.states = {} 48 | self.last_press = ((None, None), None) 49 | self.last_repeat = 0 50 | self.merge_events(-2, key_defaults) 51 | self.merge_events(0, pad_defaults) 52 | self.merge_events(1, pad_defaults) 53 | 54 | # So we don't crash adjusting nonsensical states 55 | for i in non_player: self.add_event(i, -1, i) 56 | 57 | def add_event(self, key, pid, event): 58 | self.events[key] = event 59 | self.states[(pid, event)] = False 60 | 61 | def merge_events(self, pid, events): 62 | for key, event in events.items(): 63 | self.add_event(key, pid, event) 64 | 65 | def poll(self): 66 | pid, ev = self.handler.poll() 67 | 68 | nev = self.events.get(abs(ev), PASS) 69 | 70 | if ev < 0: 71 | self.states[(pid, nev)] = False 72 | nev = -nev 73 | elif ev != PASS: 74 | self.states[(pid, nev)] = True 75 | self.last_press = ((pid, nev), pygame.time.get_ticks()) 76 | elif (nev == PASS and self.last_press[0][1] and 77 | self.last_press[1] + 500 < pygame.time.get_ticks() and 78 | self.last_repeat + 30 < pygame.time.get_ticks() and 79 | self.states[self.last_press[0]] == True): 80 | self.last_repeat = pygame.time.get_ticks() 81 | return self.last_press[0] 82 | 83 | return (pid, nev) 84 | 85 | def forget_repeat(self): 86 | self.last_press = ((None, None), None) 87 | 88 | def wait(self, delay = 20): 89 | ev = (-1, PASS) 90 | while ev[1] == PASS: 91 | ev = self.poll() 92 | pygame.time.wait(delay) 93 | return ev 94 | 95 | def empty(self): 96 | ev = (0, QUIT) 97 | while ev[1] != PASS: ev = self.poll() 98 | 99 | def clear(self): 100 | self.empty() 101 | for k in self.states: self.states[k] = False 102 | 103 | ui = UI(pad.pad) 104 | -------------------------------------------------------------------------------- /util.py: -------------------------------------------------------------------------------- 1 | import fnmatch 2 | import os 3 | import string 4 | 5 | from i18n import * 6 | 7 | # This is the standard order to present difficulties in. 8 | # DDR (USA home version) calls "beginner" "standard". Ignore that. 9 | # Beginner, light, basic, another, standard, trick, maniac, heavy, challenge, 10 | # and oni are from DDR. Smaniac is from DWI; s-maniac is a very common typo. 11 | # Hardcore is from pydance. Para and expert are from PPP. Easy, and hard are 12 | # from TM and PIU; medium is from TM; crazy is from PIU. 13 | 14 | #We need a dummy difficulty list to include it to .pot file 15 | DIFFICULTY_LIST_I18N = [_("BEGINNER"),_("EASY"),_("LIGHT"),_("BASIC"),_("PARA"), 16 | _("ANOTHER"),_("NORMAL"),_("MEDIUM"),_("STANDARD"), 17 | _("TRICK"),_("DOUBLE"),_("HARD"),_("MANIAC"),_("HEAVY"), 18 | _("HARDCORE"),_("CHALLENGE"),_("ONI"),_("SMANIAC"), 19 | _("S-MANIAC"),_("CRAZY"),_("EXPERT")] 20 | 21 | 22 | DIFFICULTY_LIST = ["BEGINNER","EASY","LIGHT","BASIC","PARA", 23 | "ANOTHER","NORMAL","MEDIUM","STANDARD", 24 | "TRICK","DOUBLE","HARD","MANIAC","HEAVY", 25 | "HARDCORE","CHALLENGE","ONI","SMANIAC", 26 | "S-MANIAC","CRAZY","EXPERT"] 27 | 28 | def difficulty_sort(a, b): 29 | if a in DIFFICULTY_LIST and b in DIFFICULTY_LIST: 30 | return cmp(DIFFICULTY_LIST.index(a), DIFFICULTY_LIST.index(b)) 31 | elif a in DIFFICULTY_LIST: return -1 32 | elif b in DIFFICULTY_LIST: return 1 33 | else: return cmp(a, b) 34 | 35 | def difficulty_sort_key(k): 36 | try: return DIFFICULTY_LIST.index(k) 37 | except ValueError: return len(DIFFICULTY_LIST) 38 | 39 | # Return the subtitle of a song... 40 | def find_subtitle(title): 41 | for pair in [("[", "]"), ("(", ")"), ("~", "~"), ("-", "-")]: 42 | if pair[0] in title and title[-1] == pair[1]: 43 | l = title[0:-1].rindex(pair[0]) 44 | if l != 0: 45 | subtitle = title[l:] 46 | title = title[:l] 47 | return title, subtitle 48 | else: return title, "" 49 | 50 | # FIXME: We should inline this. Really. 51 | # Or not, Psyco does it for us, basically. 52 | def toRealTime(bpm, steps): 53 | return steps*0.25*60.0/bpm 54 | 55 | # Search the directory specified by path recursively for files that match 56 | # the shell wildcard pattern. A list of all matching file names is returned, 57 | # with absolute paths. 58 | def find(path, patterns): 59 | root = os.path.abspath(os.path.expanduser(path)) 60 | matches = [] 61 | 62 | for path,dirs,files in os.walk(root): 63 | for fn in files: 64 | filepath = os.path.join(path, fn) 65 | for pattern in patterns: 66 | if fnmatch.fnmatch(filepath.lower(), pattern): 67 | matches.append(filepath) 68 | break 69 | 70 | return matches 71 | 72 | # This uses a bunch of heuristics to come up with a good titlecased 73 | # string. Python's titlecase function sucks. 74 | def titlecase(title): 75 | nonletter = 0 76 | uncapped = ("in", "a", "the", "is", "for", "to", "by", "of", "de", "la") 77 | vowels = "aeiouyAEIOUY" 78 | letters = string.letters + "?!'" # Yeah, those aren't letters, but... 79 | 80 | parts = title.split() 81 | if len(parts) == 0: return "" 82 | 83 | for i,p in enumerate(parts): 84 | nonletter = 0 85 | has_vowels = False 86 | for l in p: 87 | if l not in letters: nonletter += 1 88 | if l in vowels: has_vowels = True 89 | if float(nonletter) / len(p) < 1.0/3: 90 | if p == p.upper() and has_vowels: 91 | p = parts[i] = p.lower() 92 | if p not in uncapped: 93 | p = parts[i] = p.capitalize() 94 | 95 | 96 | # Capitalize the first and last words in the name, unless they are 97 | # are "stylistically" lowercase. 98 | for i in (0, -1): 99 | if parts[i] != parts[i].lower() or parts[i] in uncapped: 100 | oldparts = parts[i] 101 | parts[i] = parts[i][0].capitalize() + oldparts[1:] 102 | 103 | return " ".join(parts) 104 | -------------------------------------------------------------------------------- /utils/findbpm.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # This is a little utility program to find the BPM for a song. 3 | # It uses least squares estimation to fit a BPM and offset to 4 | # beats tapped in by a key 5 | 6 | import getopt 7 | import sys 8 | import os 9 | import pygame, pygame.font, pygame.image, pygame.mixer 10 | from pygame.locals import * 11 | 12 | VERSION = "0.20" 13 | 14 | def usage(): 15 | print "findbpm %s - find the bpm of a song" % VERSION 16 | print "Usage: %s songfile.ogg" % sys.argv[0] 17 | print 18 | print """\ 19 | Press a key on time with the beat. An average BPM (for as long as you keep 20 | tapping) will be calculated.""" 21 | 22 | def show_message(t): 23 | screen.fill((0,0,0)) 24 | #text = font.render(t, 1, (250, 80, 80)) 25 | text = font.render(t, 1, (255, 255, 255)) 26 | textpos = text.get_rect() 27 | textpos.centerx = screen.get_rect().centerx 28 | textpos.centery = screen.get_rect().centery 29 | screen.blit(text, textpos) 30 | pygame.display.flip() 31 | 32 | def main(): 33 | try: 34 | opts, args = getopt.getopt(sys.argv[1:], "vh", ["help", "version"]) 35 | except getopt.GetoptError: 36 | usage() 37 | sys.exit(2) 38 | # FIXME: interpret opts... 39 | 40 | if len(args) != 1: 41 | usage() 42 | sys.exit(2) 43 | 44 | try: pygame.mixer.pre_init(44100, -16, 2) 45 | except: pygame.mixer.pre_init() 46 | 47 | global screen, font 48 | pygame.init() 49 | screen = pygame.display.set_mode((400, 48), HWSURFACE|DOUBLEBUF) 50 | pygame.display.set_caption('Tap to find Start, BPM') 51 | font = pygame.font.Font(None, 32) 52 | show_message('Tap to start music playing') 53 | 54 | playing = 0 55 | 56 | pygame.mixer.music.load(args[0]) 57 | 58 | while 1: 59 | event = pygame.event.wait() 60 | 61 | if event.type == QUIT or event.type == KEYDOWN and event.key == K_ESCAPE: 62 | break 63 | 64 | elif event.type == KEYDOWN: 65 | now = pygame.time.get_ticks() 66 | 67 | if not playing: 68 | pygame.mixer.music.play() 69 | music_start = now 70 | n = 0 71 | xsum = 0 72 | ysum = 0 73 | xxsum = 0 74 | xysum = 0 75 | show_message('Tap on each beat') 76 | playing = 1 77 | continue 78 | 79 | if n < 4: 80 | x = n 81 | else: 82 | # Forgive user skipping a beat 83 | x = int(0.5 + ((now - offset) * 1.0 / perbeat)) 84 | xsum += x 85 | xxsum += x * x 86 | ysum += now 87 | xysum += x * now 88 | n += 1 89 | if n < 2: 90 | show_message('%d' % x) 91 | continue 92 | denom = xsum * xsum - n * xxsum 93 | offset = (xsum * xysum - xxsum * ysum) * 1.0 / denom 94 | perbeat = (xsum * ysum - n * xysum) * 1.0 / denom 95 | bpm = 60 * 1000.0 / perbeat 96 | moffset = offset - music_start 97 | show_message('%0.6s BPM offset %d ms beat %d' % (bpm, 98 | int(moffset + 0.5), 99 | x)) 100 | 101 | if n >= 2: 102 | print 'bpm %0.6f' % bpm 103 | print 'offset %d' % int(-moffset + 0.5) 104 | 105 | if __name__ == '__main__': 106 | main() 107 | -------------------------------------------------------------------------------- /utils/pyjoy.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | import os, pygame, pygame.font, pygame.image, pygame.mixer, pygame.movie, time, sys 4 | from pygame.locals import * 5 | 6 | def main(): 7 | # init 8 | pygame.init() 9 | 10 | # look for joysticks 11 | totaljoy = pygame.joystick.get_count() 12 | print totaljoy,"joysticks total -", 13 | 14 | if totaljoy < 1: 15 | print "bailing out. Check http://clickass.org/~tgz/pyddr/faq.html" 16 | sys.exit() 17 | 18 | ddrmat = pygame.joystick.Joystick(totaljoy-1) 19 | ddrmat.init() 20 | print "last one is",ddrmat.get_numaxes(),"axes and",ddrmat.get_numbuttons(),"buttons" 21 | 22 | # set up the screen and all that stuff 23 | screen = pygame.display.set_mode((640, 480), HWSURFACE|DOUBLEBUF) 24 | pygame.display.set_caption('pyDDR') 25 | pygame.mouse.set_visible(1) 26 | 27 | 28 | while 1: 29 | 30 | event = pygame.event.poll() 31 | if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE): 32 | break 33 | 34 | # event.type == 35 | # JOYAXISMOTIONjoy, axis, value 36 | # JOYBALLMOTIONjoy, ball, rel 37 | # JOYHATMOTIONjoy, hat, value 38 | # JOYBUTTONUPjoy, button 39 | # JOYBUTTONDOWNjoy, button 40 | 41 | # joystick 42 | 43 | if event.type == JOYBUTTONDOWN: 44 | print "pressed button",event.button 45 | if event.type == JOYBUTTONUP: 46 | print "released button",event.button 47 | 48 | if event.type == JOYAXISMOTION: 49 | for i in range(8): 50 | if event.axis == i: 51 | print "axis",i,"moved to",event.value 52 | 53 | # keyboard 54 | 55 | if event.type == KEYDOWN: 56 | print "key hit: code", event.key 57 | if event.key == K_LEFT: 58 | print "LEFT keypress" 59 | if event.key == K_DOWN: 60 | print "DOWN keypress" 61 | if event.key == K_UP: 62 | print "UP keypress" 63 | if event.key == K_RIGHT: 64 | print "RIGHT keypress" 65 | if event.type == KEYUP: 66 | if event.key == K_LEFT: 67 | print "LEFT unpress" 68 | if event.key == K_DOWN: 69 | print "DOWN unpress" 70 | if event.key == K_UP: 71 | print "UP unpress" 72 | if event.key == K_RIGHT: 73 | print "RIGHT unpress" 74 | 75 | #end 76 | 77 | if __name__ == '__main__': main() 78 | --------------------------------------------------------------------------------