| public+hg@0 | 1 /*
|
|---|
| public+hg@60 | 2 * Angolmois -- the simple BMS player
|
|---|
| public+hg@83 | 3 * Copyright (c) 2005, 2007, 2009, 2012, Kang Seonghoon.
|
|---|
| public+hg@60 | 4 * Project Angolmois is copyright (c) 2003-2007, Choi Kaya (CHKY).
|
|---|
| public+hg@0 | 5 *
|
|---|
| public+hg@0 | 6 * This program is free software; you can redistribute it and/or
|
|---|
| public+hg@0 | 7 * modify it under the terms of the GNU General Public License
|
|---|
| public+hg@0 | 8 * as published by the Free Software Foundation; either version 2
|
|---|
| public+hg@0 | 9 * of the License, or (at your option) any later version.
|
|---|
| public+hg@0 | 10 *
|
|---|
| public+hg@0 | 11 * This program is distributed in the hope that it will be useful,
|
|---|
| public+hg@0 | 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|---|
| public+hg@0 | 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|---|
| public+hg@0 | 14 * GNU General Public License for more details.
|
|---|
| public+hg@0 | 15 *
|
|---|
| public+hg@0 | 16 * You should have received a copy of the GNU General Public License
|
|---|
| public+hg@0 | 17 * along with this program; if not, write to the Free Software
|
|---|
| public+hg@0 | 18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|---|
| public+hg@0 | 19 */
|
|---|
| public+hg@0 | 20
|
|---|
| public+hg@0 | 21 #include <stdio.h>
|
|---|
| public+hg@0 | 22 #include <stdlib.h>
|
|---|
| public+hg@62 | 23 #include <string.h>
|
|---|
| public+hg@85 | 24 #include <stdarg.h>
|
|---|
| public+hg@2 | 25 #include <time.h>
|
|---|
| public+hg@1 | 26 #include <SDL.h>
|
|---|
| public+hg@1 | 27 #include <SDL_mixer.h>
|
|---|
| public+hg@1 | 28 #include <SDL_image.h>
|
|---|
| public+hg@32 | 29 #include <smpeg.h>
|
|---|
| public+hg@60 | 30
|
|---|
| public+hg@85 | 31 static const char VERSION[] = "Angolmois 2.0.0 alpha 1";
|
|---|
| public+hg@85 | 32 static const char *argv0 = "angolmois";
|
|---|
| public+hg@0 | 33
|
|---|
| public+hg@20 | 34 /******************************************************************************/
|
|---|
| public+hg@20 | 35 /* constants, variables */
|
|---|
| public+hg@13 | 36
|
|---|
| public+hg@11 | 37 #define ARRAYSIZE(x) (sizeof(x)/sizeof(*x))
|
|---|
| public+hg@26 | 38 #define SWAP(x,y,t) {(t)=(x);(x)=(y);(y)=(t);}
|
|---|
| public+hg@26 | 39
|
|---|
| public+hg@85 | 40 static int opt_mode = 0, opt_showinfo = 1, opt_fullscreen = 1, opt_random = 0, opt_bga = 0;
|
|---|
| public+hg@85 | 41
|
|---|
| public+hg@61 | 42 static const char *bmsheader[] = {
|
|---|
| public+hg@61 | 43 "title", "genre", "artist", "stagefile", "bpm", "player", "playlevel",
|
|---|
| public+hg@61 | 44 "rank", "lntype", "lnobj", "wav", "bmp", "bga", "stop", "stp", "random",
|
|---|
| public+hg@62 | 45 "if", "else", "endif", 0};
|
|---|
| public+hg@61 | 46 static char *bmspath, respath[512];
|
|---|
| public+hg@61 | 47 static char **bmsline = NULL;
|
|---|
| public+hg@61 | 48 static int nbmsline = 0;
|
|---|
| public+hg@0 | 49
|
|---|
| public+hg@63 | 50 static char metadata[4][1024];
|
|---|
| public+hg@61 | 51 static double bpm = 130;
|
|---|
| public+hg@61 | 52 static int value[5] = {1, 0, 2, 1, 0};
|
|---|
| public+hg@0 | 53 #define v_player value[0]
|
|---|
| public+hg@0 | 54 #define v_playlevel value[1]
|
|---|
| public+hg@0 | 55 #define v_rank value[2]
|
|---|
| public+hg@32 | 56 #define lntype value[3]
|
|---|
| public+hg@32 | 57 #define lnobj value[4]
|
|---|
| public+hg@3 | 58
|
|---|
| public+hg@67 | 59 static char *paths[2][1296];
|
|---|
| public+hg@67 | 60 #define sndpath paths[0]
|
|---|
| public+hg@67 | 61 #define imgpath paths[1]
|
|---|
| public+hg@61 | 62 static int (*blitcmd)[8] = NULL, nblitcmd = 0;
|
|---|
| public+hg@61 | 63 static Mix_Chunk *sndres[1296];
|
|---|
| public+hg@61 | 64 static SDL_Surface *imgres[1296];
|
|---|
| public+hg@61 | 65 static int stoptab[1296] = {0};
|
|---|
| public+hg@61 | 66 static double bpmtab[1296] = {0};
|
|---|
| public+hg@61 | 67 static SMPEG *mpeg = NULL;
|
|---|
| public+hg@83 | 68 int imgmpeg = -2;
|
|---|
| public+hg@3 | 69
|
|---|
| public+hg@80 | 70 typedef struct {
|
|---|
| public+hg@80 | 71 double time; /* time */
|
|---|
| public+hg@80 | 72 int type; /* for notes: start(0) and end(1) of longnote, visible(2), invisible(3)
|
|---|
| public+hg@80 | 73 * for BGA: lower layer(0), upper layer(1), poor BGA(2)
|
|---|
| public+hg@80 | 74 * for BPM: direct(0), indirect(1)
|
|---|
| public+hg@80 | 75 * for STOP: unit=1/192 measure, indirect(0), unit=msec, direct(1)
|
|---|
| public+hg@80 | 76 * otherwise: always 0. note that removed one has type -1. */
|
|---|
| public+hg@80 | 77 int index; /* associated resource or key value (if any) */
|
|---|
| public+hg@80 | 78 } bmsnote;
|
|---|
| public+hg@80 | 79
|
|---|
| public+hg@80 | 80 static bmsnote *channel[22]; /* 0..17: notes, 18: BGM; 19: BGA; 20: BPM; 21: STOP */
|
|---|
| public+hg@61 | 81 static double _shorten[2005], *shorten = _shorten + 1;
|
|---|
| public+hg@61 | 82 static int nchannel[22] = {0};
|
|---|
| public+hg@61 | 83 static double length;
|
|---|
| public+hg@4 | 84
|
|---|
| public+hg@20 | 85 /******************************************************************************/
|
|---|
| public+hg@20 | 86 /* system dependent functions */
|
|---|
| public+hg@20 | 87
|
|---|
| public+hg@20 | 88 #ifdef WIN32
|
|---|
| public+hg@61 | 89
|
|---|
| public+hg@20 | 90 #include <windows.h>
|
|---|
| public+hg@61 | 91
|
|---|
| public+hg@61 | 92 static const char sep = '\\';
|
|---|
| public+hg@61 | 93
|
|---|
| public+hg@61 | 94 static int filedialog(char *buf)
|
|---|
| public+hg@61 | 95 {
|
|---|
| public+hg@62 | 96 OPENFILENAME ofn = {
|
|---|
| public+hg@79 | 97 .lStructSize = sizeof ofn,
|
|---|
| public+hg@62 | 98 .lpstrFilter =
|
|---|
| public+hg@62 | 99 "All Be-Music Source File (*.bms;*.bme;*.bml)\0*.bms;*.bme;*.bml\0"
|
|---|
| public+hg@62 | 100 "Be-Music Source File (*.bms)\0*.bms\0"
|
|---|
| public+hg@62 | 101 "Extended Be-Music Source File (*.bme)\0*.bme\0"
|
|---|
| public+hg@62 | 102 "Longnote Be-Music Source File (*.bml)\0*.bml\0"
|
|---|
| public+hg@62 | 103 "All Files (*.*)\0*.*\0",
|
|---|
| public+hg@62 | 104 .lpstrFile = buf,
|
|---|
| public+hg@62 | 105 .nMaxFile = 512,
|
|---|
| public+hg@62 | 106 .lpstrTitle = "Choose a file to play",
|
|---|
| public+hg@62 | 107 .Flags = OFN_HIDEREADONLY};
|
|---|
| public+hg@20 | 108 return GetOpenFileName(&ofn);
|
|---|
| public+hg@20 | 109 }
|
|---|
| public+hg@20 | 110
|
|---|
| public+hg@85 | 111 static void die(const char *msg, ...)
|
|---|
| public+hg@61 | 112 {
|
|---|
| public+hg@85 | 113 va_list v;
|
|---|
| public+hg@61 | 114 char b[512];
|
|---|
| public+hg@85 | 115 va_start(v, msg);
|
|---|
| public+hg@85 | 116 vsprintf(b, c, v);
|
|---|
| public+hg@85 | 117 va_end(a);
|
|---|
| public+hg@85 | 118 MessageBox(0, b, VERSION, 0);
|
|---|
| public+hg@85 | 119 exit(1);
|
|---|
| public+hg@61 | 120 }
|
|---|
| public+hg@61 | 121
|
|---|
| public+hg@61 | 122 static void dirinit(void) {}
|
|---|
| public+hg@61 | 123 static void dirfinal(void) {}
|
|---|
| public+hg@76 | 124 static const char *adjust_path_case(char *file) { return file; }
|
|---|
| public+hg@61 | 125
|
|---|
| public+hg@61 | 126 #else /* WIN32 */
|
|---|
| public+hg@61 | 127
|
|---|
| public+hg@20 | 128 #include <dirent.h>
|
|---|
| public+hg@20 | 129
|
|---|
| public+hg@61 | 130 static const char sep = '/';
|
|---|
| public+hg@61 | 131 static char *flist[2592];
|
|---|
| public+hg@61 | 132 static int nfiles = 0;
|
|---|
| public+hg@61 | 133
|
|---|
| public+hg@61 | 134 static int filedialog(char *buf)
|
|---|
| public+hg@61 | 135 {
|
|---|
| public+hg@20 | 136 return 0;
|
|---|
| public+hg@20 | 137 }
|
|---|
| public+hg@61 | 138
|
|---|
| public+hg@85 | 139 static void die(const char *msg, ...)
|
|---|
| public+hg@61 | 140 {
|
|---|
| public+hg@85 | 141 va_list v;
|
|---|
| public+hg@85 | 142 fprintf(stderr, "%s: ", argv0);
|
|---|
| public+hg@85 | 143 va_start(v, msg);
|
|---|
| public+hg@85 | 144 vfprintf(stderr, msg, v);
|
|---|
| public+hg@85 | 145 va_end(v);
|
|---|
| public+hg@85 | 146 fprintf(stderr, "\n");
|
|---|
| public+hg@85 | 147 exit(1);
|
|---|
| public+hg@61 | 148 }
|
|---|
| public+hg@61 | 149
|
|---|
| public+hg@78 | 150 static int stricmp(const char *a, const char *b); /* DUMMY */
|
|---|
| public+hg@61 | 151 static char *strcopy(const char*); /* DUMMY */
|
|---|
| public+hg@61 | 152
|
|---|
| public+hg@61 | 153 static void dirinit(void)
|
|---|
| public+hg@61 | 154 {
|
|---|
| public+hg@61 | 155 DIR *d;
|
|---|
| public+hg@61 | 156 struct dirent *e;
|
|---|
| public+hg@61 | 157
|
|---|
| public+hg@76 | 158 if (d = opendir(bmspath)) {
|
|---|
| public+hg@61 | 159 while (e = readdir(d))
|
|---|
| public+hg@61 | 160 flist[nfiles++] = strcopy(e->d_name);
|
|---|
| public+hg@76 | 161 closedir(d);
|
|---|
| public+hg@61 | 162 }
|
|---|
| public+hg@61 | 163 }
|
|---|
| public+hg@61 | 164
|
|---|
| public+hg@61 | 165 static void dirfinal(void)
|
|---|
| public+hg@61 | 166 {
|
|---|
| public+hg@61 | 167 while (nfiles--) free(flist[nfiles]);
|
|---|
| public+hg@61 | 168 }
|
|---|
| public+hg@61 | 169
|
|---|
| public+hg@76 | 170 static const char *adjust_path_case(char *file)
|
|---|
| public+hg@61 | 171 {
|
|---|
| public+hg@20 | 172 int i;
|
|---|
| public+hg@61 | 173 for (i = 0; i < nfiles; ++i) {
|
|---|
| public+hg@76 | 174 if (stricmp(flist[i], file)) return flist[i];
|
|---|
| public+hg@61 | 175 }
|
|---|
| public+hg@76 | 176 return ""; /* always nonexistent file */
|
|---|
| public+hg@20 | 177 }
|
|---|
| public+hg@20 | 178 #endif
|
|---|
| public+hg@20 | 179
|
|---|
| public+hg@20 | 180 /******************************************************************************/
|
|---|
| public+hg@20 | 181 /* general functions */
|
|---|
| public+hg@20 | 182
|
|---|
| public+hg@78 | 183 static int lcase(char c)
|
|---|
| public+hg@78 | 184 {
|
|---|
| public+hg@78 | 185 return ((c|32)-19)/26-3 ? c : c|32;
|
|---|
| public+hg@78 | 186 }
|
|---|
| public+hg@78 | 187
|
|---|
| public+hg@78 | 188 static int stricmp(const char *a, const char *b)
|
|---|
| public+hg@78 | 189 {
|
|---|
| public+hg@78 | 190 while (*a && *b && lcase(*a) == lcase(*b)) ++a, ++b;
|
|---|
| public+hg@78 | 191 return *a == *b;
|
|---|
| public+hg@78 | 192 }
|
|---|
| public+hg@78 | 193
|
|---|
| public+hg@61 | 194 static char *adjust_path(char *path)
|
|---|
| public+hg@61 | 195 {
|
|---|
| public+hg@76 | 196 strcpy(respath, bmspath);
|
|---|
| public+hg@76 | 197 strcat(respath, adjust_path_case(path)); /* XXX could be overflow */
|
|---|
| public+hg@20 | 198 return respath;
|
|---|
| public+hg@20 | 199 }
|
|---|
| public+hg@20 | 200
|
|---|
| public+hg@83 | 201 static char *adjust_path_with_ext(char *path, char *ext)
|
|---|
| public+hg@83 | 202 {
|
|---|
| public+hg@83 | 203 int len = strlen(bmspath);
|
|---|
| public+hg@83 | 204 char *oldext;
|
|---|
| public+hg@83 | 205 strcpy(respath, bmspath);
|
|---|
| public+hg@83 | 206 strcpy(respath + len, path);
|
|---|
| public+hg@83 | 207 oldext = strrchr(respath + len, '.');
|
|---|
| public+hg@83 | 208 if (oldext) {
|
|---|
| public+hg@83 | 209 strcpy(oldext, ext);
|
|---|
| public+hg@83 | 210 strcpy(respath + len, adjust_path_case(respath + len));
|
|---|
| public+hg@83 | 211 }
|
|---|
| public+hg@83 | 212 return respath;
|
|---|
| public+hg@83 | 213 }
|
|---|
| public+hg@83 | 214
|
|---|
| public+hg@61 | 215 static char *strcopy(const char *src)
|
|---|
| public+hg@61 | 216 {
|
|---|
| public+hg@77 | 217 char *dest = malloc(strlen(src)+1);
|
|---|
| public+hg@77 | 218 return strcpy(dest, src);
|
|---|
| public+hg@20 | 219 }
|
|---|
| public+hg@20 | 220
|
|---|
| public+hg@20 | 221 /******************************************************************************/
|
|---|
| public+hg@20 | 222 /* bms parser */
|
|---|
| public+hg@20 | 223
|
|---|
| public+hg@4 | 224 #define GET_CHANNEL(player, chan) ((player)*9+(chan)-1)
|
|---|
| public+hg@4 | 225 #define ADD_NOTE(player, chan, time, index) \
|
|---|
| public+hg@80 | 226 add_note(GET_CHANNEL(player,chan), (time), 2/*NOTE*/, (index))
|
|---|
| public+hg@4 | 227 #define ADD_INVNOTE(player, chan, time, index) \
|
|---|
| public+hg@80 | 228 add_note(GET_CHANNEL(player,chan), (time), 3/*INVNOTE*/, (index))
|
|---|
| public+hg@11 | 229 #define ADD_LNDONE(player, chan, time, index) \
|
|---|
| public+hg@80 | 230 add_note(GET_CHANNEL(player,chan), (time), 0/*LNDONE*/, (index))
|
|---|
| public+hg@4 | 231 #define ADD_LNSTART(player, chan, time, index) \
|
|---|
| public+hg@80 | 232 add_note(GET_CHANNEL(player,chan), (time), 1/*LNSTART*/, (index))
|
|---|
| public+hg@61 | 233 #define ADD_BGM(time, index) \
|
|---|
| public+hg@61 | 234 add_note(18, (time), 0, (index))
|
|---|
| public+hg@61 | 235 #define ADD_BGA(time, index) \
|
|---|
| public+hg@61 | 236 add_note(19, (time), 0, (index))
|
|---|
| public+hg@61 | 237 #define ADD_BGA2(time, index) \
|
|---|
| public+hg@61 | 238 add_note(19, (time), 1, (index))
|
|---|
| public+hg@61 | 239 #define ADD_POORBGA(time, index) \
|
|---|
| public+hg@61 | 240 add_note(19, (time), 2, (index))
|
|---|
| public+hg@61 | 241 #define ADD_BPM(time, index) \
|
|---|
| public+hg@61 | 242 add_note(20, (time), 0, (index))
|
|---|
| public+hg@61 | 243 #define ADD_BPM2(time, index) \
|
|---|
| public+hg@61 | 244 add_note(20, (time), 1, (index))
|
|---|
| public+hg@61 | 245 #define ADD_STOP(time, index) \
|
|---|
| public+hg@61 | 246 add_note(21, (time), 0, (index))
|
|---|
| public+hg@61 | 247 #define ADD_STP(time, index) \
|
|---|
| public+hg@61 | 248 add_note(21, (time), 1, (index))
|
|---|
| public+hg@0 | 249
|
|---|
| public+hg@61 | 250 static int getdigit(int n)
|
|---|
| public+hg@61 | 251 {
|
|---|
| public+hg@61 | 252 return 47<n && n<58 ? n-48 : ((n|32)-19)/26==3 ? (n|32)-87 : -1296;
|
|---|
| public+hg@61 | 253 }
|
|---|
| public+hg@1 | 254
|
|---|
| public+hg@61 | 255 static int key2index(const char *a)
|
|---|
| public+hg@61 | 256 {
|
|---|
| public+hg@61 | 257 return getdigit(*a) * 36 + getdigit(a[1]);
|
|---|
| public+hg@61 | 258 }
|
|---|
| public+hg@61 | 259
|
|---|
| public+hg@61 | 260 static int compare_bmsline(const void *a, const void *b)
|
|---|
| public+hg@61 | 261 {
|
|---|
| public+hg@2 | 262 int i, j;
|
|---|
| public+hg@61 | 263 for (i = 0; i < 6; ++i) {
|
|---|
| public+hg@61 | 264 if (j = (*(char**)a)[i] - (*(char**)b)[i]) return j;
|
|---|
| public+hg@61 | 265 }
|
|---|
| public+hg@2 | 266 return 0;
|
|---|
| public+hg@2 | 267 }
|
|---|
| public+hg@2 | 268
|
|---|
| public+hg@61 | 269 static int compare_bmsnote(const void *a, const void *b)
|
|---|
| public+hg@61 | 270 {
|
|---|
| public+hg@73 | 271 const bmsnote *A = a, *B = b;
|
|---|
| public+hg@11 | 272 return (A->time > B->time ? 1 : A->time < B->time ? -1 : A->type - B->type);
|
|---|
| public+hg@11 | 273 }
|
|---|
| public+hg@11 | 274
|
|---|
| public+hg@61 | 275 static void add_note(int chan, double time, int type, int index)
|
|---|
| public+hg@61 | 276 {
|
|---|
| public+hg@73 | 277 bmsnote temp = {time, type, index};
|
|---|
| public+hg@73 | 278 channel[chan] = realloc(channel[chan], sizeof(bmsnote) * (nchannel[chan]+1));
|
|---|
| public+hg@5 | 279 channel[chan][nchannel[chan]++] = temp;
|
|---|
| public+hg@3 | 280 }
|
|---|
| public+hg@3 | 281
|
|---|
| public+hg@61 | 282 static void remove_note(int chan, int index)
|
|---|
| public+hg@61 | 283 {
|
|---|
| public+hg@73 | 284 if (chan < 18 && channel[chan][index].index) {
|
|---|
| public+hg@73 | 285 ADD_BGM(channel[chan][index].time, channel[chan][index].index);
|
|---|
| public+hg@11 | 286 }
|
|---|
| public+hg@73 | 287 channel[chan][index].type = -1;
|
|---|
| public+hg@11 | 288 }
|
|---|
| public+hg@11 | 289
|
|---|
| public+hg@63 | 290 #define KEY_PATTERN "%2[0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]"
|
|---|
| public+hg@63 | 291
|
|---|
| public+hg@61 | 292 static int parse_bms(void)
|
|---|
| public+hg@61 | 293 {
|
|---|
| public+hg@61 | 294 FILE *fp;
|
|---|
| public+hg@65 | 295 int i, j, k;
|
|---|
| public+hg@61 | 296 int rnd = 1, ignore = 0;
|
|---|
| public+hg@11 | 297 double t;
|
|---|
| public+hg@73 | 298 char linebuf[4096], buf1[4096], buf2[4096];
|
|---|
| public+hg@62 | 299 char *line = linebuf;
|
|---|
| public+hg@61 | 300
|
|---|
| public+hg@6 | 301 fp = fopen(bmspath, "r");
|
|---|
| public+hg@61 | 302 if (!fp) return 1;
|
|---|
| public+hg@6 | 303
|
|---|
| public+hg@2 | 304 srand(time(0));
|
|---|
| public+hg@73 | 305 while (fgets(line = linebuf, sizeof linebuf, fp)) {
|
|---|
| public+hg@61 | 306 if (line[0] != '#') continue;
|
|---|
| public+hg@61 | 307 ++line;
|
|---|
| public+hg@2 | 308
|
|---|
| public+hg@62 | 309 for (i = 0; bmsheader[i]; ++i) {
|
|---|
| public+hg@61 | 310 for (j = 0; bmsheader[i][j]; ++j)
|
|---|
| public+hg@62 | 311 if (((bmsheader[i][j] ^ line[j]) | 32) != 32) break;
|
|---|
| public+hg@61 | 312 if (!bmsheader[i][j]) break;
|
|---|
| public+hg@0 | 313 }
|
|---|
| public+hg@61 | 314
|
|---|
| public+hg@61 | 315 switch (i) {
|
|---|
| public+hg@32 | 316 case 15: /* random */
|
|---|
| public+hg@63 | 317 if (sscanf(line+j, "%*[ ]%d", &j) >= 1) {
|
|---|
| public+hg@63 | 318 rnd = rand() % abs(j) + 1;
|
|---|
| public+hg@61 | 319 }
|
|---|
| public+hg@0 | 320 break;
|
|---|
| public+hg@61 | 321
|
|---|
| public+hg@32 | 322 case 16: /* if */
|
|---|
| public+hg@63 | 323 if (sscanf(line+j, "%*[ ]%d", &j) >= 1) {
|
|---|
| public+hg@63 | 324 ignore = (rnd != j);
|
|---|
| public+hg@63 | 325 }
|
|---|
| public+hg@2 | 326 break;
|
|---|
| public+hg@61 | 327
|
|---|
| public+hg@32 | 328 case 17: /* else */
|
|---|
| public+hg@2 | 329 ignore = !ignore;
|
|---|
| public+hg@2 | 330 break;
|
|---|
| public+hg@61 | 331
|
|---|
| public+hg@32 | 332 case 18: /* endif */
|
|---|
| public+hg@2 | 333 ignore = 0;
|
|---|
| public+hg@2 | 334 break;
|
|---|
| public+hg@2 | 335 }
|
|---|
| public+hg@63 | 336
|
|---|
| public+hg@61 | 337 if (!ignore) {
|
|---|
| public+hg@61 | 338 switch (i) {
|
|---|
| public+hg@2 | 339 case 0: /* title */
|
|---|
| public+hg@2 | 340 case 1: /* genre */
|
|---|
| public+hg@2 | 341 case 2: /* artist */
|
|---|
| public+hg@2 | 342 case 3: /* stagefile */
|
|---|
| public+hg@67 | 343 sscanf(line+j, "%*[ ]%[^\r\n]", metadata[i]);
|
|---|
| public+hg@2 | 344 break;
|
|---|
| public+hg@61 | 345
|
|---|
| public+hg@2 | 346 case 4: /* bpm */
|
|---|
| public+hg@63 | 347 if (sscanf(line+j, "%*[ ]%lf", &bpm) >= 1) {
|
|---|
| public+hg@63 | 348 /* do nothing, bpm is set */
|
|---|
| public+hg@63 | 349 } else if (sscanf(line+j, KEY_PATTERN "%*[ ]%lf", buf1, &t) >= 2) {
|
|---|
| public+hg@63 | 350 i = key2index(buf1);
|
|---|
| public+hg@63 | 351 if (i >= 0) bpmtab[i] = t;
|
|---|
| public+hg@2 | 352 }
|
|---|
| public+hg@2 | 353 break;
|
|---|
| public+hg@61 | 354
|
|---|
| public+hg@2 | 355 case 5: /* player */
|
|---|
| public+hg@2 | 356 case 6: /* playlevel */
|
|---|
| public+hg@2 | 357 case 7: /* rank */
|
|---|
| public+hg@32 | 358 case 8: /* lntype */
|
|---|
| public+hg@63 | 359 sscanf(line+j, "%*[ ]%d", &value[i-5]);
|
|---|
| public+hg@2 | 360 break;
|
|---|
| public+hg@61 | 361
|
|---|
| public+hg@32 | 362 case 9: /* lnobj */
|
|---|
| public+hg@63 | 363 if (sscanf(line+j, "%*[ ]" KEY_PATTERN, buf1) >= 1) {
|
|---|
| public+hg@63 | 364 lnobj = key2index(buf1);
|
|---|
| public+hg@63 | 365 }
|
|---|
| public+hg@2 | 366 break;
|
|---|
| public+hg@61 | 367
|
|---|
| public+hg@32 | 368 case 10: /* wav## */
|
|---|
| public+hg@32 | 369 case 11: /* bmp## */
|
|---|
| public+hg@67 | 370 if (sscanf(line+j, KEY_PATTERN "%*[ ]%[^\r\n]", buf1, buf2) >= 2) {
|
|---|
| public+hg@67 | 371 j = key2index(buf1);
|
|---|
| public+hg@67 | 372 if (j >= 0) {
|
|---|
| public+hg@77 | 373 free(paths[i-10][j]);
|
|---|
| public+hg@67 | 374 paths[i-10][j] = strcopy(buf2);
|
|---|
| public+hg@63 | 375 }
|
|---|
| public+hg@61 | 376 }
|
|---|
| public+hg@2 | 377 break;
|
|---|
| public+hg@61 | 378
|
|---|
| public+hg@32 | 379 case 12: /* bga## */
|
|---|
| public+hg@24 | 380 i = nblitcmd;
|
|---|
| public+hg@24 | 381 blitcmd = realloc(blitcmd, sizeof(int) * 8 * (i+1));
|
|---|
| public+hg@64 | 382 if (sscanf(line+j, KEY_PATTERN "%*[ ]" KEY_PATTERN "%*[ ]%d %d %d %d %d %d",
|
|---|
| public+hg@63 | 383 buf1, buf2, blitcmd[i]+2, blitcmd[i]+3, blitcmd[i]+4,
|
|---|
| public+hg@63 | 384 blitcmd[i]+5, blitcmd[i]+6, blitcmd[i]+7) >= 8) {
|
|---|
| public+hg@63 | 385 blitcmd[i][0] = key2index(buf1);
|
|---|
| public+hg@63 | 386 blitcmd[i][1] = key2index(buf2);
|
|---|
| public+hg@63 | 387 if (blitcmd[i][0] >= 0 && blitcmd[i][1] >= 0) ++nblitcmd;
|
|---|
| public+hg@61 | 388 }
|
|---|
| public+hg@2 | 389 break;
|
|---|
| public+hg@61 | 390
|
|---|
| public+hg@32 | 391 case 13: /* stop## */
|
|---|
| public+hg@63 | 392 if (sscanf(line+j, KEY_PATTERN "%*[ ]%d", buf1, &j) >= 2) {
|
|---|
| public+hg@63 | 393 i = key2index(buf1);
|
|---|
| public+hg@63 | 394 if (i >= 0) stoptab[i] = j;
|
|---|
| public+hg@63 | 395 }
|
|---|
| public+hg@2 | 396 break;
|
|---|
| public+hg@61 | 397
|
|---|
| public+hg@32 | 398 case 14: /* stp## */
|
|---|
| public+hg@64 | 399 if (sscanf(line+j, "%d.%d %d", &i, &j, &k) >= 3) {
|
|---|
| public+hg@63 | 400 ADD_STP(i+j/1e3, k);
|
|---|
| public+hg@63 | 401 }
|
|---|
| public+hg@2 | 402 break;
|
|---|
| public+hg@61 | 403
|
|---|
| public+hg@63 | 404 case 19: /* #####:... */
|
|---|
| public+hg@63 | 405 /* only check validity, do not store them yet */
|
|---|
| public+hg@63 | 406 if (sscanf(line+j, "%*5c:%c", buf1) >= 1) {
|
|---|
| public+hg@63 | 407 bmsline = realloc(bmsline, sizeof(char*) * (nbmsline+1));
|
|---|
| public+hg@63 | 408 bmsline[nbmsline] = strcopy(line);
|
|---|
| public+hg@63 | 409 ++nbmsline;
|
|---|
| public+hg@63 | 410 }
|
|---|
| public+hg@1 | 411 }
|
|---|
| public+hg@0 | 412 }
|
|---|
| public+hg@0 | 413 }
|
|---|
| public+hg@6 | 414 fclose(fp);
|
|---|
| public+hg@2 | 415
|
|---|
| public+hg@65 | 416 return 0;
|
|---|
| public+hg@65 | 417 }
|
|---|
| public+hg@65 | 418
|
|---|
| public+hg@65 | 419 static int parse_bmsline(void)
|
|---|
| public+hg@65 | 420 {
|
|---|
| public+hg@65 | 421 int prev[40] = {0};
|
|---|
| public+hg@65 | 422 int i, j, k, a, b, c;
|
|---|
| public+hg@65 | 423 int measure, chan;
|
|---|
| public+hg@65 | 424 double t;
|
|---|
| public+hg@65 | 425
|
|---|
| public+hg@2 | 426 qsort(bmsline, nbmsline, sizeof(char*), compare_bmsline);
|
|---|
| public+hg@65 | 427
|
|---|
| public+hg@61 | 428 for (i = 0; i < nbmsline; ++i) {
|
|---|
| public+hg@65 | 429 j = atoi(bmsline[i]);
|
|---|
| public+hg@61 | 430 measure = j / 100;
|
|---|
| public+hg@61 | 431 chan = j % 100;
|
|---|
| public+hg@61 | 432 if (chan == 2) {
|
|---|
| public+hg@22 | 433 shorten[measure] = atof(bmsline[i]+6);
|
|---|
| public+hg@3 | 434 } else {
|
|---|
| public+hg@65 | 435 j = 6 + strspn(bmsline[i]+6, " \t\r\n");
|
|---|
| public+hg@65 | 436 a = strcspn(bmsline[i]+j, " \t\r\n") / 2;
|
|---|
| public+hg@61 | 437 for (k = 0; k < a; ++k, j+=2) {
|
|---|
| public+hg@30 | 438 b = key2index(bmsline[i]+j);
|
|---|
| public+hg@11 | 439 t = measure + 1. * k / a;
|
|---|
| public+hg@61 | 440 if (b) {
|
|---|
| public+hg@61 | 441 if (chan == 1) {
|
|---|
| public+hg@11 | 442 ADD_BGM(t, b);
|
|---|
| public+hg@61 | 443 } else if (chan == 3 && (b/36<16 && b%36<16)) {
|
|---|
| public+hg@11 | 444 ADD_BPM(t, b/36*16+b%36);
|
|---|
| public+hg@61 | 445 } else if (chan == 4) {
|
|---|
| public+hg@11 | 446 ADD_BGA(t, b);
|
|---|
| public+hg@61 | 447 } else if (chan == 6) {
|
|---|
| public+hg@11 | 448 ADD_POORBGA(t, b);
|
|---|
| public+hg@61 | 449 } else if (chan == 7) {
|
|---|
| public+hg@11 | 450 ADD_BGA2(t, b);
|
|---|
| public+hg@61 | 451 } else if (chan == 8) {
|
|---|
| public+hg@11 | 452 ADD_BPM2(t, b);
|
|---|
| public+hg@61 | 453 } else if (chan == 9) {
|
|---|
| public+hg@11 | 454 ADD_STOP(t, b);
|
|---|
| public+hg@61 | 455 } else if (chan % 10 != 0 && chan > 9 && chan < 30) {
|
|---|
| public+hg@61 | 456 if (lnobj && b == lnobj) {
|
|---|
| public+hg@10 | 457 c = GET_CHANNEL(chan>20, chan%10);
|
|---|
| public+hg@80 | 458 if (nchannel[c] && channel[c][nchannel[c]-1].type==2/*NOTE*/) {
|
|---|
| public+hg@80 | 459 channel[c][nchannel[c]-1].type = 1/*LNSTART*/;
|
|---|
| public+hg@11 | 460 ADD_LNDONE(chan>20, chan%10, t, b);
|
|---|
| public+hg@5 | 461 }
|
|---|
| public+hg@5 | 462 } else {
|
|---|
| public+hg@11 | 463 ADD_NOTE(chan>20, chan%10, t, b);
|
|---|
| public+hg@4 | 464 }
|
|---|
| public+hg@61 | 465 } else if (chan % 10 != 0 && chan > 29 && chan < 50) {
|
|---|
| public+hg@11 | 466 ADD_INVNOTE(chan>40, chan%10, t, b);
|
|---|
| public+hg@4 | 467 }
|
|---|
| public+hg@5 | 468 }
|
|---|
| public+hg@61 | 469 if (chan % 10 != 0 && chan > 49 && chan < 70) {
|
|---|
| public+hg@61 | 470 if (lntype == 1 && b) {
|
|---|
| public+hg@61 | 471 if (prev[chan-50]) {
|
|---|
| public+hg@4 | 472 prev[chan-50] = 0;
|
|---|
| public+hg@11 | 473 ADD_LNDONE(chan>60, chan%10, t, 0);
|
|---|
| public+hg@4 | 474 } else {
|
|---|
| public+hg@4 | 475 prev[chan-50] = b;
|
|---|
| public+hg@11 | 476 ADD_LNSTART(chan>60, chan%10, t, b);
|
|---|
| public+hg@4 | 477 }
|
|---|
| public+hg@61 | 478 } else if (lntype == 2) {
|
|---|
| public+hg@61 | 479 if (prev[chan-50] || prev[chan-50] != b) {
|
|---|
| public+hg@61 | 480 if (prev[chan-50]) {
|
|---|
| public+hg@61 | 481 if (prev[chan-30] + 1 < measure) {
|
|---|
| public+hg@12 | 482 ADD_LNDONE(chan>60, chan%10, prev[chan-30]+1, 0);
|
|---|
| public+hg@61 | 483 } else if (prev[chan-50] != b) {
|
|---|
| public+hg@12 | 484 ADD_LNDONE(chan>60, chan%10, t, 0);
|
|---|
| public+hg@12 | 485 }
|
|---|
| public+hg@10 | 486 }
|
|---|
| public+hg@61 | 487 if (b && (prev[chan-50]!=b || prev[chan-30]+1<measure)) {
|
|---|
| public+hg@11 | 488 ADD_LNSTART(chan>60, chan%10, t, b);
|
|---|
| public+hg@4 | 489 }
|
|---|
| public+hg@12 | 490 prev[chan-30] = measure;
|
|---|
| public+hg@12 | 491 prev[chan-50] = b;
|
|---|
| public+hg@4 | 492 }
|
|---|
| public+hg@4 | 493 }
|
|---|
| public+hg@3 | 494 }
|
|---|
| public+hg@3 | 495 }
|
|---|
| public+hg@3 | 496 }
|
|---|
| public+hg@12 | 497 free(bmsline[i]);
|
|---|
| public+hg@3 | 498 }
|
|---|
| public+hg@12 | 499 free(bmsline);
|
|---|
| public+hg@30 | 500 length = measure + 2;
|
|---|
| public+hg@61 | 501 for (i = 0; i < 20; ++i) {
|
|---|
| public+hg@61 | 502 if (prev[i]) {
|
|---|
| public+hg@61 | 503 if (lntype == 2 && prev[i+20] + 1 < measure) {
|
|---|
| public+hg@12 | 504 ADD_LNDONE(i>10, i%10, prev[i+20]+1, 0);
|
|---|
| public+hg@12 | 505 } else {
|
|---|
| public+hg@30 | 506 ADD_LNDONE(i>10, i%10, length - 1, 0);
|
|---|
| public+hg@12 | 507 }
|
|---|
| public+hg@4 | 508 }
|
|---|
| public+hg@4 | 509 }
|
|---|
| public+hg@61 | 510
|
|---|
| public+hg@65 | 511 return 0;
|
|---|
| public+hg@65 | 512 }
|
|---|
| public+hg@65 | 513
|
|---|
| public+hg@65 | 514 static int sanitize_bmsline(void)
|
|---|
| public+hg@65 | 515 {
|
|---|
| public+hg@79 | 516 int i, j, k, b, c;
|
|---|
| public+hg@65 | 517
|
|---|
| public+hg@61 | 518 for (i = 0; i < 22; ++i) {
|
|---|
| public+hg@61 | 519 if (!channel[i]) continue;
|
|---|
| public+hg@73 | 520 qsort(channel[i], nchannel[i], sizeof(bmsnote), compare_bmsnote);
|
|---|
| public+hg@79 | 521
|
|---|
| public+hg@61 | 522 if (i != 18 && i < 21) {
|
|---|
| public+hg@61 | 523 b = 0;
|
|---|
| public+hg@79 | 524 j = 0;
|
|---|
| public+hg@79 | 525 while (j < nchannel[i]) {
|
|---|
| public+hg@79 | 526 k = j;
|
|---|
| public+hg@79 | 527 c = 0;
|
|---|
| public+hg@79 | 528 for (k = j; k < nchannel[i] && channel[i][k].time <= channel[i][j].time; ++k) {
|
|---|
| public+hg@79 | 529 if (c & 1 << channel[i][k].type) {
|
|---|
| public+hg@79 | 530 remove_note(i, k);
|
|---|
| public+hg@79 | 531 } else {
|
|---|
| public+hg@79 | 532 c |= 1 << channel[i][k].type;
|
|---|
| public+hg@11 | 533 }
|
|---|
| public+hg@11 | 534 }
|
|---|
| public+hg@79 | 535
|
|---|
| public+hg@79 | 536 if (b) {
|
|---|
| public+hg@79 | 537 /* remove starting longnote if there's no ending longnote */
|
|---|
| public+hg@80 | 538 c &= ~(c & 1 ? 0 : 2);
|
|---|
| public+hg@79 | 539 /* remove visible note */
|
|---|
| public+hg@80 | 540 c &= ~4;
|
|---|
| public+hg@80 | 541 /* remove invisible note if there is any longnote */
|
|---|
| public+hg@80 | 542 c &= ~(c & 3 ? 8 : 0);
|
|---|
| public+hg@79 | 543
|
|---|
| public+hg@80 | 544 b = !(c & 1);
|
|---|
| public+hg@79 | 545 } else {
|
|---|
| public+hg@79 | 546 /* remove starting longnote if there's also ending longnote */
|
|---|
| public+hg@80 | 547 c &= ~(c & 1 ? 2 : 0);
|
|---|
| public+hg@79 | 548 /* remove ending longnote */
|
|---|
| public+hg@80 | 549 c &= ~1;
|
|---|
| public+hg@80 | 550 /* keep only one note, in the order of importance */
|
|---|
| public+hg@80 | 551 c &= -c;
|
|---|
| public+hg@79 | 552
|
|---|
| public+hg@80 | 553 b = (c & 2);
|
|---|
| public+hg@79 | 554 }
|
|---|
| public+hg@79 | 555
|
|---|
| public+hg@79 | 556 for (; j < k; ++j) {
|
|---|
| public+hg@79 | 557 if (channel[i][j].type < 0) continue;
|
|---|
| public+hg@79 | 558
|
|---|
| public+hg@79 | 559 if (i < 18 && !(c & 1 << channel[i][j].type)) {
|
|---|
| public+hg@79 | 560 remove_note(i, j);
|
|---|
| public+hg@79 | 561 }
|
|---|
| public+hg@79 | 562 }
|
|---|
| public+hg@11 | 563 }
|
|---|
| public+hg@79 | 564 if (i < 18 && b) {
|
|---|
| public+hg@79 | 565 /* remove last starting longnote which is unfinished */
|
|---|
| public+hg@73 | 566 while (j >= 0 && channel[i][--j].type < 0);
|
|---|
| public+hg@80 | 567 if (j >= 0 && channel[i][j].type == 1/*LNSTART*/) remove_note(i, j);
|
|---|
| public+hg@11 | 568 }
|
|---|
| public+hg@11 | 569 }
|
|---|
| public+hg@11 | 570 k = 0;
|
|---|
| public+hg@61 | 571 for (j = 0; j < nchannel[i]; ++j) {
|
|---|
| public+hg@73 | 572 if (channel[i][j].type >= 0) {
|
|---|
| public+hg@61 | 573 channel[i][j-k] = channel[i][j];
|
|---|
| public+hg@61 | 574 } else {
|
|---|
| public+hg@61 | 575 ++k;
|
|---|
| public+hg@61 | 576 }
|
|---|
| public+hg@11 | 577 }
|
|---|
| public+hg@11 | 578 nchannel[i] -= k;
|
|---|
| public+hg@11 | 579 }
|
|---|
| public+hg@11 | 580
|
|---|
| public+hg@61 | 581 for (i = 0; i < 2005; ++i) {
|
|---|
| public+hg@61 | 582 if (_shorten[i] <= .001)
|
|---|
| public+hg@30 | 583 _shorten[i] = 1;
|
|---|
| public+hg@61 | 584 }
|
|---|
| public+hg@16 | 585
|
|---|
| public+hg@6 | 586 return 0;
|
|---|
| public+hg@6 | 587 }
|
|---|
| public+hg@4 | 588
|
|---|
| public+hg@65 | 589 static int read_bms(void)
|
|---|
| public+hg@65 | 590 {
|
|---|
| public+hg@65 | 591 if (parse_bms()) return 1;
|
|---|
| public+hg@65 | 592 if (parse_bmsline()) return 1;
|
|---|
| public+hg@65 | 593 if (sanitize_bmsline()) return 1;
|
|---|
| public+hg@65 | 594
|
|---|
| public+hg@65 | 595 return 0;
|
|---|
| public+hg@65 | 596 }
|
|---|
| public+hg@65 | 597
|
|---|
| public+hg@61 | 598 static SDL_Surface *newsurface(int f, int w, int h); /* DUMMY */
|
|---|
| public+hg@61 | 599 static SDL_Rect *newrect(int x, int y, int w, int h); /* DUMMY */
|
|---|
| public+hg@61 | 600
|
|---|
| public+hg@61 | 601 static int load_resource(void (*callback)(const char *))
|
|---|
| public+hg@61 | 602 {
|
|---|
| public+hg@13 | 603 SDL_Surface *temp;
|
|---|
| public+hg@83 | 604 int i;
|
|---|
| public+hg@61 | 605
|
|---|
| public+hg@61 | 606 for (i = 0; i < 1296; ++i) {
|
|---|
| public+hg@61 | 607 if (sndpath[i]) {
|
|---|
| public+hg@61 | 608 if (callback) callback(sndpath[i]);
|
|---|
| public+hg@76 | 609 sndres[i] = Mix_LoadWAV(adjust_path(sndpath[i]));
|
|---|
| public+hg@83 | 610 if (!sndres[i]) sndres[i] = Mix_LoadWAV(adjust_path_with_ext(sndpath[i], ".mp3"));
|
|---|
| public+hg@83 | 611 if (!sndres[i]) sndres[i] = Mix_LoadWAV(adjust_path_with_ext(sndpath[i], ".ogg"));
|
|---|
| public+hg@83 | 612 free(sndpath[i]);
|
|---|
| public+hg@83 | 613 sndpath[i] = 0;
|
|---|
| public+hg@13 | 614 }
|
|---|
| public+hg@61 | 615 if (imgpath[i]) {
|
|---|
| public+hg@83 | 616 char *ext = strrchr(imgpath[i], '.');
|
|---|
| public+hg@61 | 617 if (callback) callback(imgpath[i]);
|
|---|
| public+hg@85 | 618 if (ext && stricmp(ext, ".mpg") && opt_bga < 1 && !mpeg) {
|
|---|
| public+hg@83 | 619 mpeg = SMPEG_new(adjust_path(imgpath[i]), NULL, 0);
|
|---|
| public+hg@83 | 620 imgmpeg = i;
|
|---|
| public+hg@85 | 621 } else if (opt_bga < 2) {
|
|---|
| public+hg@83 | 622 temp = IMG_Load(adjust_path(imgpath[i]));
|
|---|
| public+hg@83 | 623 if (!temp) temp = IMG_Load(adjust_path_with_ext(imgpath[i], ".png"));
|
|---|
| public+hg@83 | 624 if (!temp) temp = IMG_Load(adjust_path_with_ext(imgpath[i], ".jpg"));
|
|---|
| public+hg@83 | 625 if (temp) {
|
|---|
| public+hg@83 | 626 imgres[i] = SDL_DisplayFormat(temp);
|
|---|
| public+hg@83 | 627 SDL_FreeSurface(temp);
|
|---|
| public+hg@83 | 628 SDL_SetColorKey(imgres[i], SDL_SRCCOLORKEY|SDL_RLEACCEL, 0);
|
|---|
| public+hg@83 | 629 }
|
|---|
| public+hg@13 | 630 }
|
|---|
| public+hg@61 | 631 free(imgpath[i]);
|
|---|
| public+hg@61 | 632 imgpath[i] = 0;
|
|---|
| public+hg@11 | 633 }
|
|---|
| public+hg@6 | 634 }
|
|---|
| public+hg@61 | 635
|
|---|
| public+hg@61 | 636 for (i = 0; i < nblitcmd; ++i) {
|
|---|
| public+hg@61 | 637 if (blitcmd[i][0]<0 || blitcmd[i][1]<0 || !imgres[blitcmd[i][1]]) continue;
|
|---|
| public+hg@24 | 638 temp = imgres[blitcmd[i][0]];
|
|---|
| public+hg@61 | 639 if (!temp) {
|
|---|
| public+hg@24 | 640 imgres[blitcmd[i][0]] = temp = newsurface(SDL_SWSURFACE, 256, 256);
|
|---|
| public+hg@83 | 641 SDL_FillRect(temp, 0, SDL_MapRGB(imgres[blitcmd[i][0]]->format, 0, 0, 0));
|
|---|
| public+hg@24 | 642 SDL_SetColorKey(temp, SDL_SRCCOLORKEY|SDL_RLEACCEL, 0);
|
|---|
| public+hg@24 | 643 }
|
|---|
| public+hg@61 | 644 if (blitcmd[i][2] < 0) blitcmd[i][2] = 0;
|
|---|
| public+hg@61 | 645 if (blitcmd[i][3] < 0) blitcmd[i][3] = 0;
|
|---|
| public+hg@61 | 646 if (blitcmd[i][4] > blitcmd[i][2] + 256) blitcmd[i][4] = blitcmd[i][2] + 256;
|
|---|
| public+hg@61 | 647 if (blitcmd[i][5] > blitcmd[i][3] + 256) blitcmd[i][5] = blitcmd[i][3] + 256;
|
|---|
| public+hg@24 | 648 SDL_BlitSurface(imgres[blitcmd[i][1]],
|
|---|
| public+hg@24 | 649 newrect(blitcmd[i][2], blitcmd[i][3], blitcmd[i][4]-blitcmd[i][2], blitcmd[i][5]-blitcmd[i][3]),
|
|---|
| public+hg@24 | 650 temp, newrect(blitcmd[i][6], blitcmd[i][7], 0, 0));
|
|---|
| public+hg@24 | 651 }
|
|---|
| public+hg@24 | 652 free(blitcmd);
|
|---|
| public+hg@61 | 653
|
|---|
| public+hg@5 | 654 return 0;
|
|---|
| public+hg@5 | 655 }
|
|---|
| public+hg@5 | 656
|
|---|
| public+hg@61 | 657 static int xflag, xnnotes, xscore; /* DUMMY */
|
|---|
| public+hg@61 | 658
|
|---|
| public+hg@13 | 659 /*
|
|---|
| public+hg@13 | 660 bit 0: it uses 7 keys?
|
|---|
| public+hg@13 | 661 bit 1: it uses long-note?
|
|---|
| public+hg@13 | 662 bit 2: it uses pedal?
|
|---|
| public+hg@18 | 663 bit 3: it has bpm variation?
|
|---|
| public+hg@13 | 664 */
|
|---|
| public+hg@61 | 665 static void get_bms_info(void)
|
|---|
| public+hg@61 | 666 {
|
|---|
| public+hg@13 | 667 int i, j;
|
|---|
| public+hg@61 | 668
|
|---|
| public+hg@30 | 669 xflag = xnnotes = 0;
|
|---|
| public+hg@61 | 670 if (nchannel[7] || nchannel[8] || nchannel[16] || nchannel[17]) xflag |= 1;
|
|---|
| public+hg@61 | 671 if (nchannel[6] || nchannel[15]) xflag |= 4;
|
|---|
| public+hg@61 | 672 if (nchannel[20]) xflag |= 8;
|
|---|
| public+hg@61 | 673 for (i = 0; i < 18; ++i) {
|
|---|
| public+hg@61 | 674 for (j = 0; j < nchannel[i]; ++j) {
|
|---|
| public+hg@80 | 675 if (channel[i][j].type == 1/*LNSTART*/) {
|
|---|
| public+hg@80 | 676 xflag |= 2;
|
|---|
| public+hg@80 | 677 ++xnnotes;
|
|---|
| public+hg@80 | 678 } else if (channel[i][j].type == 2/*NOTE*/) {
|
|---|
| public+hg@80 | 679 ++xnnotes;
|
|---|
| public+hg@80 | 680 }
|
|---|
| public+hg@11 | 681 }
|
|---|
| public+hg@30 | 682 }
|
|---|
| public+hg@61 | 683 for (i = 0; i < xnnotes; ++i) {
|
|---|
| public+hg@30 | 684 xscore += (int)(300 * (1 + 1. * i / xnnotes));
|
|---|
| public+hg@61 | 685 }
|
|---|
| public+hg@30 | 686 }
|
|---|
| public+hg@30 | 687
|
|---|
| public+hg@61 | 688 static double adjust_object_position(double base, double time); /* DUMMY */
|
|---|
| public+hg@61 | 689
|
|---|
| public+hg@61 | 690 static int pcur[22]; /* DUMMY */
|
|---|
| public+hg@61 | 691
|
|---|
| public+hg@61 | 692 static int get_bms_duration(void)
|
|---|
| public+hg@61 | 693 {
|
|---|
| public+hg@30 | 694 int i, j, time, rtime, ttime;
|
|---|
| public+hg@30 | 695 double pos, xbpm, tmp;
|
|---|
| public+hg@30 | 696
|
|---|
| public+hg@30 | 697 xbpm = bpm;
|
|---|
| public+hg@61 | 698 time = rtime = 0;
|
|---|
| public+hg@61 | 699 pos = -1;
|
|---|
| public+hg@61 | 700 while (1) {
|
|---|
| public+hg@61 | 701 for (i = 0, j = -1; i < 22; ++i) {
|
|---|
| public+hg@73 | 702 if (pcur[i] < nchannel[i] && (j < 0 || channel[i][pcur[i]].time < channel[j][pcur[j]].time)) j = i;
|
|---|
| public+hg@61 | 703 }
|
|---|
| public+hg@61 | 704 if (j < 0) {
|
|---|
| public+hg@30 | 705 time += (int)(adjust_object_position(pos, length) * 24e7 / xbpm);
|
|---|
| public+hg@30 | 706 break;
|
|---|
| public+hg@30 | 707 }
|
|---|
| public+hg@73 | 708 time += (int)(adjust_object_position(pos, channel[j][pcur[j]].time) * 24e7 / xbpm);
|
|---|
| public+hg@61 | 709
|
|---|
| public+hg@73 | 710 i = channel[j][pcur[j]].index;
|
|---|
| public+hg@61 | 711 ttime = 0;
|
|---|
| public+hg@61 | 712 if (j < 19) {
|
|---|
| public+hg@61 | 713 if (sndres[i]) ttime = (int)(sndres[i]->alen / .1764);
|
|---|
| public+hg@61 | 714 } else if (j == 20) {
|
|---|
| public+hg@73 | 715 tmp = (channel[j][pcur[j]].type ? bpmtab[i] : i);
|
|---|
| public+hg@61 | 716 if (tmp > 0) {
|
|---|
| public+hg@30 | 717 xbpm = tmp;
|
|---|
| public+hg@61 | 718 } else if (tmp < 0) {
|
|---|
| public+hg@30 | 719 time += (int)(adjust_object_position(-1, pos) * 24e7 / xbpm);
|
|---|
| public+hg@30 | 720 break;
|
|---|
| public+hg@30 | 721 }
|
|---|
| public+hg@61 | 722 } else if (j == 21) {
|
|---|
| public+hg@73 | 723 if (channel[j][pcur[j]].type) {
|
|---|
| public+hg@61 | 724 time += i;
|
|---|
| public+hg@61 | 725 } else {
|
|---|
| public+hg@61 | 726 time += (int)(stoptab[i] * 125e4 * shorten[(int)(pos+1)-1] / xbpm);
|
|---|
| public+hg@61 | 727 }
|
|---|
| public+hg@30 | 728 }
|
|---|
| public+hg@61 | 729 if (rtime < time + ttime) rtime = time + ttime;
|
|---|
| public+hg@73 | 730 pos = channel[j][pcur[j]].time;
|
|---|
| public+hg@61 | 731 ++pcur[j];
|
|---|
| public+hg@30 | 732 }
|
|---|
| public+hg@30 | 733 return (time > rtime ? time : rtime) / 1000;
|
|---|
| public+hg@11 | 734 }
|
|---|
| public+hg@11 | 735
|
|---|
| public+hg@61 | 736 static void clone_bms(void)
|
|---|
| public+hg@61 | 737 {
|
|---|
| public+hg@80 | 738 int i;
|
|---|
| public+hg@26 | 739
|
|---|
| public+hg@61 | 740 for (i = 0; i < 9; ++i) {
|
|---|
| public+hg@77 | 741 free(channel[i+9]);
|
|---|
| public+hg@26 | 742 nchannel[i+9] = nchannel[i];
|
|---|
| public+hg@73 | 743 channel[i+9] = malloc(sizeof(bmsnote) * nchannel[i]);
|
|---|
| public+hg@80 | 744 memcpy(channel[i+9], channel[i], sizeof(bmsnote) * nchannel[i]);
|
|---|
| public+hg@26 | 745 }
|
|---|
| public+hg@26 | 746 }
|
|---|
| public+hg@26 | 747
|
|---|
| public+hg@61 | 748 static void shuffle_bms(int mode, int player)
|
|---|
| public+hg@61 | 749 {
|
|---|
| public+hg@73 | 750 bmsnote *tempchan, *result[18] = {0};
|
|---|
| public+hg@73 | 751 int nresult[18] = {0};
|
|---|
| public+hg@26 | 752 int map[18], perm[18], nmap;
|
|---|
| public+hg@73 | 753 int ptr[18] = {0,}, thru[18] = {0}, target[18];
|
|---|
| public+hg@26 | 754 int thrumap[18], thrurmap[18];
|
|---|
| public+hg@73 | 755 int i, j, flag = 1, temp;
|
|---|
| public+hg@26 | 756 double t;
|
|---|
| public+hg@26 | 757
|
|---|
| public+hg@26 | 758 srand(time(0));
|
|---|
| public+hg@61 | 759 for (i = 0; i < 18; ++i) map[i] = perm[i] = i;
|
|---|
| public+hg@61 | 760 if (!nchannel[7] && !nchannel[8] && !nchannel[16] && !nchannel[17]) {
|
|---|
| public+hg@26 | 761 map[7] = map[8] = map[16] = map[17] = -1;
|
|---|
| public+hg@61 | 762 }
|
|---|
| public+hg@61 | 763 if (!nchannel[6] && !nchannel[15]) {
|
|---|
| public+hg@26 | 764 map[6] = map[15] = -1;
|
|---|
| public+hg@61 | 765 }
|
|---|
| public+hg@61 | 766 if (mode != 3 && mode != 5) {
|
|---|
| public+hg@26 | 767 map[5] = map[6] = map[14] = map[15] = -1;
|
|---|
| public+hg@26 | 768 }
|
|---|
| public+hg@61 | 769 if (player) {
|
|---|
| public+hg@61 | 770 for (i = 0; i < 9; ++i) map[player==1 ? i+9 : i] = -1;
|
|---|
| public+hg@61 | 771 }
|
|---|
| public+hg@61 | 772 for (i = j = 0; i < 18; ++i) {
|
|---|
| public+hg@61 | 773 if (map[i] < 0) {
|
|---|
| public+hg@61 | 774 ++j;
|
|---|
| public+hg@61 | 775 } else {
|
|---|
| public+hg@61 | 776 map[i-j] = map[i];
|
|---|
| public+hg@61 | 777 }
|
|---|
| public+hg@61 | 778 }
|
|---|
| public+hg@26 | 779 nmap = 18 - j;
|
|---|
| public+hg@26 | 780
|
|---|
| public+hg@61 | 781 if (mode < 2) { /* mirror */
|
|---|
| public+hg@61 | 782 for (i = 0, j = nmap-1; i < j; ++i, --j) {
|
|---|
| public+hg@26 | 783 SWAP(channel[map[i]], channel[map[j]], tempchan);
|
|---|
| public+hg@26 | 784 SWAP(nchannel[map[i]], nchannel[map[j]], temp);
|
|---|
| public+hg@26 | 785 }
|
|---|
| public+hg@61 | 786 } else if (mode < 4) { /* shuffle */
|
|---|
| public+hg@61 | 787 for (i = nmap-1; i > 0; --i) {
|
|---|
| public+hg@26 | 788 j = rand() % i;
|
|---|
| public+hg@26 | 789 SWAP(channel[map[i]], channel[map[j]], tempchan);
|
|---|
| public+hg@26 | 790 SWAP(nchannel[map[i]], nchannel[map[j]], temp);
|
|---|
| public+hg@26 | 791 }
|
|---|
| public+hg@61 | 792 } else if (mode < 6) { /* random */
|
|---|
| public+hg@61 | 793 while (flag) {
|
|---|
| public+hg@61 | 794 for (i = nmap-1; i > 0; --i) {
|
|---|
| public+hg@26 | 795 j = rand() % i;
|
|---|
| public+hg@26 | 796 SWAP(perm[i], perm[j], temp);
|
|---|
| public+hg@26 | 797 }
|
|---|
| public+hg@26 | 798 t = 1e4;
|
|---|
| public+hg@26 | 799 flag = 0;
|
|---|
| public+hg@61 | 800 for (i = 0; i < nmap; ++i) {
|
|---|
| public+hg@61 | 801 if (ptr[map[i]] < nchannel[map[i]]) {
|
|---|
| public+hg@61 | 802 flag = 1;
|
|---|
| public+hg@61 | 803 target[i] = 1;
|
|---|
| public+hg@73 | 804 if (t > channel[map[i]][ptr[map[i]]].time)
|
|---|
| public+hg@73 | 805 t = channel[map[i]][ptr[map[i]]].time - 1e-4;
|
|---|
| public+hg@26 | 806 } else {
|
|---|
| public+hg@26 | 807 target[i] = 0;
|
|---|
| public+hg@26 | 808 }
|
|---|
| public+hg@26 | 809 }
|
|---|
| public+hg@26 | 810 t += 2e-4;
|
|---|
| public+hg@61 | 811 for (i = 0; i < nmap; ++i) {
|
|---|
| public+hg@73 | 812 if (target[i] && channel[map[i]][ptr[map[i]]].time > t)
|
|---|
| public+hg@26 | 813 target[i] = 0;
|
|---|
| public+hg@26 | 814 }
|
|---|
| public+hg@61 | 815 for (i = 0; i < nmap; ++i) {
|
|---|
| public+hg@61 | 816 if (!target[i]) continue;
|
|---|
| public+hg@73 | 817 temp = channel[map[i]][ptr[map[i]]].type;
|
|---|
| public+hg@80 | 818 if (temp == 0/*LNDONE*/) {
|
|---|
| public+hg@26 | 819 j = thrumap[i];
|
|---|
| public+hg@26 | 820 thru[j] = 2;
|
|---|
| public+hg@26 | 821 } else {
|
|---|
| public+hg@26 | 822 j = perm[i];
|
|---|
| public+hg@61 | 823 while (thru[j]) j = perm[thrurmap[j]];
|
|---|
| public+hg@80 | 824 if (temp == 1/*LNSTART*/) {
|
|---|
| public+hg@26 | 825 thrumap[i] = j;
|
|---|
| public+hg@26 | 826 thrurmap[j] = i;
|
|---|
| public+hg@26 | 827 thru[j] = 1;
|
|---|
| public+hg@26 | 828 }
|
|---|
| public+hg@26 | 829 }
|
|---|
| public+hg@73 | 830 result[j] = realloc(result[j], sizeof(bmsnote) * (nresult[j]+1));
|
|---|
| public+hg@26 | 831 result[j][nresult[j]++] = channel[map[i]][ptr[map[i]]++];
|
|---|
| public+hg@26 | 832 }
|
|---|
| public+hg@61 | 833 for(i = 0; i < nmap; ++i) {
|
|---|
| public+hg@61 | 834 if (thru[i] == 2) thru[i] = 0;
|
|---|
| public+hg@61 | 835 }
|
|---|
| public+hg@26 | 836 }
|
|---|
| public+hg@61 | 837 for (i = 0; i < nmap; ++i) {
|
|---|
| public+hg@26 | 838 free(channel[map[i]]);
|
|---|
| public+hg@26 | 839 channel[map[i]] = result[i];
|
|---|
| public+hg@26 | 840 nchannel[map[i]] = nresult[i];
|
|---|
| public+hg@26 | 841 }
|
|---|
| public+hg@26 | 842 }
|
|---|
| public+hg@26 | 843 }
|
|---|
| public+hg@26 | 844
|
|---|
| public+hg@5 | 845 /******************************************************************************/
|
|---|
| public+hg@20 | 846 /* general graphic functions */
|
|---|
| public+hg@5 | 847
|
|---|
| public+hg@61 | 848 static SDL_Surface *screen;
|
|---|
| public+hg@61 | 849 static SDL_Event event;
|
|---|
| public+hg@61 | 850 static SDL_Rect rect[2];
|
|---|
| public+hg@61 | 851 static int _rect=0;
|
|---|
| public+hg@14 | 852
|
|---|
| public+hg@61 | 853 static int getpixel(SDL_Surface *s, int x, int y)
|
|---|
| public+hg@61 | 854 {
|
|---|
| public+hg@83 | 855 Uint8 r, g, b;
|
|---|
| public+hg@83 | 856 SDL_GetRGB(((Uint32*)s->pixels)[x+y*s->pitch/4], s->format, &r, &g, &b);
|
|---|
| public+hg@83 | 857 return (int)(r << 16) | ((int)g << 8) | (int)b;
|
|---|
| public+hg@83 | 858 }
|
|---|
| public+hg@83 | 859
|
|---|
| public+hg@83 | 860 static Uint32 map(int c)
|
|---|
| public+hg@83 | 861 {
|
|---|
| public+hg@83 | 862 return SDL_MapRGB(screen->format, c >> 16, (c >> 8) & 255, c & 255);
|
|---|
| public+hg@61 | 863 }
|
|---|
| public+hg@14 | 864
|
|---|
| public+hg@61 | 865 static int putpixel(SDL_Surface *s, int x, int y, int c)
|
|---|
| public+hg@61 | 866 {
|
|---|
| public+hg@83 | 867 c = SDL_MapRGB(s->format, c >> 16, (c >> 8) & 255, c & 255);
|
|---|
| public+hg@61 | 868 return ((Uint32*)s->pixels)[x+y*s->pitch/4] = c;
|
|---|
| public+hg@61 | 869 }
|
|---|
| public+hg@61 | 870
|
|---|
| public+hg@61 | 871 static int blend(int x, int y, int a, int b)
|
|---|
| public+hg@61 | 872 {
|
|---|
| public+hg@61 | 873 int i = 0;
|
|---|
| public+hg@61 | 874 for (; i < 24; i += 8)
|
|---|
| public+hg@61 | 875 y += ((x>>i&255) - (y>>i&255))*a/b << i;
|
|---|
| public+hg@61 | 876 return y;
|
|---|
| public+hg@61 | 877 }
|
|---|
| public+hg@61 | 878
|
|---|
| public+hg@61 | 879 static void putblendedpixel(SDL_Surface *s, int x, int y, int c, int o)
|
|---|
| public+hg@61 | 880 {
|
|---|
| public+hg@61 | 881 putpixel(s, x, y, blend(getpixel(s,x,y), c, o, 255));
|
|---|
| public+hg@61 | 882 }
|
|---|
| public+hg@61 | 883
|
|---|
| public+hg@61 | 884 static SDL_Surface *newsurface(int f, int w, int h)
|
|---|
| public+hg@61 | 885 {
|
|---|
| public+hg@61 | 886 return SDL_CreateRGBSurface(f, w, h, 32, 0xff0000, 0xff00, 0xff, 0);
|
|---|
| public+hg@61 | 887 }
|
|---|
| public+hg@61 | 888
|
|---|
| public+hg@61 | 889 static SDL_Rect *newrect(int x, int y, int w, int h)
|
|---|
| public+hg@61 | 890 {
|
|---|
| public+hg@61 | 891 SDL_Rect *r = rect+_rect++%2;
|
|---|
| public+hg@61 | 892 r->x = x;
|
|---|
| public+hg@61 | 893 r->y = y;
|
|---|
| public+hg@61 | 894 r->w = w;
|
|---|
| public+hg@61 | 895 r->h = h;
|
|---|
| public+hg@61 | 896 return r;
|
|---|
| public+hg@61 | 897 }
|
|---|
| public+hg@61 | 898
|
|---|
| public+hg@61 | 899 static int bicubic_kernel(int x, int y) {
|
|---|
| public+hg@61 | 900 if (x < 0) x = -x;
|
|---|
| public+hg@61 | 901 if (x < y) {
|
|---|
| public+hg@14 | 902 return ((y*y - 2*x*x + x*x/y*x) << 11) / y / y;
|
|---|
| public+hg@61 | 903 } else if (x < y * 2) {
|
|---|
| public+hg@14 | 904 return ((4*y*y - 8*x*y + 5*x*x - x*x/y*x) << 11) / y / y;
|
|---|
| public+hg@14 | 905 } else {
|
|---|
| public+hg@14 | 906 return 0;
|
|---|
| public+hg@14 | 907 }
|
|---|
| public+hg@14 | 908 }
|
|---|
| public+hg@14 | 909
|
|---|
| public+hg@61 | 910 static int bicubic_interpolation(SDL_Surface *src, SDL_Surface *dest) {
|
|---|
| public+hg@14 | 911 int x, dx, y, dy, ww, hh, w, h;
|
|---|
| public+hg@30 | 912 int i, j, k, r, g, b, c, xx, yy, a[4][2], d;
|
|---|
| public+hg@14 | 913
|
|---|
| public+hg@14 | 914 dx = x = 0;
|
|---|
| public+hg@61 | 915 ww = src->w - 1;
|
|---|
| public+hg@61 | 916 hh = src->h - 1;
|
|---|
| public+hg@61 | 917 w = dest->w - 1;
|
|---|
| public+hg@61 | 918 h = dest->h - 1;
|
|---|
| public+hg@61 | 919 for (i = 0; i <= w; ++i) {
|
|---|
| public+hg@14 | 920 dy = y = 0;
|
|---|
| public+hg@61 | 921 for (j = 0; j <= h; ++j) {
|
|---|
| public+hg@14 | 922 r = g = b = 0;
|
|---|
| public+hg@61 | 923 for (k = 0; k < 4; ++k) {
|
|---|
| public+hg@61 | 924 a[k][0] = bicubic_kernel((x+k-1)*w - i*ww, w);
|
|---|
| public+hg@61 | 925 a[k][1] = bicubic_kernel((y+k-1)*h - j*hh, h);
|
|---|
| public+hg@30 | 926 }
|
|---|
| public+hg@61 | 927 for (k = 0; k < 16; ++k) {
|
|---|
| public+hg@61 | 928 xx = x + k/4 - 1;
|
|---|
| public+hg@61 | 929 yy = y + k%4 - 1;
|
|---|
| public+hg@61 | 930 if (xx>=0 && xx<=ww && yy>=0 && yy<=hh) {
|
|---|
| public+hg@61 | 931 c = getpixel(src, xx, yy);
|
|---|
| public+hg@61 | 932 d = a[k/4][0] * a[k%4][1] >> 6;
|
|---|
| public+hg@83 | 933 r += (c>>16) * d;
|
|---|
| public+hg@61 | 934 g += (c>>8&255) * d;
|
|---|
| public+hg@83 | 935 b += (c&255) * d;
|
|---|
| public+hg@30 | 936 }
|
|---|
| public+hg@14 | 937 }
|
|---|
| public+hg@14 | 938 r = (r<0 ? 0 : r>>24 ? 255 : r>>16);
|
|---|
| public+hg@14 | 939 g = (g<0 ? 0 : g>>24 ? 255 : g>>16);
|
|---|
| public+hg@14 | 940 b = (b<0 ? 0 : b>>24 ? 255 : b>>16);
|
|---|
| public+hg@83 | 941 putpixel(dest, i, j, (r<<16) | (g<<8) | b);
|
|---|
| public+hg@61 | 942
|
|---|
| public+hg@61 | 943 dy += hh;
|
|---|
| public+hg@61 | 944 if (dy > h) {
|
|---|
| public+hg@61 | 945 ++y;
|
|---|
| public+hg@61 | 946 dy -= h;
|
|---|
| public+hg@61 | 947 }
|
|---|
| public+hg@14 | 948 }
|
|---|
| public+hg@61 | 949 dx += ww;
|
|---|
| public+hg@61 | 950 if (dx > w) {
|
|---|
| public+hg@61 | 951 ++x;
|
|---|
| public+hg@61 | 952 dx -= w;
|
|---|
| public+hg@61 | 953 }
|
|---|
| public+hg@14 | 954 }
|
|---|
| public+hg@14 | 955
|
|---|
| public+hg@14 | 956 return 0;
|
|---|
| public+hg@14 | 957 }
|
|---|
| public+hg@14 | 958
|
|---|
| public+hg@14 | 959 /******************************************************************************/
|
|---|
| public+hg@20 | 960 /* font functions */
|
|---|
| public+hg@5 | 961
|
|---|
| public+hg@82 | 962 static int fontdatawords[] = {0, 0, 2, 6, 2, 5, 32, 96, 97, 15, 497, 15,
|
|---|
| public+hg@82 | 963 1521, 15, 1537, 16, 48, 176, 1, 3, 1, 3, 7, 1, 4080, 4096, 3, 1, 8,
|
|---|
| public+hg@82 | 964 3, 4097, 4080, 16, 16128, 240, 1, 2, 9, 3, 8177, 15, 16385, 240, 15,
|
|---|
| public+hg@82 | 965 1, 47, 721, 143, 2673, 2, 6, 7, 1, 31, 17, 16, 63, 64, 33, 0, 1, 2,
|
|---|
| public+hg@82 | 966 1, 8, 3};
|
|---|
| public+hg@82 | 967 static const char *fontdataindices =
|
|---|
| public+hg@82 | 968 "!!7a/&w7a!!g'M*Qg(O&J!!&Je!!g2Qg-B!!u2cQ[b7b2[[Q7b2[bQ!c!i&d>UT2c&"
|
|---|
| public+hg@82 | 969 "b>WT!b2eGW&!c!i2MbUbD!.8(M$UQCb-b!!l'U*2eTXb2Gb5b>9ZW!!k*e8(J$b!!u"
|
|---|
| public+hg@82 | 970 "*8(M$Q!h#b'O*?!!k#Q'O*?b!h8(M$Q!!m&JTLcG_&J>]TLc&J!!o&Je7[&Je!!{&J"
|
|---|
| public+hg@82 | 971 "dM$Q!!s7[!!}e&Je!!m0b3b.8(M$U!Cb-b!o>UQ2Ub]ba9Y[SbQCb2GW!!k*MbQbBb"
|
|---|
| public+hg@82 | 972 "!kaQ!!k>UQ2Ub]bG8.M(U$[!Ca[!!k>UQ2d!IJQ!d2cGW!!k78bM6U2Cb2ea[2!c!l"
|
|---|
| public+hg@82 | 973 "a[!2e>[Q!d2cGW!!k>UQ2c!b>[Q2gGW!!ka[Q!UbDb.8(J&h!!k>UQ2eIXQ2gGW!!k"
|
|---|
| public+hg@82 | 974 ">UQ2gaWQ!b2cGW!!m&Je!!e&Je!!m&Je!!e&JdM$Q!!k3b.8(M$U!H#W'O,?4!!t7["
|
|---|
| public+hg@82 | 975 "!!c7[!!r:#W'O,?5!.8(M$U!Cb!k>UQ2cUbD!.8(J!!&Jc!!k>UJ)LKKhGb!)7W!!k"
|
|---|
| public+hg@82 | 976 "'8,M=UWCQ2ca[Q2e!!k>[Q2eI[Q2gG[!!k>MSUQC!2gQ:RWGO!!k,[<2WbQhUbDb.["
|
|---|
| public+hg@82 | 977 "!!ka[!2e7[!2ga[!!ka[!2e7[!2j!k>MSUQC!2c[bWbQ:RWGO!!kQ2ga[Q2i!!k7[&"
|
|---|
| public+hg@82 | 978 "Jo7[!!kQm2eGW!!kU2Db.9([$b#b'b,@<2Wb!!l2qa[!!kU:^[adT2cQh!!kQ2d:R["
|
|---|
| public+hg@82 | 979 "Vba@_2WbQd!!k,M=UWCQ2gU:EW.O!!k>[Q2gG[!2h!k>UQ2iVbabIW_!Wb!j>[Q2gI"
|
|---|
| public+hg@82 | 980 "[Q2g!!k>UQ2c!b>WQ!d2cGW!!k7[&Jq!!kQ2qGW!!kQ2kU:EW.O(?!!kQ2gTfa[CW2"
|
|---|
| public+hg@82 | 981 "Q!!kM+U:^[GW.O,M>U`[WCO-!!kM'U,D<.W(O&Ji!!ka[Q!Ub]bG8.M(U$[!Ca[!!k"
|
|---|
| public+hg@82 | 982 "*Q!p*b!!n+b:#W'O,?4!1b!p*Qb!pQ!!g'8,M=UWCO-!!}oa[!!i#Q'O,?4!!}b>QQ"
|
|---|
| public+hg@82 | 983 "!caUQ2eaW!!l2e>[Q2iG[!!o>UQ2c!dQdGW!!kQfaUQ2iaW!!o>UQ2ea[!2UbGW!!k"
|
|---|
| public+hg@82 | 984 ">8TJc&b7[&Ji!!oaUQ2gaWQ!b2cGW!!f2e>[Q2m!!k&Jc!!&Jm!!kQd!dQi2eGW!!h"
|
|---|
| public+hg@82 | 985 "2cUbDb.9(['b,@<2Wb!!k*Jb?b!o!p;[abT2gQd!!o>[Q2m!!o>UQ2kGW!!o>[Q2kG"
|
|---|
| public+hg@82 | 986 "[!2f!iaUQ2kaWQ!e!j>[Q2c!k!o>UW2!b>WQ!d:GW!!k&Jc7[&JeTfG?!!oQ2mGW!!"
|
|---|
| public+hg@82 | 987 "oQ2gU:EW.O(?!!oQ2eTfa[FW!!oM+U:EW.O,M=UWCO-!!oQ2f:RWGO.A(M$U!Cb!ka"
|
|---|
| public+hg@82 | 988 "[]!G8.M(U$[!Ca[!!i78&Jg%[&Jg7?!!e&J}c!!c#[&Jg7A&Jg$[!!k#]NaaPG?!!}"
|
|---|
| public+hg@82 | 989 "o7[.W(O";
|
|---|
| public+hg@7 | 990
|
|---|
| public+hg@82 | 991 static Uint16 fontdata[3072];
|
|---|
| public+hg@66 | 992 static Uint8 (*zoomfont[16])[96] = {NULL};
|
|---|
| public+hg@61 | 993
|
|---|
| public+hg@82 | 994 static void fontdecompress(void)
|
|---|
| public+hg@82 | 995 {
|
|---|
| public+hg@82 | 996 int i, ch;
|
|---|
| public+hg@82 | 997
|
|---|
| public+hg@82 | 998 for (i = ch = 0; i < ARRAYSIZE(fontdatawords); ++i) {
|
|---|
| public+hg@82 | 999 ch += fontdatawords[i];
|
|---|
| public+hg@82 | 1000 fontdatawords[i] = ch;
|
|---|
| public+hg@82 | 1001 }
|
|---|
| public+hg@82 | 1002 for (i = 0; ch = *fontdataindices++; ) {
|
|---|
| public+hg@82 | 1003 if (ch > 97) {
|
|---|
| public+hg@82 | 1004 while (ch-- > 97) fontdata[i] = fontdata[i-2], ++i;
|
|---|
| public+hg@82 | 1005 } else if (ch > 32) {
|
|---|
| public+hg@82 | 1006 fontdata[i++] = fontdatawords[ch - 33];
|
|---|
| public+hg@82 | 1007 }
|
|---|
| public+hg@82 | 1008 }
|
|---|
| public+hg@82 | 1009 }
|
|---|
| public+hg@82 | 1010
|
|---|
| public+hg@61 | 1011 static int _fontprocess(int x, int y, int z, int c, int s)
|
|---|
| public+hg@61 | 1012 {
|
|---|
| public+hg@9 | 1013 int i, j;
|
|---|
| public+hg@61 | 1014 for (i = 0; i < z; ++i) {
|
|---|
| public+hg@61 | 1015 for (j = (s==1 ? z-i : s==3 ? i+1 : 0); j < (s==2 ? i : s==4 ? z-i-1 : z); ++j)
|
|---|
| public+hg@66 | 1016 zoomfont[z][(y*z+i)*z+j][c] |= 1<<(7-x);
|
|---|
| public+hg@61 | 1017 }
|
|---|
| public+hg@9 | 1018 return z;
|
|---|
| public+hg@7 | 1019 }
|
|---|
| public+hg@7 | 1020
|
|---|
| public+hg@61 | 1021 static void fontprocess(int z)
|
|---|
| public+hg@61 | 1022 {
|
|---|
| public+hg@82 | 1023 int i, j, k, l, v;
|
|---|
| public+hg@66 | 1024
|
|---|
| public+hg@66 | 1025 zoomfont[z] = calloc(16*z*z, 96);
|
|---|
| public+hg@82 | 1026 for (i = l = 0; i < 96; ++i) {
|
|---|
| public+hg@82 | 1027 for (j = 0; j < 16; ++j, l+=2) {
|
|---|
| public+hg@82 | 1028 v = fontdata[l] << 16 | fontdata[l+1];
|
|---|
| public+hg@66 | 1029 for (k = 0; k < 8; ++k, v >>= 4) {
|
|---|
| public+hg@66 | 1030 if ((v & 15) == 15) _fontprocess(k, j, z, i, 0); /* XXX? */
|
|---|
| public+hg@66 | 1031 if (v & 1) _fontprocess(k, j, z, i, 1); /* /| */
|
|---|
| public+hg@66 | 1032 if (v & 2) _fontprocess(k, j, z, i, 2); /* |\ */
|
|---|
| public+hg@66 | 1033 if (v & 4) _fontprocess(k, j, z, i, 3); /* \| */
|
|---|
| public+hg@66 | 1034 if (v & 8) _fontprocess(k, j, z, i, 4); /* |/ */
|
|---|
| public+hg@61 | 1035 }
|
|---|
| public+hg@9 | 1036 }
|
|---|
| public+hg@9 | 1037 }
|
|---|
| public+hg@9 | 1038 }
|
|---|
| public+hg@9 | 1039
|
|---|
| public+hg@61 | 1040 static int printchar(SDL_Surface *s, int x, int y, int z, int c, int u, int v)
|
|---|
| public+hg@61 | 1041 {
|
|---|
| public+hg@8 | 1042 int i, j;
|
|---|
| public+hg@82 | 1043
|
|---|
| public+hg@66 | 1044 if (c != ' ' && c != '\t' && c != '\n' && c != '\r') {
|
|---|
| public+hg@30 | 1045 c -= (c<0 ? -96 : c<33 || c>126 ? c : 32);
|
|---|
| public+hg@61 | 1046 for (i = 0; i < 16*z; ++i) {
|
|---|
| public+hg@61 | 1047 for (j = 0; j < 8*z; ++j) {
|
|---|
| public+hg@66 | 1048 if (zoomfont[z][i*z+j%z][c] & (1<<(7-j/z)))
|
|---|
| public+hg@17 | 1049 putpixel(s, x+j, y+i, blend(u, v, i, 16*z-1));
|
|---|
| public+hg@61 | 1050 }
|
|---|
| public+hg@61 | 1051 }
|
|---|
| public+hg@16 | 1052 }
|
|---|
| public+hg@82 | 1053
|
|---|
| public+hg@16 | 1054 return 8*z;
|
|---|
| public+hg@7 | 1055 }
|
|---|
| public+hg@7 | 1056
|
|---|
| public+hg@61 | 1057 static void printstr(SDL_Surface *s, int x, int y, int z, const char *c, int u, int v)
|
|---|
| public+hg@61 | 1058 {
|
|---|
| public+hg@82 | 1059 while (*c) {
|
|---|
| public+hg@61 | 1060 x += printchar(s, x, y, z, (Uint8)*c++, u, v);
|
|---|
| public+hg@82 | 1061 }
|
|---|
| public+hg@61 | 1062 }
|
|---|
| public+hg@8 | 1063
|
|---|
| public+hg@13 | 1064 /******************************************************************************/
|
|---|
| public+hg@20 | 1065 /* main routines */
|
|---|
| public+hg@13 | 1066
|
|---|
| public+hg@61 | 1067 static double playspeed = 1, targetspeed;
|
|---|
| public+hg@69 | 1068 static int now, origintime, starttime, stoptime = 0, adjustspeed = 0;
|
|---|
| public+hg@75 | 1069 static double startoffset = -1, startshorten = 1;
|
|---|
| public+hg@61 | 1070 static int xflag, xnnotes, xscore, xduration;
|
|---|
| public+hg@61 | 1071 static int pcur[22] = {0}, pfront[22] = {0}, prear[22] = {0}, pcheck[18] = {0}, thru[22] = {0};
|
|---|
| public+hg@61 | 1072 static int bga[3] = {-1,-1,0}, poorbga = 0, bga_updated = 1;
|
|---|
| public+hg@61 | 1073 static int score = 0, scocnt[5] = {0}, scombo = 0, smaxcombo = 0;
|
|---|
| public+hg@61 | 1074 static double gradefactor;
|
|---|
| public+hg@85 | 1075 static int gradetime = 0, grademode, gauge = 256, survival = 150;
|
|---|
| public+hg@19 | 1076
|
|---|
| public+hg@61 | 1077 static SDL_Surface *sprite=0;
|
|---|
| public+hg@85 | 1078 static int keymap[SDLK_LAST]; /* -1: none, 0..17: notes, 18..19: speed down/up */
|
|---|
| public+hg@61 | 1079 static int keypressed[18] = {0};
|
|---|
| public+hg@61 | 1080 static int tkeyleft[18] = {41,67,93,119,145,0,223,171,197, 578,604,630,656,682,760,537,708,734};
|
|---|
| public+hg@61 | 1081 static int tkeywidth[18] = {25,25,25,25,25,40,40,25,25, 25,25,25,25,25,40,40,25,25};
|
|---|
| public+hg@61 | 1082 static int tpanel1 = 264, tpanel2 = 536, tbga = 272;
|
|---|
| public+hg@16 | 1083 #define WHITE 0x808080
|
|---|
| public+hg@16 | 1084 #define BLUE 0x8080ff
|
|---|
| public+hg@61 | 1085 static int tkeycolor[18] = {
|
|---|
| public+hg@61 | 1086 WHITE, BLUE, WHITE, BLUE, WHITE, 0xff8080, 0x80ff80, BLUE, WHITE,
|
|---|
| public+hg@61 | 1087 WHITE, BLUE, WHITE, BLUE, WHITE, 0xff8080, 0x80ff80, BLUE, WHITE};
|
|---|
| public+hg@16 | 1088 #undef WHITE
|
|---|
| public+hg@16 | 1089 #undef BLUE
|
|---|
| public+hg@61 | 1090 static char *tgradestr[5] = {"MISS", "BAD", "GOOD", "GREAT", "COOL"};
|
|---|
| public+hg@61 | 1091 static int tgradecolor[5][2] = {
|
|---|
| public+hg@30 | 1092 {0xff4040, 0xffc0c0}, {0xff40ff, 0xffc0ff}, {0xffff40, 0xffffc0},
|
|---|
| public+hg@30 | 1093 {0x40ff40, 0xc0ffc0}, {0x4040ff, 0xc0c0ff}};
|
|---|
| public+hg@16 | 1094
|
|---|
| public+hg@85 | 1095 static Mix_Chunk *beep;
|
|---|
| public+hg@85 | 1096
|
|---|
| public+hg@85 | 1097 static void check_exit(void)
|
|---|
| public+hg@61 | 1098 {
|
|---|
| public+hg@61 | 1099 while (SDL_PollEvent(&event)) {
|
|---|
| public+hg@85 | 1100 if (event.type == SDL_QUIT || (event.type == SDL_KEYUP && event.key.keysym.sym == SDLK_ESCAPE)) exit(0);
|
|---|
| public+hg@14 | 1101 }
|
|---|
| public+hg@14 | 1102 }
|
|---|
| public+hg@14 | 1103
|
|---|
| public+hg@79 | 1104 static SDLKey get_sdlkey_from_name(const char *str)
|
|---|
| public+hg@79 | 1105 {
|
|---|
| public+hg@79 | 1106 SDLKey i;
|
|---|
| public+hg@79 | 1107
|
|---|
| public+hg@79 | 1108 /* XXX maybe won't work in SDL 1.3 */
|
|---|
| public+hg@79 | 1109 for (i = SDLK_FIRST; i < SDLK_LAST; ++i) {
|
|---|
| public+hg@79 | 1110 if (stricmp(SDL_GetKeyName(i), str)) return i;
|
|---|
| public+hg@79 | 1111 }
|
|---|
| public+hg@79 | 1112 return SDLK_UNKNOWN;
|
|---|
| public+hg@79 | 1113 }
|
|---|
| public+hg@79 | 1114
|
|---|
| public+hg@85 | 1115 static void read_keymap(void)
|
|---|
| public+hg@79 | 1116 {
|
|---|
| public+hg@85 | 1117 static const struct { const char *name, *def; int base, limit; } envvars[] = {
|
|---|
| public+hg@85 | 1118 {"ANGOLMOIS_1P_KEYS", "z|s|x|d|c|left shift|left alt|f|v", 0, 9},
|
|---|
| public+hg@85 | 1119 {"ANGOLMOIS_2P_KEYS", "m|k|,|l|.|right shift|right alt|;|/", 9, 18},
|
|---|
| public+hg@85 | 1120 {"ANGOLMOIS_SPEED_KEYS", "f3|f4", 18, 20},
|
|---|
| public+hg@79 | 1121 };
|
|---|
| public+hg@85 | 1122 char *s, buf[256] = "";
|
|---|
| public+hg@85 | 1123 int i, j, k, sep;
|
|---|
| public+hg@79 | 1124 SDLKey key;
|
|---|
| public+hg@79 | 1125
|
|---|
| public+hg@85 | 1126 for (i = 0; i < SDLK_LAST; ++i) keymap[i] = -1;
|
|---|
| public+hg@85 | 1127 for (i = 0; i < 3; ++i) {
|
|---|
| public+hg@85 | 1128 s = getenv(envvars[i].name);
|
|---|
| public+hg@85 | 1129 strncpy(buf, s ? s : envvars[i].def, sizeof(buf) - 1);
|
|---|
| public+hg@85 | 1130 s = buf;
|
|---|
| public+hg@85 | 1131 sep = 1;
|
|---|
| public+hg@85 | 1132 for (j = envvars[i].base; sep && j < envvars[i].limit; ) {
|
|---|
| public+hg@85 | 1133 k = strcspn(s, "%|"); /* both character is not used as a key name in SDL 1.2 */
|
|---|
| public+hg@85 | 1134 sep = s[k];
|
|---|
| public+hg@85 | 1135 s[k++] = '\0';
|
|---|
| public+hg@85 | 1136 key = get_sdlkey_from_name(s);
|
|---|
| public+hg@85 | 1137 if (key == SDLK_UNKNOWN) {
|
|---|
| public+hg@85 | 1138 die("Unknown key name in the environment variable %s: %s", envvars[i].name, s);
|
|---|
| public+hg@85 | 1139 }
|
|---|
| public+hg@85 | 1140 keymap[key] = j;
|
|---|
| public+hg@85 | 1141 if (sep != '%') ++j;
|
|---|
| public+hg@85 | 1142 s += k;
|
|---|
| public+hg@85 | 1143 }
|
|---|
| public+hg@85 | 1144 }
|
|---|
| public+hg@85 | 1145
|
|---|
| public+hg@85 | 1146 }
|
|---|
| public+hg@79 | 1147
|
|---|
| public+hg@85 | 1148 static void create_beep(void)
|
|---|
| public+hg@85 | 1149 {
|
|---|
| public+hg@85 | 1150 Sint32 samples[12000]; /* approx. 0.14 seconds */
|
|---|
| public+hg@85 | 1151 int i;
|
|---|
| public+hg@85 | 1152
|
|---|
| public+hg@85 | 1153 for (i = 0; i < 12000; ++i) {
|
|---|
| public+hg@85 | 1154 /* sawtooth wave at 3150 Hz, quadratic decay after 0.02 seconds. */
|
|---|
| public+hg@85 | 1155 samples[i] = (i%28-14)*(i<2000 ? 2000 : (12000-i)*(12000-i)/50000);
|
|---|
| public+hg@79 | 1156 }
|
|---|
| public+hg@85 | 1157 beep = Mix_QuickLoad_RAW((Uint8*)samples, sizeof samples);
|
|---|
| public+hg@79 | 1158 }
|
|---|
| public+hg@79 | 1159
|
|---|
| public+hg@61 | 1160 static int initialize(void)
|
|---|
| public+hg@61 | 1161 {
|
|---|
| public+hg@61 | 1162 if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0)
|
|---|
| public+hg@85 | 1163 die("SDL Initialization Failure: %s", SDL_GetError());
|
|---|
| public+hg@13 | 1164 atexit(SDL_Quit);
|
|---|
| public+hg@26 | 1165 screen = SDL_SetVideoMode(800, 600, 32, opt_fullscreen ? SDL_FULLSCREEN : SDL_SWSURFACE|SDL_DOUBLEBUF);
|
|---|
| public+hg@61 | 1166 if (!screen)
|
|---|
| public+hg@85 | 1167 die("SDL Video Initialization Failure: %s", SDL_GetError());
|
|---|
| public+hg@17 | 1168 SDL_ShowCursor(SDL_DISABLE);
|
|---|
| public+hg@83 | 1169 IMG_Init(IMG_INIT_JPG|IMG_INIT_PNG);
|
|---|
| public+hg@83 | 1170 Mix_Init(MIX_INIT_OGG|MIX_INIT_MP3);
|
|---|
| public+hg@83 | 1171 if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048)<0)
|
|---|
| public+hg@85 | 1172 die("SDL Mixer Initialization Failure: %s", Mix_GetError());
|
|---|
| public+hg@60 | 1173 SDL_WM_SetCaption(VERSION, 0);
|
|---|
| public+hg@5 | 1174
|
|---|
| public+hg@82 | 1175 fontdecompress();
|
|---|
| public+hg@66 | 1176 fontprocess(1);
|
|---|
| public+hg@9 | 1177 fontprocess(2);
|
|---|
| public+hg@9 | 1178 fontprocess(3);
|
|---|
| public+hg@85 | 1179 read_keymap(); /* this is unfortunate, but get_sdlkey_from_name depends on SDL_Init. */
|
|---|
| public+hg@85 | 1180 create_beep();
|
|---|
| public+hg@13 | 1181 return 0;
|
|---|
| public+hg@13 | 1182 }
|
|---|
| public+hg@61 | 1183
|
|---|
| public+hg@61 | 1184 static SDL_Surface *stagefile_tmp;
|
|---|
| public+hg@85 | 1185 static int last_flip = -1;
|
|---|
| public+hg@13 | 1186
|
|---|
| public+hg@61 | 1187 static void callback_resource(const char *path) {
|
|---|
| public+hg@85 | 1188 /* try not to refresh the screen within 1/20 seconds */
|
|---|
| public+hg@85 | 1189 int t = SDL_GetTicks();
|
|---|
| public+hg@85 | 1190 if (last_flip >= 0 && (t - last_flip) < 50) return;
|
|---|
| public+hg@85 | 1191
|
|---|
| public+hg@85 | 1192 last_flip = t;
|
|---|
| public+hg@14 | 1193 SDL_BlitSurface(stagefile_tmp, newrect(0,0,800,20), screen, newrect(0,580,800,20));
|
|---|
| public+hg@77 | 1194 printstr(screen, 797-8*strlen(path), 582, 1, path, 0x808080, 0xc0c0c0);
|
|---|
| public+hg@14 | 1195 SDL_Flip(screen);
|
|---|
| public+hg@85 | 1196 check_exit();
|
|---|
| public+hg@10 | 1197 }
|
|---|
| public+hg@10 | 1198
|
|---|
| public+hg@61 | 1199 static void play_show_stagefile(void)
|
|---|
| public+hg@61 | 1200 {
|
|---|
| public+hg@13 | 1201 SDL_Surface *temp, *stagefile;
|
|---|
| public+hg@19 | 1202 char buf[256];
|
|---|
| public+hg@15 | 1203 int i, j, t;
|
|---|
| public+hg@13 | 1204
|
|---|
| public+hg@60 | 1205 sprintf(buf, "%s: %s - %s", VERSION, metadata[2], metadata[0]);
|
|---|
| public+hg@85 | 1206 /*SDL_WM_SetCaption(buf, 0);*/
|
|---|
| public+hg@17 | 1207 printstr(screen, 248, 284, 2, "loading bms file...", 0x202020, 0x808080);
|
|---|
| public+hg@14 | 1208 SDL_Flip(screen);
|
|---|
| public+hg@14 | 1209
|
|---|
| public+hg@14 | 1210 stagefile_tmp = newsurface(SDL_SWSURFACE, 800, 20);
|
|---|
| public+hg@77 | 1211 if (*metadata[3] && (temp = IMG_Load(adjust_path(metadata[3])))) {
|
|---|
| public+hg@13 | 1212 stagefile = SDL_DisplayFormat(temp);
|
|---|
| public+hg@13 | 1213 bicubic_interpolation(stagefile, screen);
|
|---|
| public+hg@13 | 1214 SDL_FreeSurface(temp);
|
|---|
| public+hg@13 | 1215 SDL_FreeSurface(stagefile);
|
|---|
| public+hg@13 | 1216 }
|
|---|
| public+hg@61 | 1217 if (opt_showinfo) {
|
|---|
| public+hg@61 | 1218 for (i = 0; i < 800; ++i) {
|
|---|
| public+hg@61 | 1219 for (j = 0; j < 42; ++j) putblendedpixel(screen, i, j, 0x101010, 64);
|
|---|
| public+hg@61 | 1220 for (j = 580; j < 600; ++j) putblendedpixel(screen, i, j, 0x101010, 64);
|
|---|
| public+hg@17 | 1221 }
|
|---|
| public+hg@17 | 1222 printstr(screen, 6, 4, 2, metadata[0], 0x808080, 0xffffff);
|
|---|
| public+hg@77 | 1223 printstr(screen, 792-8*strlen(metadata[1]), 4, 1, metadata[1], 0x808080, 0xffffff);
|
|---|
| public+hg@77 | 1224 printstr(screen, 792-8*strlen(metadata[2]), 20, 1, metadata[2], 0x808080, 0xffffff);
|
|---|
| public+hg@22 | 1225 i = sprintf(buf, "Level %d | BPM %.2f%s | %d note%s [%dKEY%s]",
|
|---|
| public+hg@22 | 1226 v_playlevel, bpm, "?"+((xflag&8)==0), xnnotes,
|
|---|
| public+hg@22 | 1227 "s"+(xnnotes==1), (xflag&1) ? 7 : 5, (xflag&2) ? "-LN" : "");
|
|---|
| public+hg@17 | 1228 printstr(screen, 3, 582, 1, buf, 0x808080, 0xffffff);
|
|---|
| public+hg@17 | 1229 SDL_BlitSurface(screen, newrect(0,580,800,20), stagefile_tmp, newrect(0,0,800,20));
|
|---|
| public+hg@13 | 1230 }
|
|---|
| public+hg@14 | 1231 SDL_Flip(screen);
|
|---|
| public+hg@14 | 1232
|
|---|
| public+hg@15 | 1233 t = SDL_GetTicks() + 3000;
|
|---|
| public+hg@17 | 1234 load_resource(opt_showinfo ? callback_resource : 0);
|
|---|
| public+hg@61 | 1235 if (opt_showinfo) {
|
|---|
| public+hg@85 | 1236 last_flip = -1; /* force update */
|
|---|
| public+hg@17 | 1237 callback_resource("loading...");
|
|---|
| public+hg@17 | 1238 SDL_FreeSurface(stagefile_tmp);
|
|---|
| public+hg@17 | 1239 }
|
|---|
| public+hg@85 | 1240 while ((int)SDL_GetTicks() < t) check_exit();
|
|---|
| public+hg@15 | 1241 }
|
|---|
| public+hg@15 | 1242
|
|---|
| public+hg@61 | 1243 static void play_prepare(void)
|
|---|
| public+hg@61 | 1244 {
|
|---|
| public+hg@22 | 1245 int i, j, c;
|
|---|
| public+hg@61 | 1246
|
|---|
| public+hg@22 | 1247 /* panel position */
|
|---|
| public+hg@61 | 1248 if ((xflag&4) == 0) {
|
|---|
| public+hg@22 | 1249 tkeyleft[6] = tkeyleft[15] = -1;
|
|---|
| public+hg@22 | 1250 tpanel1 -= tkeywidth[6] + 1;
|
|---|
| public+hg@22 | 1251 tpanel2 += tkeywidth[15] + 1;
|
|---|
| public+hg@22 | 1252 }
|
|---|
| public+hg@61 | 1253 if ((xflag&1) == 0) {
|
|---|
| public+hg@22 | 1254 tkeyleft[7] = tkeyleft[8] = tkeyleft[16] = tkeyleft[17] = -1;
|
|---|
| public+hg@61 | 1255 for (i = 9; i < 16; ++i) {
|
|---|
| public+hg@61 | 1256 if (i != 14 && tkeyleft[i] >= 0)
|
|---|
| public+hg@22 | 1257 tkeyleft[i] += tkeywidth[16] + tkeywidth[17] + 2;
|
|---|
| public+hg@61 | 1258 }
|
|---|
| public+hg@61 | 1259 if (tkeyleft[6] > 0)
|
|---|
| public+hg@22 | 1260 tkeyleft[6] -= tkeywidth[7] + tkeywidth[8] + 2;
|
|---|
| public+hg@22 | 1261 tpanel1 -= tkeywidth[7] + tkeywidth[8] + 2;
|
|---|
| public+hg@22 | 1262 tpanel2 += tkeywidth[16] + tkeywidth[17] + 2;
|
|---|
| public+hg@22 | 1263 }
|
|---|
| public+hg@61 | 1264 if (v_player == 1) {
|
|---|
| public+hg@61 | 1265 for (i = 9; i < 18; ++i) tkeyleft[i] = -1;
|
|---|
| public+hg@61 | 1266 } else if (v_player == 3) {
|
|---|
| public+hg@61 | 1267 for (i = 9; i < 18; ++i) tkeyleft[i] += tpanel1 - tpanel2;
|
|---|
| public+hg@22 | 1268 tpanel1 += 801 - tpanel2;
|
|---|
| public+hg@28 | 1269 }
|
|---|
| public+hg@61 | 1270 if (v_player % 2) {
|
|---|
| public+hg@22 | 1271 tpanel2 = 0;
|
|---|
| public+hg@22 | 1272 tbga = tpanel1 / 2 + 282;
|
|---|
| public+hg@22 | 1273 }
|
|---|
| public+hg@61 | 1274
|
|---|
| public+hg@22 | 1275 /* sprite */
|
|---|
| public+hg@22 | 1276 sprite = newsurface(SDL_SWSURFACE, 1200, 600);
|
|---|
| public+hg@61 | 1277 for (i = 0; i < 18; ++i) {
|
|---|
| public+hg@61 | 1278 if (tkeyleft[i] < 0) continue;
|
|---|
| public+hg@61 | 1279 for (j = 140; j < 520; ++j)
|
|---|
| public+hg@17 | 1280 SDL_FillRect(sprite, newrect(tkeyleft[i],j,tkeywidth[i],1), blend(tkeycolor[i], 0, j-140, 1000));
|
|---|
| public+hg@61 | 1281 if (i < 9) {
|
|---|
| public+hg@61 | 1282 for (j = 0; j*2 < tkeywidth[i]; ++j)
|
|---|
| public+hg@28 | 1283 SDL_FillRect(sprite, newrect(800+tkeyleft[i]+j,0,tkeywidth[i]-2*j,600), blend(tkeycolor[i], 0xffffff, tkeywidth[i]-j, tkeywidth[i]));
|
|---|
| public+hg@28 | 1284 }
|
|---|
| public+hg@16 | 1285 }
|
|---|
| public+hg@61 | 1286 for (j = -244; j < 556; ++j) {
|
|---|
| public+hg@61 | 1287 for (i = -10; i < 20; ++i) {
|
|---|
| public+hg@22 | 1288 c = (i*2+j*3+750) % 2000;
|
|---|
| public+hg@22 | 1289 c = blend(0xc0c0c0, 0x606060, c>1000 ? 1850-c : c-150, 700);
|
|---|
| public+hg@22 | 1290 putpixel(sprite, j+244, i+10, c);
|
|---|
| public+hg@22 | 1291 }
|
|---|
| public+hg@61 | 1292 for (i = -20; i < 60; ++i) {
|
|---|
| public+hg@22 | 1293 c = (i*3+j*2+750) % 2000;
|
|---|
| public+hg@22 | 1294 c = blend(0xc0c0c0, 0x404040, c>1000 ? 1850-c : c-150, 700);
|
|---|
| public+hg@22 | 1295 putpixel(sprite, j+244, i+540, c);
|
|---|
| public+hg@22 | 1296 }
|
|---|
| public+hg@22 | 1297 }
|
|---|
| public+hg@22 | 1298 SDL_FillRect(sprite, newrect(tpanel1+20,0,(tpanel2?tpanel2:820)-tpanel1-40,600), 0);
|
|---|
| public+hg@61 | 1299 for (i = 0; i < 20; ++i) {
|
|---|
| public+hg@61 | 1300 for (j = 20; j*j+i*i > 400; --j) {
|
|---|
| public+hg@22 | 1301 putpixel(sprite, tpanel1+j, i+10, 0);
|
|---|
| public+hg@22 | 1302 putpixel(sprite, tpanel1+j, 539-i, 0);
|
|---|
| public+hg@61 | 1303 if (tpanel2) {
|
|---|
| public+hg@22 | 1304 putpixel(sprite, tpanel2-j-1, i+10, 0);
|
|---|
| public+hg@22 | 1305 putpixel(sprite, tpanel2-j-1, 539-i, 0);
|
|---|
| public+hg@22 | 1306 }
|
|---|
| public+hg@22 | 1307 }
|
|---|
| public+hg@22 | 1308 }
|
|---|
| public+hg@61 | 1309 if (!tpanel2 && !opt_mode) {
|
|---|
| public+hg@30 | 1310 SDL_FillRect(sprite, newrect(0,584,368,16), 0x404040);
|
|---|
| public+hg@30 | 1311 SDL_FillRect(sprite, newrect(4,588,360,8), 0);
|
|---|
| public+hg@30 | 1312 }
|
|---|
| public+hg@30 | 1313 SDL_FillRect(sprite, newrect(10,564,tpanel1,1), 0x404040);
|
|---|
| public+hg@16 | 1314
|
|---|
| public+hg@22 | 1315 /* screen */
|
|---|
| public+hg@83 | 1316 SDL_FillRect(screen, 0, map(0));
|
|---|
| public+hg@22 | 1317 SDL_BlitSurface(sprite, newrect(0,0,800,30), screen, newrect(0,0,0,0));
|
|---|
| public+hg@22 | 1318 SDL_BlitSurface(sprite, newrect(0,520,800,80), screen, newrect(0,520,0,0));
|
|---|
| public+hg@30 | 1319
|
|---|
| public+hg@83 | 1320 /* video (if any) */
|
|---|
| public+hg@83 | 1321 if (mpeg) {
|
|---|
| public+hg@83 | 1322 imgres[imgmpeg] = newsurface(SDL_SWSURFACE, 256, 256);
|
|---|
| public+hg@83 | 1323 SMPEG_enablevideo(mpeg, 1);
|
|---|
| public+hg@83 | 1324 SMPEG_setdisplay(mpeg, imgres[imgmpeg], NULL, NULL);
|
|---|
| public+hg@83 | 1325 }
|
|---|
| public+hg@83 | 1326
|
|---|
| public+hg@30 | 1327 /* configuration */
|
|---|
| public+hg@30 | 1328 origintime = starttime = SDL_GetTicks();
|
|---|
| public+hg@28 | 1329 targetspeed = playspeed;
|
|---|
| public+hg@22 | 1330 Mix_AllocateChannels(128);
|
|---|
| public+hg@61 | 1331 for (i = 0; i < 22; ++i) pcur[i] = 0;
|
|---|
| public+hg@32 | 1332 gradefactor = 1.5 - v_rank * .25;
|
|---|
| public+hg@15 | 1333 }
|
|---|
| public+hg@15 | 1334
|
|---|
| public+hg@61 | 1335 static double adjust_object_time(double base, double offset)
|
|---|
| public+hg@61 | 1336 {
|
|---|
| public+hg@18 | 1337 int i = (int)(base+1)-1;
|
|---|
| public+hg@61 | 1338 if ((i + 1 - base) * shorten[i] > offset)
|
|---|
| public+hg@18 | 1339 return base + offset / shorten[i];
|
|---|
| public+hg@18 | 1340 offset -= (i + 1 - base) * shorten[i];
|
|---|
| public+hg@61 | 1341 while (shorten[++i] <= offset)
|
|---|
| public+hg@18 | 1342 offset -= shorten[i];
|
|---|
| public+hg@18 | 1343 return i + offset / shorten[i];
|
|---|
| public+hg@18 | 1344 }
|
|---|
| public+hg@18 | 1345
|
|---|
| public+hg@61 | 1346 static double adjust_object_position(double base, double time)
|
|---|
| public+hg@61 | 1347 {
|
|---|
| public+hg@18 | 1348 int i = (int)(base+1)-1, j = (int)(time+1)-1;
|
|---|
| public+hg@18 | 1349 base = (time - j) * shorten[j] - (base - i) * shorten[i];
|
|---|
| public+hg@61 | 1350 while (i < j) base += shorten[i++];
|
|---|
| public+hg@18 | 1351 return base;
|
|---|
| public+hg@16 | 1352 }
|
|---|
| public+hg@16 | 1353
|
|---|
| public+hg@69 | 1354 static void update_grade(int grade)
|
|---|
| public+hg@69 | 1355 {
|
|---|
| public+hg@69 | 1356 ++scocnt[grade];
|
|---|
| public+hg@69 | 1357 grademode = grade;
|
|---|
| public+hg@69 | 1358 gradetime = now + 700;
|
|---|
| public+hg@69 | 1359
|
|---|
| public+hg@69 | 1360 if (grade < 1) {
|
|---|
| public+hg@69 | 1361 scombo = 0;
|
|---|
| public+hg@85 | 1362 gauge -= 30;
|
|---|
| public+hg@69 | 1363 poorbga = now + 600;
|
|---|
| public+hg@69 | 1364 } else if (grade < 2) {
|
|---|
| public+hg@69 | 1365 scombo = 0;
|
|---|
| public+hg@85 | 1366 gauge -= 15;
|
|---|
| public+hg@69 | 1367 } else if (grade < 3) {
|
|---|
| public+hg@69 | 1368 /* do nothing */
|
|---|
| public+hg@69 | 1369 } else {
|
|---|
| public+hg@69 | 1370 ++scombo;
|
|---|
| public+hg@85 | 1371 gauge += (grade<4 ? 2 : 3) + (scombo<100 ? scombo : 100) / 50;
|
|---|
| public+hg@69 | 1372 }
|
|---|
| public+hg@69 | 1373
|
|---|
| public+hg@69 | 1374 if (scombo > smaxcombo) smaxcombo = scombo;
|
|---|
| public+hg@69 | 1375 }
|
|---|
| public+hg@69 | 1376
|
|---|
| public+hg@61 | 1377 static int play_process(void)
|
|---|
| public+hg@61 | 1378 {
|
|---|
| public+hg@85 | 1379 int i, j, k, l, ibottom, eop;
|
|---|
| public+hg@19 | 1380 double bottom, top, line, tmp;
|
|---|
| public+hg@30 | 1381 char buf[99];
|
|---|
| public+hg@15 | 1382
|
|---|
| public+hg@61 | 1383 if (adjustspeed) {
|
|---|
| public+hg@28 | 1384 tmp = targetspeed - playspeed;
|
|---|
| public+hg@61 | 1385 if (-0.001 < tmp && tmp < 0.001) {
|
|---|
| public+hg@61 | 1386 adjustspeed = 0;
|
|---|
| public+hg@61 | 1387 playspeed = targetspeed;
|
|---|
| public+hg@61 | 1388 for (i = 0; i < 22; ++i) prear[i] = pfront[i];
|
|---|
| public+hg@28 | 1389 } else {
|
|---|
| public+hg@85 | 1390 playspeed += tmp * 0.1;
|
|---|
| public+hg@28 | 1391 }
|
|---|
| public+hg@28 | 1392 }
|
|---|
| public+hg@28 | 1393
|
|---|
| public+hg@69 | 1394 now = SDL_GetTicks();
|
|---|
| public+hg@69 | 1395 if (now < stoptime) {
|
|---|
| public+hg@26 | 1396 bottom = startoffset;
|
|---|
| public+hg@61 | 1397 } else if (stoptime) {
|
|---|
| public+hg@69 | 1398 starttime = now;
|
|---|
| public+hg@26 | 1399 stoptime = 0;
|
|---|
| public+hg@26 | 1400 bottom = startoffset;
|
|---|
| public+hg@26 | 1401 } else {
|
|---|
| public+hg@69 | 1402 bottom = startoffset + (now - starttime) * bpm / startshorten / 24e4;
|
|---|
| public+hg@26 | 1403 }
|
|---|
| public+hg@18 | 1404 ibottom = (int)(bottom + 1) - 1;
|
|---|
| public+hg@61 | 1405 if (bottom > -1 && startshorten != shorten[ibottom]) {
|
|---|
| public+hg@18 | 1406 starttime += (int)((ibottom - startoffset) * 24e4 * startshorten / bpm);
|
|---|
| public+hg@19 | 1407 startoffset = ibottom;
|
|---|
| public+hg@18 | 1408 startshorten = shorten[ibottom];
|
|---|
| public+hg@18 | 1409 }
|
|---|
| public+hg@85 | 1410 line = bottom;/*adjust_object_time(bottom, 0.03/playspeed);*/
|
|---|
| public+hg@17 | 1411 top = adjust_object_time(bottom, 1.25/playspeed);
|
|---|
| public+hg@85 | 1412 eop = 1;
|
|---|
| public+hg@61 | 1413 for (i = 0; i < 22; ++i) {
|
|---|
| public+hg@73 | 1414 while (pfront[i] < nchannel[i] && channel[i][pfront[i]].time < bottom) ++pfront[i];
|
|---|
| public+hg@73 | 1415 while (prear[i] < nchannel[i] && channel[i][prear[i]].time <= top) ++prear[i];
|
|---|
| public+hg@73 | 1416 while (pcur[i] < nchannel[i] && channel[i][pcur[i]].time < line) {
|
|---|
| public+hg@73 | 1417 j = channel[i][pcur[i]].index;
|
|---|
| public+hg@61 | 1418 if (i == 18) {
|
|---|
| public+hg@61 | 1419 if (sndres[j]) {
|
|---|
| public+hg@32 | 1420 j = Mix_PlayChannel(-1, sndres[j], 0);
|
|---|
| public+hg@61 | 1421 if (j >= 0) {
|
|---|
| public+hg@61 | 1422 Mix_Volume(j, 96);
|
|---|
| public+hg@61 | 1423 Mix_GroupChannel(j, 1);
|
|---|
| public+hg@61 | 1424 }
|
|---|
| public+hg@16 | 1425 }
|
|---|
| public+hg@61 | 1426 } else if (i == 19) {
|
|---|
| public+hg@73 | 1427 bga[channel[i][pcur[i]].type] = j;
|
|---|
| public+hg@15 | 1428 bga_updated = 1;
|
|---|
| public+hg@61 | 1429 } else if (i == 20) {
|
|---|
| public+hg@73 | 1430 if (tmp = (channel[i][pcur[i]].type ? bpmtab[j] : j)) {
|
|---|
| public+hg@69 | 1431 starttime = now;
|
|---|
| public+hg@30 | 1432 startoffset = bottom;
|
|---|
| public+hg@30 | 1433 bpm = tmp;
|
|---|
| public+hg@30 | 1434 }
|
|---|
| public+hg@61 | 1435 } else if (i == 21) {
|
|---|
| public+hg@69 | 1436 if (now >= stoptime) stoptime = now;
|
|---|
| public+hg@73 | 1437 if (channel[i][pcur[i]].type) {
|
|---|
| public+hg@32 | 1438 stoptime += j;
|
|---|
| public+hg@26 | 1439 } else {
|
|---|
| public+hg@32 | 1440 stoptime += (int)(stoptab[j] * 1250 * startshorten / bpm);
|
|---|
| public+hg@26 | 1441 }
|
|---|
| public+hg@26 | 1442 startoffset = bottom;
|
|---|
| public+hg@80 | 1443 } else if (opt_mode && channel[i][pcur[i]].type != 3/*INVNOTE*/ && sndres[j]) {
|
|---|
| public+hg@32 | 1444 j = Mix_PlayChannel(-1, sndres[j], 0);
|
|---|
| public+hg@61 | 1445 if (j >= 0) Mix_GroupChannel(j, 0);
|
|---|
| public+hg@81 | 1446 score += (int)(300 * (1 + 1. * scombo / xnnotes));
|
|---|
| public+hg@81 | 1447 update_grade(4);
|
|---|
| public+hg@15 | 1448 }
|
|---|
| public+hg@61 | 1449 ++pcur[i];
|
|---|
| public+hg@15 | 1450 }
|
|---|
| public+hg@61 | 1451 if (i<18 && !opt_mode) {
|
|---|
| public+hg@61 | 1452 for (; pcheck[i] < pcur[i]; ++pcheck[i]) {
|
|---|
| public+hg@73 | 1453 j = channel[i][pcheck[i]].type;
|
|---|
| public+hg@80 | 1454 if (j < 0 || j == 3/*INVNOTE*/ || (j == 0/*LNDONE*/ && !thru[i])) continue;
|
|---|
| public+hg@73 | 1455 tmp = channel[i][pcheck[i]].time;
|
|---|
| public+hg@32 | 1456 tmp = (line - tmp) * shorten[(int)tmp] / bpm * gradefactor;
|
|---|
| public+hg@69 | 1457 if (tmp > 6e-4) update_grade(0); else break;
|
|---|
| public+hg@30 | 1458 }
|
|---|
| public+hg@85 | 1459 if (pfront[i] < nchannel[i]) eop = 0;
|
|---|
| public+hg@30 | 1460 }
|
|---|
| public+hg@15 | 1461 }
|
|---|
| public+hg@15 | 1462
|
|---|
| public+hg@61 | 1463 while (SDL_PollEvent(&event)) {
|
|---|
| public+hg@61 | 1464 if (event.type == SDL_QUIT) {
|
|---|
| public+hg@85 | 1465 return (eop ? 0 : -1);
|
|---|
| public+hg@61 | 1466 } else if (event.type == SDL_KEYUP) {
|
|---|
| public+hg@61 | 1467 if (event.key.keysym.sym == SDLK_ESCAPE) {
|
|---|
| public+hg@85 | 1468 return (eop ? 0 : -1);
|
|---|
| public+hg@61 | 1469 } else if (!opt_mode) {
|
|---|
| public+hg@85 | 1470 i = keymap[event.key.keysym.sym];
|
|---|
| public+hg@85 | 1471 if (i >= 0 && i < 18 && tkeyleft[i] >= 0) {
|
|---|
| public+hg@85 | 1472 j = keypressed[i];
|
|---|
| public+hg@85 | 1473 if (j > 0) --keypressed[i];
|
|---|
| public+hg@85 | 1474 if (j == 1 && nchannel[i] && thru[i]) {
|
|---|
| public+hg@85 | 1475 for (j = pcur[i]; channel[i][j].type != 0/*LNDONE*/; --j);
|
|---|
| public+hg@85 | 1476 thru[i] = 0;
|
|---|
| public+hg@85 | 1477 tmp = (channel[i][j].time - line) * shorten[(int)line] / bpm * gradefactor;
|
|---|
| public+hg@85 | 1478 if (-6e-4 < tmp && tmp < 6e-4) {
|
|---|
| public+hg@85 | 1479 channel[i][j].type ^= -1;
|
|---|
| public+hg@85 | 1480 } else {
|
|---|
| public+hg@85 | 1481 update_grade(0);
|
|---|
| public+hg@28 | 1482 }
|
|---|
| public+hg@28 | 1483 }
|
|---|
| public+hg@28 | 1484 }
|
|---|
| public+hg@16 | 1485 }
|
|---|
| public+hg@61 | 1486 } else if (event.type == SDL_KEYDOWN) {
|
|---|
| public+hg@85 | 1487 i = keymap[event.key.keysym.sym];
|
|---|
| public+hg@85 | 1488 if (i == 18/*SPEED_DOWN*/) {
|
|---|
| public+hg@61 | 1489 if (targetspeed > 20) targetspeed -= 5;
|
|---|
| public+hg@61 | 1490 else if (targetspeed > 10) targetspeed -= 1;
|
|---|
| public+hg@61 | 1491 else if (targetspeed > 1) targetspeed -= .5;
|
|---|
| public+hg@61 | 1492 else if (targetspeed > .201) targetspeed -= .2;
|
|---|
| public+hg@24 | 1493 else continue;
|
|---|
| public+hg@28 | 1494 adjustspeed = 1;
|
|---|
| public+hg@85 | 1495 Mix_PlayChannel(-1, beep, 0);
|
|---|
| public+hg@85 | 1496 } else if (i == 19/*SPEED_UP*/) {
|
|---|
| public+hg@61 | 1497 if (targetspeed < 1) targetspeed += .2;
|
|---|
| public+hg@61 | 1498 else if (targetspeed < 10) targetspeed += .5;
|
|---|
| public+hg@61 | 1499 else if (targetspeed < 20) targetspeed += 1;
|
|---|
| public+hg@61 | 1500 else if (targetspeed < 95) targetspeed += 5;
|
|---|
| public+hg@28 | 1501 else continue;
|
|---|
| public+hg@28 | 1502 adjustspeed = 1;
|
|---|
| public+hg@85 | 1503 Mix_PlayChannel(-1, beep, 0);
|
|---|
| public+hg@61 | 1504 } else if (!opt_mode) {
|
|---|
| public+hg@85 | 1505 if (i >= 0 && i < 18 && tkeyleft[i] >= 0) {
|
|---|
| public+hg@85 | 1506 if (keypressed[i]++ || !nchannel[i]) continue;
|
|---|
| public+hg@80 | 1507
|
|---|
| public+hg@85 | 1508 j = (pcur[i] < 1 || (pcur[i] < nchannel[i] && channel[i][pcur[i]-1].time + channel[i][pcur[i]].time < 2*line) ? pcur[i] : pcur[i]-1);
|
|---|
| public+hg@85 | 1509 if (sndres[channel[i][j].index]) {
|
|---|
| public+hg@85 | 1510 l = Mix_PlayChannel(-1, sndres[channel[i][j].index], 0);
|
|---|
| public+hg@85 | 1511 if (l >= 0) Mix_GroupChannel(l, 0);
|
|---|
| public+hg@85 | 1512 }
|
|---|
| public+hg@80 | 1513
|
|---|
| public+hg@85 | 1514 if (j < pcur[i]) {
|
|---|
| public+hg@85 | 1515 while (j >= 0 && channel[i][j].type == 3/*INVNOTE*/) --j;
|
|---|
| public+hg@85 | 1516 if (j < 0) continue;
|
|---|
| public+hg@85 | 1517 } else {
|
|---|
| public+hg@85 | 1518 while (j < nchannel[i] && channel[i][j].type == 3/*INVNOTE*/) ++j;
|
|---|
| public+hg@85 | 1519 if (j == nchannel[i]) continue;
|
|---|
| public+hg@85 | 1520 }
|
|---|
| public+hg@80 | 1521
|
|---|
| public+hg@85 | 1522 if (channel[i][j].type == 0/*LNDONE*/) {
|
|---|
| public+hg@85 | 1523 if (thru[i]) update_grade(0);
|
|---|
| public+hg@85 | 1524 } else if (channel[i][j].type >= 0) {
|
|---|
| public+hg@85 | 1525 tmp = (channel[i][j].time - line) * shorten[(int)line] / bpm * gradefactor;
|
|---|
| public+hg@85 | 1526 if (tmp < 0) tmp *= -1;
|
|---|
| public+hg@85 | 1527 if (channel[i][j].type >= 0 && tmp < 6e-4) {
|
|---|
| public+hg@85 | 1528 if (channel[i][j].type == 1/*LNSTART*/) thru[i] = 1;
|
|---|
| public+hg@85 | 1529 channel[i][j].type ^= -1;
|
|---|
| public+hg@85 | 1530 score += (int)((300 - tmp * 5e5) * (1 + 1. * scombo / xnnotes));
|
|---|
| public+hg@85 | 1531 update_grade(tmp<0.6e-4 ? 4 : tmp<2.0e-4 ? 3 : tmp<3.5e-4 ? 2 : 1);
|
|---|
| public+hg@24 | 1532 }
|
|---|
| public+hg@19 | 1533 }
|
|---|
| public+hg@16 | 1534 }
|
|---|
| public+hg@16 | 1535 }
|
|---|
| public+hg@16 | 1536 }
|
|---|
| public+hg@16 | 1537 }
|
|---|
| public+hg@61 | 1538 if (bottom > length) {
|
|---|
| public+hg@84 | 1539 if (opt_mode ? Mix_Playing(-1)==0 : Mix_GroupNewer(1)==-1) return 0;
|
|---|
| public+hg@61 | 1540 } else if (bottom < -1) {
|
|---|
| public+hg@28 | 1541 return 0;
|
|---|
| public+hg@26 | 1542 }
|
|---|
| public+hg@15 | 1543
|
|---|
| public+hg@83 | 1544 SDL_FillRect(screen, newrect(0,30,tpanel1,490), map(0x404040));
|
|---|
| public+hg@83 | 1545 if (tpanel2) SDL_FillRect(screen, newrect(tpanel2,30,800-tpanel2,490), map(0x404040));
|
|---|
| public+hg@61 | 1546 for (i = 0; i < 18; ++i) {
|
|---|
| public+hg@61 | 1547 if (tkeyleft[i] < 0) continue;
|
|---|
| public+hg@83 | 1548 SDL_FillRect(screen, newrect(tkeyleft[i],30,tkeywidth[i],490), map(0));
|
|---|
| public+hg@61 | 1549 if (keypressed[i]) {
|
|---|
| public+hg@17 | 1550 SDL_BlitSurface(sprite, newrect(tkeyleft[i],140,tkeywidth[i],380), screen, newrect(tkeyleft[i],140,0,0));
|
|---|
| public+hg@16 | 1551 }
|
|---|
| public+hg@15 | 1552 }
|
|---|
| public+hg@22 | 1553 SDL_SetClipRect(screen, newrect(0,30,800,490));
|
|---|
| public+hg@61 | 1554 for (i = 0; i < 18; ++i) {
|
|---|
| public+hg@61 | 1555 if (tkeyleft[i] < 0) continue;
|
|---|
| public+hg@61 | 1556 for (j = pfront[i]; j < prear[i]; ++j) {
|
|---|
| public+hg@73 | 1557 k = (int)(525 - 400 * playspeed * adjust_object_position(bottom, channel[i][j].time));
|
|---|
| public+hg@80 | 1558 if (channel[i][j].type == 1/*LNSTART*/) {
|
|---|
| public+hg@26 | 1559 l = k + 5;
|
|---|
| public+hg@73 | 1560 k = (int)(530 - 400 * playspeed * adjust_object_position(bottom, channel[i][++j].time));
|
|---|
| public+hg@61 | 1561 if (k < 30) k = 30;
|
|---|
| public+hg@80 | 1562 } else if (channel[i][j].type == 0/*LNDONE*/) {
|
|---|
| public+hg@26 | 1563 k += 5;
|
|---|
| public+hg@24 | 1564 l = 520;
|
|---|
| public+hg@80 | 1565 } else if (channel[i][j].type == 2/*NOTE*/) {
|
|---|
| public+hg@24 | 1566 l = k + 5;
|
|---|
| public+hg@24 | 1567 } else {
|
|---|
| public+hg@24 | 1568 continue;
|
|---|
| public+hg@22 | 1569 }
|
|---|
| public+hg@61 | 1570 if (k > 0 && l > k) {
|
|---|
| public+hg@24 | 1571 SDL_BlitSurface(sprite, newrect(800+tkeyleft[i%9],0,tkeywidth[i%9],l-k), screen, newrect(tkeyleft[i],k,0,0));
|
|---|
| public+hg@24 | 1572 }
|
|---|
| public+hg@24 | 1573 }
|
|---|
| public+hg@80 | 1574 if (pfront[i]==prear[i] && prear[i]<nchannel[i] && channel[i][prear[i]].type==0/*LNDONE*/) {
|
|---|
| public+hg@24 | 1575 SDL_BlitSurface(sprite, newrect(800+tkeyleft[i%9],0,tkeywidth[i%9],490), screen, newrect(tkeyleft[i],30,0,0));
|
|---|
| public+hg@16 | 1576 }
|
|---|
| public+hg@16 | 1577 }
|
|---|
| public+hg@61 | 1578 for (i = ibottom; i < top; ++i) {
|
|---|
| public+hg@24 | 1579 j = (int)(530 - 400 * playspeed * adjust_object_position(bottom, i));
|
|---|
| public+hg@83 | 1580 SDL_FillRect(screen, newrect(0,j,tpanel1,1), map(0xc0c0c0));
|
|---|
| public+hg@83 | 1581 if (tpanel2) SDL_FillRect(screen, newrect(tpanel2,j,800-tpanel2,1), map(0xc0c0c0));
|
|---|
| public+hg@17 | 1582 }
|
|---|
| public+hg@69 | 1583 if (now < gradetime) {
|
|---|
| public+hg@81 | 1584 int delta = (gradetime - now - 400) / 30;
|
|---|
| public+hg@81 | 1585 if (delta < 0) delta = 0;
|
|---|
| public+hg@81 | 1586 printstr(screen, tpanel1/2-8*strlen(tgradestr[grademode]), 260 - delta, 2,
|
|---|
| public+hg@77 | 1587 tgradestr[grademode], tgradecolor[grademode][0], tgradecolor[grademode][1]);
|
|---|
| public+hg@61 | 1588 if (scombo > 1) {
|
|---|
| public+hg@30 | 1589 i = sprintf(buf, "%d COMBO", scombo);
|
|---|
| public+hg@81 | 1590 printstr(screen, tpanel1/2-4*i, 288 - delta, 1, buf, 0x808080, 0xffffff);
|
|---|
| public+hg@30 | 1591 }
|
|---|
| public+hg@81 | 1592 if (opt_mode) printstr(screen, tpanel1/2-24, 302 - delta, 1, "(AUTO)", 0x404040, 0xc0c0c0);
|
|---|
| public+hg@61 | 1593 if (!grademode) bga_updated = 1;
|
|---|
| public+hg@30 | 1594 }
|
|---|
| public+hg@18 | 1595 SDL_SetClipRect(screen, 0);
|
|---|
| public+hg@84 | 1596 if (bga_updated > 0 || (bga_updated < 0 && now >= poorbga) || (mpeg && SMPEG_status(mpeg) == SMPEG_PLAYING)) {
|
|---|
| public+hg@83 | 1597 SDL_FillRect(screen, newrect(tbga,172,256,256), map(0));
|
|---|
| public+hg@83 | 1598 for (i = 0; i < 3; ++i) {
|
|---|
| public+hg@83 | 1599 if (bga_updated > 0 && bga[i] == imgmpeg && SMPEG_status(mpeg) != SMPEG_PLAYING) SMPEG_play(mpeg);
|
|---|
| public+hg@83 | 1600 }
|
|---|
| public+hg@69 | 1601 if (now < poorbga) {
|
|---|
| public+hg@61 | 1602 if (bga[2] >= 0 && imgres[bga[2]])
|
|---|
| public+hg@26 | 1603 SDL_BlitSurface(imgres[bga[2]], newrect(0,0,256,256), screen, newrect(tbga,172,0,0));
|
|---|
| public+hg@30 | 1604 bga_updated = -1;
|
|---|
| public+hg@26 | 1605 } else {
|
|---|
| public+hg@61 | 1606 for (i = 0; i < 2; ++i)
|
|---|
| public+hg@83 | 1607 if (bga[i] >= 0 && imgres[bga[i]])
|
|---|
| public+hg@26 | 1608 SDL_BlitSurface(imgres[bga[i]], newrect(0,0,256,256), screen, newrect(tbga,172,0,0));
|
|---|
| public+hg@26 | 1609 bga_updated = 0;
|
|---|
| public+hg@26 | 1610 }
|
|---|
| public+hg@15 | 1611 }
|
|---|
| public+hg@30 | 1612
|
|---|
| public+hg@69 | 1613 i = (now - origintime) / 1000;
|
|---|
| public+hg@61 | 1614 j = xduration / 1000;
|
|---|
| public+hg@30 | 1615 sprintf(buf, "SCORE %07d%c%4.1fx%c%02d:%02d / %02d:%02d%c@%9.4f%cBPM %6.2f",
|
|---|
| public+hg@30 | 1616 score, 0, targetspeed, 0, i/60, i%60, j/60, j%60, 0, bottom, 0, bpm);
|
|---|
| public+hg@30 | 1617 SDL_BlitSurface(sprite, newrect(0,0,800,30), screen, newrect(0,0,0,0));
|
|---|
| public+hg@30 | 1618 SDL_BlitSurface(sprite, newrect(0,520,800,80), screen, newrect(0,520,0,0));
|
|---|
| public+hg@30 | 1619 printstr(screen, 10, 8, 1, buf, 0, 0);
|
|---|
| public+hg@30 | 1620 printstr(screen, 5, 522, 2, buf+14, 0, 0);
|
|---|
| public+hg@30 | 1621 printstr(screen, tpanel1-94, 565, 1, buf+20, 0, 0x404040);
|
|---|
| public+hg@30 | 1622 printstr(screen, 95, 538, 1, buf+34, 0, 0);
|
|---|
| public+hg@30 | 1623 printstr(screen, 95, 522, 1, buf+45, 0, 0);
|
|---|
| public+hg@69 | 1624 i = (now - origintime) * tpanel1 / xduration;
|
|---|
| public+hg@32 | 1625 printchar(screen, 6+(i<tpanel1?i:tpanel1), 548, 1, -1, 0x404040, 0x404040);
|
|---|
| public+hg@61 | 1626 if (!tpanel2 && !opt_mode) {
|
|---|
| public+hg@61 | 1627 if (gauge > 512) gauge = 512;
|
|---|
| public+hg@85 | 1628 k = (int)(160*startshorten*(1+bottom)) % 40; /* i.e. cycles four times per measure */
|
|---|
| public+hg@85 | 1629 i = (gauge<0 ? 0 : (gauge*400>>9) - k);
|
|---|
| public+hg@85 | 1630 j = (gauge>=survival ? 0xc0 : 0xc0 - k*4) << 16;
|
|---|
| public+hg@85 | 1631 SDL_FillRect(screen, newrect(4,588,i>360?360:i<5?5:i,8), map(j));
|
|---|
| public+hg@19 | 1632 }
|
|---|
| public+hg@19 | 1633
|
|---|
| public+hg@15 | 1634 SDL_Flip(screen);
|
|---|
| public+hg@16 | 1635 return 1;
|
|---|
| public+hg@15 | 1636 }
|
|---|
| public+hg@15 | 1637
|
|---|
| public+hg@20 | 1638 /******************************************************************************/
|
|---|
| public+hg@20 | 1639 /* entry point */
|
|---|
| public+hg@20 | 1640
|
|---|
| public+hg@61 | 1641 static int play(void)
|
|---|
| public+hg@61 | 1642 {
|
|---|
| public+hg@30 | 1643 int i;
|
|---|
| public+hg@76 | 1644 char *pos1, *pos2;
|
|---|
| public+hg@61 | 1645
|
|---|
| public+hg@61 | 1646 if (initialize()) return 1;
|
|---|
| public+hg@61 | 1647
|
|---|
| public+hg@85 | 1648 if (read_bms()) die("Couldn't load BMS file: %s", bmspath);
|
|---|
| public+hg@61 | 1649 if (v_player == 4) clone_bms();
|
|---|
| public+hg@61 | 1650 if (opt_random) {
|
|---|
| public+hg@61 | 1651 if (v_player == 3) {
|
|---|
| public+hg@26 | 1652 shuffle_bms(opt_random, 0);
|
|---|
| public+hg@26 | 1653 } else {
|
|---|
| public+hg@26 | 1654 shuffle_bms(opt_random, 1);
|
|---|
| public+hg@61 | 1655 if (v_player != 1) shuffle_bms(opt_random, 2);
|
|---|
| public+hg@26 | 1656 }
|
|---|
| public+hg@26 | 1657 }
|
|---|
| public+hg@30 | 1658 get_bms_info();
|
|---|
| public+hg@61 | 1659
|
|---|
| public+hg@76 | 1660 /* get basename of bmspath */
|
|---|
| public+hg@76 | 1661 pos1 = strrchr(bmspath, '/');
|
|---|
| public+hg@76 | 1662 pos2 = strrchr(bmspath, '\\');
|
|---|
| public+hg@76 | 1663 if (!pos1) pos1 = bmspath + 1;
|
|---|
| public+hg@76 | 1664 if (!pos2) pos2 = bmspath + 1;
|
|---|
| public+hg@76 | 1665 (pos1>pos2 ? pos1 : pos2)[1] = '\0';
|
|---|
| public+hg@76 | 1666 if (pos1 == pos2) { /* will be pos1 = pos2 = bmspath + 1 */
|
|---|
| public+hg@76 | 1667 bmspath[0] = '.';
|
|---|
| public+hg@76 | 1668 bmspath[1] = sep;
|
|---|
| public+hg@76 | 1669 }
|
|---|
| public+hg@76 | 1670
|
|---|
| public+hg@76 | 1671 dirinit();
|
|---|
| public+hg@15 | 1672 play_show_stagefile();
|
|---|
| public+hg@72 | 1673 dirfinal();
|
|---|
| public+hg@61 | 1674
|
|---|
| public+hg@30 | 1675 xduration = get_bms_duration();
|
|---|
| public+hg@15 | 1676 play_prepare();
|
|---|
| public+hg@61 | 1677 while ((i = play_process()) > 0);
|
|---|
| public+hg@61 | 1678
|
|---|
| public+hg@61 | 1679 if (!opt_mode && i == 0) {
|
|---|
| public+hg@85 | 1680 if (gauge >= survival) {
|
|---|
| public+hg@30 | 1681 printf("*** CLEARED! ***\n");
|
|---|
| public+hg@61 | 1682 for (i = 4; i >= 0; --i)
|
|---|
| public+hg@30 | 1683 printf("%-5s %4d %s", tgradestr[i], scocnt[i], "\n"+(i!=2));
|
|---|
| public+hg@30 | 1684 printf("MAX COMBO %d\nSCORE %07d (max %07d)\n", smaxcombo, score, xscore);
|
|---|
| public+hg@30 | 1685 } else {
|
|---|
| public+hg@30 | 1686 printf("YOU FAILED!\n");
|
|---|
| public+hg@30 | 1687 }
|
|---|
| public+hg@30 | 1688 }
|
|---|
| public+hg@61 | 1689
|
|---|
| public+hg@30 | 1690 return 0;
|
|---|
| public+hg@17 | 1691 }
|
|---|
| public+hg@15 | 1692
|
|---|
| public+hg@85 | 1693 int usage(void)
|
|---|
| public+hg@61 | 1694 {
|
|---|
| public+hg@85 | 1695 fprintf(stderr,
|
|---|
| public+hg@85 | 1696 "%s -- the simple BMS player\n"
|
|---|
| public+hg@85 | 1697 "http://mearie.org/projects/angolmois/\n\n"
|
|---|
| public+hg@85 | 1698 "Usage: %s <options> <path>\n"
|
|---|
| public+hg@85 | 1699 " Accepts any BMS, BME or BML file.\n"
|
|---|
| public+hg@85 | 1700 " Resources should be in the same directory as the BMS file.\n\n"
|
|---|
| public+hg@85 | 1701 "Options:\n"
|
|---|
| public+hg@85 | 1702 " -h, --help This help\n"
|
|---|
| public+hg@85 | 1703 " -V, --version Shows the version\n"
|
|---|
| public+hg@85 | 1704 " -a #.#, --speed #.# Sets the initial play speed (default: 1.0x)\n"
|
|---|
| public+hg@85 | 1705 " -# Same as '-a #.0'\n"
|
|---|
| public+hg@85 | 1706 " -v, --autoplay Enables AUTO PLAY (viewer) mode\n"
|
|---|
| public+hg@85 | 1707 " --fullscreen Enables the fullscreen mode (default)\n"
|
|---|
| public+hg@85 | 1708 " -w, --no-fullscreen Disables the fullscreen mode\n"
|
|---|
| public+hg@85 | 1709 " --info Shows a brief information about the song (default)\n"
|
|---|
| public+hg@85 | 1710 " -q, --no-info Do not show an information about the song\n"
|
|---|
| public+hg@85 | 1711 " -m, --mirror Uses a mirror modifier\n"
|
|---|
| public+hg@85 | 1712 " -r, --random Uses a random modifier\n"
|
|---|
| public+hg@85 | 1713 " -R, --random-ex Uses a random modifier, even for scratches\n"
|
|---|
| public+hg@85 | 1714 " -s, --srandom Uses a super-random modifier\n"
|
|---|
| public+hg@85 | 1715 " -S, --srandom-ex Uses a super-random modifier, even for scratches\n"
|
|---|
| public+hg@85 | 1716 " --bga Loads and shows the BGA (default)\n"
|
|---|
| public+hg@85 | 1717 " -B, --no-bga Do not load and show the BGA\n"
|
|---|
| public+hg@85 | 1718 " -M, --no-movie Do not load and show the BGA movie\n\n"
|
|---|
| public+hg@85 | 1719 "Environment Variables:\n"
|
|---|
| public+hg@85 | 1720 " ANGOLMOIS_1P_KEYS=<1>|<2>|<3>|<4>|<5>|<scratch>|<pedal>|<6>|<7>\n"
|
|---|
| public+hg@85 | 1721 " ANGOLMOIS_2P_KEYS=<1>|<2>|<3>|<4>|<5>|<scratch>|<pedal>|<6>|<7>\n"
|
|---|
| public+hg@85 | 1722 " ANGOLMOIS_SPEED_KEYS=<speed down>|<speed up>\n"
|
|---|
| public+hg@85 | 1723 " Specifies the keys used for gameplay. Key names should follow them of\n"
|
|---|
| public+hg@85 | 1724 " SDL (e.g. 'a', 'right shift' etc.). The mapping for 1P/2P is as follows:\n"
|
|---|
| public+hg@85 | 1725 " <2> <4> <6>\n"
|
|---|
| public+hg@85 | 1726 " <scratch> <1> <3> <5> <7> <pedal>\n"
|
|---|
| public+hg@85 | 1727 " One can map multiple keys by separating key names with '%%'.\n"
|
|---|
| public+hg@85 | 1728 " The default mapping is to use zsxdcfv and mk,l.;/ for 1P and 2P,\n"
|
|---|
| public+hg@85 | 1729 " respectively. F3 and F4 is used for speed adjustment.\n\n",
|
|---|
| public+hg@85 | 1730 VERSION, argv0);
|
|---|
| public+hg@85 | 1731 return 1;
|
|---|
| public+hg@13 | 1732 }
|
|---|
| public+hg@13 | 1733
|
|---|
| public+hg@61 | 1734 int main(int argc, char **argv)
|
|---|
| public+hg@61 | 1735 {
|
|---|
| public+hg@85 | 1736 static char *longargs[] =
|
|---|
| public+hg@85 | 1737 {"h--help", "V--version", "a--speed", "v--autoplay", "w--windowed",
|
|---|
| public+hg@85 | 1738 "w--no-fullscreen", " --fullscreen", " --info", "q--no-info", "m--mirror",
|
|---|
| public+hg@85 | 1739 "r--random", "R--random-ex", "s--srandom", "S--srandom-ex", " --bga",
|
|---|
| public+hg@85 | 1740 "B--no-bga", " --movie", "M--no-movie", NULL};
|
|---|
| public+hg@61 | 1741 char buf[512]={0};
|
|---|
| public+hg@85 | 1742 int i, j, cont;
|
|---|
| public+hg@24 | 1743
|
|---|
| public+hg@85 | 1744 argv0 = argv[0];
|
|---|
| public+hg@85 | 1745 for (i = 1; argv[i]; ++i) {
|
|---|
| public+hg@85 | 1746 if (argv[i][0] != '-') {
|
|---|
| public+hg@85 | 1747 if (!bmspath) bmspath = argv[i];
|
|---|
| public+hg@85 | 1748 } else if (!strcmp(argv[i], "--")) {
|
|---|
| public+hg@85 | 1749 if (!bmspath) bmspath = argv[++i];
|
|---|
| public+hg@85 | 1750 break;
|
|---|
| public+hg@85 | 1751 } else {
|
|---|
| public+hg@85 | 1752 if (argv[i][1] == '-') {
|
|---|
| public+hg@85 | 1753 for (j = 0; longargs[j]; ++j) {
|
|---|
| public+hg@85 | 1754 if (!strcmp(argv[i], longargs[j]+1)) {
|
|---|
| public+hg@85 | 1755 argv[i][1] = longargs[j][0];
|
|---|
| public+hg@85 | 1756 argv[i][2] = '\0';
|
|---|
| public+hg@85 | 1757 break;
|
|---|
| public+hg@85 | 1758 }
|
|---|
| public+hg@85 | 1759 }
|
|---|
| public+hg@85 | 1760 if (!longargs[j]) die("Invalid option: %s", argv[i]);
|
|---|
| public+hg@85 | 1761 }
|
|---|
| public+hg@85 | 1762 for (j = cont = 1; cont; ++j) {
|
|---|
| public+hg@85 | 1763 switch (argv[i][j]) {
|
|---|
| public+hg@85 | 1764 case 'h': case 'V': usage(); exit(1);
|
|---|
| public+hg@85 | 1765 case 'v': opt_mode = 1; break;
|
|---|
| public+hg@85 | 1766 case 'w': opt_fullscreen = 0; break;
|
|---|
| public+hg@85 | 1767 case 'q': opt_showinfo = 0; break;
|
|---|
| public+hg@85 | 1768 case 'm': opt_random = 1; break;
|
|---|
| public+hg@85 | 1769 case 's': opt_random = 2; break;
|
|---|
| public+hg@85 | 1770 case 'S': opt_random = 3; break;
|
|---|
| public+hg@85 | 1771 case 'r': opt_random = 4; break;
|
|---|
| public+hg@85 | 1772 case 'R': opt_random = 5; break;
|
|---|
| public+hg@85 | 1773 case 'a':
|
|---|
| public+hg@85 | 1774 playspeed = atof(argv[i][++j] ? argv[i]+j : argv[++i]);
|
|---|
| public+hg@85 | 1775 if (playspeed <= 0) playspeed = 1;
|
|---|
| public+hg@85 | 1776 if (playspeed < .1) playspeed = .1;
|
|---|
| public+hg@85 | 1777 if (playspeed > 99) playspeed = 99;
|
|---|
| public+hg@85 | 1778 case 'B': opt_bga = 2; break;
|
|---|
| public+hg@85 | 1779 case 'M': opt_bga = 1; break;
|
|---|
| public+hg@85 | 1780 case '\0': cont = 0;
|
|---|
| public+hg@85 | 1781 case ' ': break;
|
|---|
| public+hg@85 | 1782 default:
|
|---|
| public+hg@85 | 1783 if (argv[i][j] >= '1' && argv[i][j] <= '9') {
|
|---|
| public+hg@85 | 1784 playspeed = argv[i][j] - '0';
|
|---|
| public+hg@85 | 1785 } else {
|
|---|
| public+hg@85 | 1786 die("Invalid option: -%c", argv[i][j]);
|
|---|
| public+hg@85 | 1787 }
|
|---|
| public+hg@85 | 1788 }
|
|---|
| public+hg@85 | 1789 }
|
|---|
| public+hg@17 | 1790 }
|
|---|
| public+hg@17 | 1791 }
|
|---|
| public+hg@61 | 1792
|
|---|
| public+hg@85 | 1793 if (!bmspath && filedialog(buf)) bmspath = buf;
|
|---|
| public+hg@85 | 1794 return bmspath ? play() : usage();
|
|---|
| public+hg@0 | 1795 }
|
|---|
| public+hg@0 | 1796
|
|---|
| public+hg@0 | 1797 /* vim: set ts=4 sw=4: */
|