~ubuntu-branches/ubuntu/lucid/tuxtype/lucid-proposed

« back to all changes in this revision

Viewing changes to src/scripting.c

  • Committer: Bazaar Package Importer
  • Author(s): Holger Levsen
  • Date: 2009-11-25 13:17:11 UTC
  • mfrom: (2.1.6 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091125131711-nhssnv6ewxj4ubrv
Tags: 1.8.0-1
* New upstream release, quoting from the upstream changelog:
  - new music files and backgrounds contributed by Caroline Ford,
    some old sounds (the ones with suboptimal free licensing) removed -
    Tux Typing is now 100% DFSG-compliant (Closes: #400924)
  - fixed a problem that was causing the wrong key to flash in the bottom
    row of keys
  - game Instructions - simplified and reactivated cascade and laser game
    instruction scripts, fixed scripting background image so that it scales
    properly in fullscreen
  - scripting - Added some basic scripts so that new users will have a
    complete lesson set out of the box. Added a howto in the docs.
  - Sarah Frisk's word list editor from GSoC 2009 has been merged in as
    a new, somewhat "beta" feature. (Closes: #94986)
* tuxtype.postinst: Make tuxtype binary and shared wordlist directory 
  setgid games, so that wordlists can be edited and shared. This is done
  with dpkg-statoverride, so local admins can override this decission.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
#define MAX_LESSONS 100
21
21
#include "SDL_extras.h"
22
22
#include "convert_utf.h"
 
23
#include "scandir.h"
23
24
 
24
25
/* Local function prototypes: */
25
26
static void clear_items(itemType* i);
31
32
static char hex2int(char b, char s);
32
33
static int load_script(const char* fn);
33
34
static void run_script(void);
34
 
 
 
35
static int is_xml_file(const struct dirent* xml_dirent);
35
36
/************************************************************************/
36
37
/*                                                                      */ 
37
38
/*         "Public" functions (callable throughout program)             */
65
66
void InstructLaser(void)
66
67
{
67
68
  char fn[FNLEN]; 
68
 
  int i;
69
69
 
70
70
  /* Try theme script first: */
71
71
  if (!settings.use_english)
73
73
 
74
74
  if (load_script( fn ) == 0) /* meaning successful load */
75
75
  {
76
 
    for (i = 0; i < 20; i++)
77
 
    {
78
 
      run_script();
79
 
      SDL_Delay(500);
80
 
    }
 
76
    run_script();
81
77
    return;
82
78
  }
83
79
 
87
83
  if (load_script( fn ) != 0)
88
84
    return; // bail if any errors occur
89
85
 
90
 
  for (i = 0; i < 20; i++)
91
 
  {
92
 
    run_script();
93
 
    SDL_Delay(500);
94
 
  }
 
86
  run_script();
95
87
}
96
88
 
97
 
 
98
89
void ProjectInfo(void)
99
90
{
100
91
  char fn[FNLEN]; 
117
108
  run_script();
118
109
}
119
110
 
120
 
/* NOTE - confusing function name - this is the function that allows the user */
121
 
/* to select a lesson from the menu.                                          */
122
 
int TestLesson(void)
 
111
/* This is the function that allows the user */
 
112
/* to select a lesson from the menu.         */
 
113
/* FIXME we ought to display descriptive titles from the lessons, */
 
114
/* rather than just the filenames.  We also should consider a     */
 
115
/* "gold stars" system like in TuxMath - DSB                      */
 
116
int XMLLesson(void)
123
117
{
124
118
  SDL_Surface* titles[MAX_LESSONS] = {NULL};
125
119
  SDL_Surface* select[MAX_LESSONS] = {NULL};
127
121
  SDL_Rect leftRect, rightRect;
128
122
  SDL_Rect titleRects[8];
129
123
 
 
124
  int nchars;
 
125
  struct dirent **script_list_dirents = NULL;
 
126
  int i = 0;
 
127
  int scriptIterator = 0;  //Iterator over matching files in script dir
 
128
  int scripts = 0;         //Iterator over accepted (& parsed) script files
 
129
  int num_scripts = 0;
 
130
  char script_path[FNLEN];
 
131
  char script_filenames[MAX_LESSONS][FNLEN];
 
132
  char fn[FNLEN]; 
 
133
 
130
134
  int stop = 0;
131
135
  int loc = 0;
132
136
  int old_loc = 1;
133
 
  int num_scripts = 0;
134
137
  int found = 0;
135
 
  int i;
136
 
  char script_path[FNLEN];
137
 
  char script_filenames[MAX_LESSONS][200];
138
 
  char fn[FNLEN]; 
139
 
 
140
 
  DIR* script_dir = NULL;
141
 
  struct dirent* script_file = NULL;
142
 
 
143
 
  LOG("Entering TestLesson():\n");
 
138
 
 
139
 
 
140
  LOG("Entering XMLLesson():\n");
144
141
 
145
142
  /* First look in theme path, if desired: */
146
143
  if (!settings.use_english)
166
163
 
167
164
  if (!found)
168
165
  {
169
 
    fprintf(stderr, "TestLesson(): Error finding script directory!\n");
 
166
    fprintf(stderr, "XMLLesson(): Error finding script directory!\n");
170
167
    return 0;
171
168
  }
172
169
 
177
174
  DEBUGCODE { fprintf(stderr, "script_path is: %s\n", script_path); }
178
175
 
179
176
 
180
 
  /* FIXME looks like a place for scandir() - or our own w32_scandir() */
181
177
  /* create a list of all the .xml files */
182
 
 
183
 
  script_dir = opendir(script_path);    
184
 
 
185
 
  do
186
 
  {
187
 
    script_file = readdir(script_dir);
188
 
    if (!script_file)
189
 
      break;
190
 
 
191
 
    /* must have at least '.xml' at the end */
192
 
    if (strlen(script_file->d_name) < 5)
193
 
      continue;
194
 
 
195
 
    /* Don't show project info file: */
196
 
    if (strcmp(script_file->d_name, "projectInfo.xml") == 0)
197
 
      continue;
198
 
 
199
 
    if (strcmp(&script_file->d_name[strlen(script_file->d_name) - 4],".xml"))
200
 
      continue;
201
 
 
202
 
    sprintf(script_filenames[num_scripts], "%s", script_file->d_name);
203
 
    num_scripts++;
204
 
    DEBUGCODE { fprintf(stderr, "Adding XML file no. %d: %s\n",
205
 
                num_scripts, script_filenames[num_scripts]); }
206
 
 
207
 
  } while (1); /* Leave loop when readdir() returns NULL */
208
 
 
209
 
  closedir(script_dir); 
 
178
  num_scripts = scandir(script_path, &script_list_dirents, is_xml_file, alphasort);
 
179
 
 
180
  for (scriptIterator = 0, scripts = 0;
 
181
       scriptIterator < num_scripts && scripts < MAX_LESSONS;
 
182
       scriptIterator++)
 
183
  {
 
184
    /* Copy over the filename: */
 
185
    nchars = snprintf(script_filenames[scripts], FNLEN, "%s",
 
186
                      script_list_dirents[scriptIterator]->d_name);
 
187
 
 
188
    /* Skip (actually clobber) any invalid or undesired files: */
 
189
    if (nchars < 0 || nchars >= FNLEN)
 
190
      continue;
 
191
    /* Don't show project info file or instructions files */
 
192
    if (strcmp(script_filenames[scripts], "projectInfo.xml") == 0 ||
 
193
        strcmp(script_filenames[scripts], "laser.xml") == 0 ||
 
194
        strcmp(script_filenames[scripts], "cascade.xml") == 0)
 
195
      continue;
 
196
 
 
197
    DEBUGCODE
 
198
    {
 
199
      fprintf(stderr, "Found script file %d:\t%s\n", scripts, script_filenames[scripts]);
 
200
    }
 
201
 
 
202
    /* Increment the iterator for correctly-parsed lesson files */
 
203
    scripts++;
 
204
  }
 
205
 
 
206
//  DEBUGCODE  
 
207
  {
 
208
    fprintf(stderr, "Before undesired files screened out:\n");
 
209
    for(i = 0; i < num_scripts; i++)
 
210
      fprintf(stderr, "script %d filename: %s\n", i,
 
211
              script_list_dirents[i]->d_name);
 
212
    fprintf(stderr, "After undesired files screened out:\n");
 
213
    for(i = 0; i < scripts; i++)
 
214
      fprintf(stderr, "script %d filename: %s\n", i,
 
215
              script_filenames[i]);
 
216
  }
 
217
 
 
218
 
 
219
  /* Now free the individual dirents. We do this on a second pass */
 
220
  /* because of the "continue" approach used to error handling.   */
 
221
  for (scriptIterator = 0; scriptIterator < num_scripts; scriptIterator++)
 
222
    free(script_list_dirents[scriptIterator]);
 
223
  free(script_list_dirents);
 
224
 
 
225
  /* Adjust num_scripts for any skipped files: */
 
226
  num_scripts = scripts;
 
227
 
 
228
//START OF OLD IMPLEMENTATION
 
229
//   num_scripts = 0;
 
230
//   script_dir = opendir(script_path); 
 
231
//   do
 
232
//   {
 
233
//     script_file = readdir(script_dir);
 
234
//     if (!script_file)
 
235
//       break;
 
236
// 
 
237
//     /* must have at least '.xml' at the end */
 
238
//     if (strlen(script_file->d_name) < 5)
 
239
//       continue;
 
240
// 
 
241
//     /* Don't show project info file or instructions files */
 
242
//     if (strcmp(script_file->d_name, "projectInfo.xml") == 0 ||
 
243
//         strcmp(script_file->d_name, "laser.xml") == 0 ||
 
244
//         strcmp(script_file->d_name, "cascade.xml") == 0)
 
245
//       continue;
 
246
// 
 
247
// 
 
248
//     if (strcmp(&script_file->d_name[strlen(script_file->d_name) - 4],".xml"))
 
249
//       continue;
 
250
// 
 
251
//     sprintf(script_filenames[num_scripts], "%s", script_file->d_name);
 
252
//     num_scripts++;
 
253
//     DEBUGCODE { fprintf(stderr, "Adding XML file no. %d: %s\n",
 
254
//                 num_scripts, script_filenames[num_scripts]); }
 
255
// 
 
256
//   } while (1); /* Leave loop when readdir() returns NULL */
 
257
// 
 
258
//   closedir(script_dir);      
 
259
 
 
260
// END OF OLD IMPLEMENTATION
 
261
 
 
262
 
210
263
 
211
264
  DEBUGCODE { fprintf(stderr, "Found %d . xml file(s) in script dir\n", num_scripts); }
212
265
 
225
278
  /* Get out if needed surface not loaded successfully: */
226
279
  if (!CurrentBkgd() || !left || !right)
227
280
  {
228
 
    fprintf(stderr, "TestLesson(): needed image not available\n");
 
281
    fprintf(stderr, "XMLLesson(): needed image not available\n");
229
282
  
230
283
    for (i = 0; i < num_scripts; i++)
231
284
    {
245
298
  leftRect.w = left->w;
246
299
  leftRect.h = left->h;
247
300
  leftRect.x = screen->w/2 - 80 - (leftRect.w/2);
248
 
  leftRect.y = screen->h/2 - 50;
 
301
  leftRect.y = screen->h - 50;
249
302
 
250
 
  rightRect.w = right->w; rightRect.h = right->h;
251
 
  rightRect.x = screen->w/2 + 80 - (rightRect.w/2); rightRect.y = screen->h/2 - 50;
 
303
  rightRect.w = right->w; 
 
304
  rightRect.h = right->h;
 
305
  rightRect.x = screen->w/2 + 80 - (rightRect.w/2);
 
306
  rightRect.y = screen->h - 50;
252
307
 
253
308
  /* set initial rect sizes */
254
309
  titleRects[0].y = 30;
268
323
      switch (event.type)
269
324
      {
270
325
        case SDL_QUIT:
271
 
          exit(0); /* FIXME may need to cleanup memory and exit more cleanly */
 
326
          return 0; /* Return control to the main program so we can exit cleanly */
272
327
          break;
273
328
 
274
329
        case SDL_MOUSEMOTION:
304
359
            if (inRect(titleRects[i], event.button.x, event.button.y))
305
360
            {
306
361
              loc = loc - (loc % 8) + i;
307
 
              sprintf(fn, "%s/scripts/%s", settings.default_data_path, script_filenames[loc]);
 
362
              if(settings.use_english)
 
363
                sprintf(fn, "%s/scripts/%s", settings.default_data_path, script_filenames[loc]);
 
364
              else
 
365
                sprintf(fn, "%s/scripts/%s", settings.theme_data_path, script_filenames[loc]);
308
366
              stop = 1;
309
367
              break; 
310
368
            }
321
379
 
322
380
          if (event.key.keysym.sym == SDLK_RETURN)
323
381
          {
324
 
            sprintf(fn, "%s/scripts/%s", settings.default_data_path, script_filenames[loc]);
325
 
            stop = 1;
 
382
            if(settings.use_english)
 
383
              sprintf(fn, "%s/scripts/%s", settings.default_data_path, script_filenames[loc]);
 
384
            else
 
385
              sprintf(fn, "%s/scripts/%s", settings.theme_data_path, script_filenames[loc]);            stop = 1;
326
386
            break;
327
387
          }
328
388
 
422
482
  run_script();
423
483
  SDL_ShowCursor(1);
424
484
 
425
 
  LOG("Leave TestLesson()\n");
 
485
  LOG("Leave XMLLesson()\n");
426
486
 
427
487
  return 1;
428
488
}
542
602
    if (fscanf_result == EOF)
543
603
      break;
544
604
 
 
605
    if (strncmp("<!--", str, 4) == 0)
 
606
    {
 
607
        /* -- comment section found, ignore everything until comment close -- */
 
608
        int found = 0;
 
609
        char* tmpStr;
 
610
 
 
611
        do
 
612
        {
 
613
            // search the current line for comment end
 
614
            for ( tmpStr = str; strlen(tmpStr) >= 3 && !found; tmpStr++ )
 
615
            {    
 
616
                 if (strncmp("-->",tmpStr, 3) == 0)
 
617
                 {
 
618
                     // move past the comment end tag
 
619
                     tmpStr += 2;
 
620
                     found = 1;
 
621
                 }
 
622
            }
 
623
 
 
624
            // if the comment end was not found get another line
 
625
            if (!found)
 
626
            {
 
627
                fscanf_result = fscanf(f, "%[^\n]\n", str);
 
628
                tmpStr = str;
 
629
            }
 
630
 
 
631
            // we did find the end of the comment
 
632
            else
 
633
            {
 
634
 
 
635
                if (strlen(tmpStr) > 0)
 
636
                {
 
637
                    // copy the rest of the line into str for processing
 
638
                    strncpy(str, tmpStr, strlen(tmpStr));
 
639
                    str[strlen(tmpStr)] = '\0';
 
640
                }
 
641
                else
 
642
                {
 
643
                    // str needs another line, this one is used up
 
644
                    fscanf_result = fscanf(f, "%[^\n]\n", str);
 
645
                    tmpStr = str;
 
646
                }
 
647
                
 
648
                // if the next line is a comment, start all over again
 
649
                if (fscanf_result != EOF && strncmp("<!--", str, 4) == 0)
 
650
                {
 
651
                    found = 0;
 
652
                }
 
653
            }
 
654
 
 
655
        } while ( fscanf_result != EOF && !found );
 
656
        
 
657
        /* -- if we reached the end of the file and saw no close to the comment, generate a warning -- */
 
658
        if ( !found && fscanf_result == EOF )
 
659
        {
 
660
            fprintf(stderr, "XML Warning: End of file reached looking for the end of a comment.\n");
 
661
            break;
 
662
        }
 
663
 
 
664
        /* -- don't continue processing if at EOF -- */
 
665
        if (fscanf_result == EOF)
 
666
        {
 
667
            break;
 
668
        }
 
669
    }
 
670
 
545
671
    if (strncmp("<script", str, 7) == 0)
546
672
    {
547
673
      /* -- allocate space for the lesson info -- */
565
691
    {
566
692
      if (curScript==NULL)
567
693
      {
568
 
        fprintf(stderr, "CRITICAL XML ERROR: <page> should be in a <script> in file %s line (todo)", fn); exit(1);
 
694
        fprintf(stderr, "CRITICAL XML ERROR: <page> should be in a <script> in file %s line (todo)", fn);
 
695
        close_script();
 
696
        return 0;
569
697
      }
570
698
 
571
699
      if (curScript->pages==NULL)
600
728
    {
601
729
      if (curPage == NULL)
602
730
      {
603
 
        fprintf(stderr, "CRITICAL XML ERROR: <text> should be in a <page> in file %s line (todo)", fn); exit(1);
 
731
        fprintf(stderr, "CRITICAL XML ERROR: <text> should be in a <page> in file %s line (todo)", fn);
 
732
        close_script();
 
733
        return 0;
604
734
      }
605
735
 
606
736
      if (curPage->items == NULL) 
687
817
        fprintf(stderr,
688
818
                "CRITICAL XML ERROR: <img> should be in a <page> in file %s line (todo)",
689
819
               fn);
690
 
        exit(1); //FIXME should call cleanup() or maybe just return without exiting
 
820
        close_script();
 
821
        return 0; //Return control to the main program for a clean exit
691
822
      }
692
823
 
693
824
      if (curPage->items == NULL)
740
871
        }
741
872
      }
742
873
    }
 
874
    else if (strncmp("<bkgd", str, 5) == 0)
 
875
    {
 
876
      if (curPage == NULL)
 
877
      {
 
878
        fprintf(stderr,
 
879
                "CRITICAL XML ERROR: <bkgd> should be in a <page> in file %s line (todo)",
 
880
               fn);
 
881
        close_script();
 
882
        return 0; //Return control to the main program for a clean exit
 
883
      }
 
884
 
 
885
      if (curPage->items == NULL)
 
886
      {
 
887
        curItem = (itemType*)calloc(1, sizeof(itemType));
 
888
        curPage->items = curItem;
 
889
      }
 
890
      else 
 
891
      {
 
892
        curItem->next = (itemType*)calloc(1, sizeof(itemType));
 
893
        curItem = curItem->next;
 
894
      }
 
895
 
 
896
      curItem->type = itemBKGD;
 
897
      curItem->x = curItem->y = -1;
 
898
 
 
899
 
 
900
      for (i = 6; i < strlen(str); i++) 
 
901
      {
 
902
        if ((str[i] == 's') && strncmp("src", &str[i], 3) == 0)
 
903
          curItem->data = get_quote(&str[i + 3]);
 
904
      }
 
905
    }
 
906
 
743
907
    else if (strncmp("<wav", str, 4) == 0)
744
908
    {
745
909
      if (curPage == NULL)
747
911
        fprintf(stderr,
748
912
                "CRITICAL XML ERROR: <wav> should be in a <page> in file %s line (todo)",
749
913
                fn);
750
 
        exit(1);  /* FIXME call Cleanup() to exit */
 
914
        close_script();
 
915
        return 0;  /* Return control to main program for a clean exit */
751
916
      }
752
917
 
753
918
      if (curPage->items == NULL)
788
953
      {
789
954
        fprintf(stderr,
790
955
                "CRITICAL XML ERROR: <prac> should be in a <page> in file %s line (todo)",
 
956
 
791
957
                fn);
792
 
        exit(1); /* FIXME call cleanup() rather than exit() */
 
958
        close_script();
 
959
        return 0; /* Return control to the main program for a clean exit */
793
960
      }
794
961
 
795
962
      if (curPage->items == NULL)
870
1037
        fprintf(stderr,
871
1038
               "CRITICAL XML ERROR: <waitforinput> should be in a <page> in file %s line (todo)",
872
1039
                fn);
873
 
        exit(1);
 
1040
        close_script();
 
1041
        return 0;
874
1042
      }
875
1043
 
876
1044
      if (curPage->items == NULL)
894
1062
        fprintf(stderr,
895
1063
               "CRITICAL XML ERROR: <waitforchar> should be in a <page> in file %s line (todo)",
896
1064
               fn);
897
 
        exit(1);
 
1065
        close_script();
 
1066
        return 0;
898
1067
      }
899
1068
 
900
1069
      if (curPage->items == NULL)
927
1096
}
928
1097
 
929
1098
 
 
1099
 
 
1100
 
930
1101
static void run_script(void)
931
1102
{
932
1103
  /* FIXME FNLEN doesn't make sense for size of these arrays */
965
1136
    if (curPage->background)
966
1137
    {
967
1138
      SDL_Surface* img = LoadImage(curPage->background, IMG_ALPHA|IMG_NOT_REQUIRED);
968
 
      SDL_BlitSurface(img, NULL, screen, NULL);
 
1139
 
 
1140
      /* hack: since this is the background it needs to scale when in fullscreen
 
1141
       * but shouldn't every image scale when in fullscreen? assuming svg is for that... -MDT */
 
1142
      if (settings.fullscreen)
 
1143
      {
 
1144
        SDL_Surface* fsimg = zoom(img, fs_res_x, fs_res_y);
 
1145
        SDL_BlitSurface(fsimg, NULL, screen, NULL);
 
1146
        SDL_FreeSurface(fsimg);
 
1147
      }
 
1148
      else
 
1149
      { 
 
1150
        SDL_BlitSurface(img, NULL, screen, NULL);
 
1151
      } 
 
1152
 
969
1153
      SDL_FreeSurface(img);
 
1154
 
970
1155
    }
971
1156
    else if (curScript->background)
972
1157
    {
973
1158
      SDL_Surface* img = LoadImage(curScript->background, IMG_ALPHA|IMG_NOT_REQUIRED);
974
 
      SDL_BlitSurface(img, NULL, screen, NULL);
 
1159
 
 
1160
      /* hack: since this is the background it needs to scale when in fullscreen -MDT */
 
1161
      if (settings.fullscreen)
 
1162
      { 
 
1163
        SDL_Surface* fsimg = zoom(img, fs_res_x, fs_res_y);
 
1164
        SDL_BlitSurface(fsimg, NULL, screen, NULL);
 
1165
        SDL_FreeSurface(fsimg);
 
1166
      }
 
1167
      else
 
1168
      { 
 
1169
        SDL_BlitSurface(img, NULL, screen, NULL);
 
1170
      } 
 
1171
 
975
1172
      SDL_FreeSurface(img);
976
1173
    }
977
1174
 
1036
1233
              clickRects[numClicks].h = loc.h;
1037
1234
              numClicks++;
1038
1235
            }
1039
 
          }
1040
 
          SDL_FreeSurface(img);
 
1236
 
 
1237
            SDL_FreeSurface(img);
 
1238
          }
 
1239
          break;
 
1240
        }
 
1241
 
 
1242
        case itemBKGD:
 
1243
        {
 
1244
          SDL_Surface* img = LoadImage(curItem->data, IMG_ALPHA|IMG_NOT_REQUIRED);
 
1245
          if (img)
 
1246
          {
 
1247
            /* hack: since this is the background it needs to scale when in fullscreen -MDT */
 
1248
            if (settings.fullscreen)
 
1249
            {
 
1250
              SDL_Surface* fsimg = zoom(img, fs_res_x, fs_res_y);
 
1251
              SDL_BlitSurface(fsimg, NULL, screen, NULL);
 
1252
              SDL_FreeSurface(fsimg);
 
1253
            }
 
1254
            else
 
1255
            {
 
1256
              SDL_BlitSurface(img, NULL, screen, NULL);
 
1257
            }
 
1258
            SDL_FreeSurface(img);
 
1259
          }
1041
1260
          break;
1042
1261
        }
1043
1262
 
1081
1300
                continue;
1082
1301
 
1083
1302
              tmp[toshow] = 0;
 
1303
 
1084
1304
              img = SimpleText(tmp, (int)curItem->size, col);
 
1305
 
1085
1306
              if (img)
1086
1307
              { 
1087
1308
                if (img->w + 20 < screen->w)
1142
1363
        {
1143
1364
          // HACK, we need to make sure no more than 8 sounds or so..
1144
1365
          sounds[numWavs] = LoadSound( curItem->data );
1145
 
          Mix_PlayChannel( numWavs, sounds[numWavs], -curItem->loop );
 
1366
 
 
1367
          // let audio.c handle calls to SDL_mixer
 
1368
          //Mix_PlayChannel( numWavs, sounds[numWavs], -curItem->loop );
 
1369
          
 
1370
          PlaySoundLoop( sounds[numWavs], -curItem->loop );
1146
1371
          numWavs++;
1147
1372
          break;
1148
1373
        }
1170
1395
                  for (j=0; j<numClicks; j++) 
1171
1396
                  {
1172
1397
                    if (inRect(clickRects[j], event.button.x, event.button.y))
1173
 
                     Mix_PlayChannel(numWavs + j, clickWavs[j], 0);
 
1398
                     PlaySound( clickWavs[j] );
 
1399
                     // let audio.c handle calls to SDL_mixer
 
1400
                     //Mix_PlayChannel(numWavs + j, clickWavs[j], 0);
1174
1401
                  }
1175
1402
                  break;
1176
1403
                }
1306
1533
 
1307
1534
      if (settings.sys_sound)
1308
1535
      {
 
1536
        // halt all the channels before we try to free the sounds
 
1537
        audioHaltChannel(-1);
 
1538
 
1309
1539
        for (i=0; i<numWavs; i++)
1310
1540
        {
1311
 
          Mix_HaltChannel(i);
 
1541
          // let audio.c handle calls to SDL_mixer
 
1542
          //Mix_HaltChannel(i);
 
1543
 
1312
1544
          Mix_FreeChunk(sounds[i]);
1313
1545
        }
1314
1546
 
1315
1547
        for (i = 0; i < numClicks; i++)
1316
1548
        {
1317
 
          Mix_HaltChannel(i + numWavs);
 
1549
          // let audio.c handle calls to SDL_mixer
 
1550
          //Mix_HaltChannel(i + numWavs);
 
1551
 
1318
1552
          Mix_FreeChunk(clickWavs[i]);
1319
1553
        }
1320
1554
      }
1395
1629
}
1396
1630
 
1397
1631
 
1398
 
 
1399
 
 
 
1632
/* NOTE we just check to see if the name ends in ".xml", but we don't */
 
1633
/* verify that it really contains XML.                                */
 
1634
static int is_xml_file(const struct dirent* xml_dirent)
 
1635
{
 
1636
  const char* ending = &xml_dirent->d_name[strlen(xml_dirent->d_name) - 4]; 
 
1637
  return (0 == strncasecmp(ending, ".xml", 4));
 
1638
}