Free Hero Mesh

Check-in [c144d8069c]
Login
This is a mirror of the main repository for Free Hero Mesh. New tickets and changes will not be accepted at this mirror.
Overview
Comment:Begin to implement sounds; it is currently unused and is not fully implemented, nor tested yet.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: c144d8069ceb2e46154ace59fc81131f65fb7a08
User & Date: user on 2021-04-02 07:08:41
Other Links: manifest | tags
Context
2021-04-02
19:32
Implement diagonal shoving. check-in: 57d6d9a4f7 user: user tags: trunk
07:08
Begin to implement sounds; it is currently unused and is not fully implemented, nor tested yet. check-in: c144d8069c user: user tags: trunk
2021-04-01
19:07
Mention that contributions of documentation in languages other than English are not required to use the PC haracter set, and may use whatever character set is appropriate. check-in: 63c71e1a57 user: user tags: trunk
Changes

Modified quarks from [070f56c8ad] to [89b36181b9].

22
23
24
25
26
27
28
29
30
31
32
33
34






35
36
37
38
39
40
41
22
23
24
25
26
27
28






29
30
31
32
33
34
35
36
37
38
39
40
41







-
-
-
-
-
-
+
+
+
+
+
+







!  'n' = NOFRAME
!  'p' = HWPALETTE
!  'r' = RESIZABLE
!  'y' = ASYNCBLIT
!  'z' = NOPARACHUTE

! Audio
sfxVolume
audioBuffer
audioRate
audioFormat
musicVolume
musicFile
audio
rate
buffer
mmlVolume
waveVolume
standardSounds

! Keyboard
keyRepeat
editKey
gameKey

! Key codes

Modified quarks.h from [37ad5affad] to [b213ef7a95].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17






18
19
20
21
22
23
24
1
2
3
4
5
6
7
8
9
10
11






12
13
14
15
16
17
18
19
20
21
22
23
24











-
-
-
-
-
-
+
+
+
+
+
+







#define Q_screenWidth 2
#define Q_screenHeight 3
#define Q_margin 4
#define Q_palette 5
#define Q_popupColors 6
#define Q_imageSize 7
#define Q_altImage 8
#define Q_editTitle 9
#define Q_gameTitle 10
#define Q_gamma 11
#define Q_screenFlags 12
#define Q_sfxVolume 13
#define Q_audioBuffer 14
#define Q_audioRate 15
#define Q_audioFormat 16
#define Q_musicVolume 17
#define Q_musicFile 18
#define Q_audio 13
#define Q_rate 14
#define Q_buffer 15
#define Q_mmlVolume 16
#define Q_waveVolume 17
#define Q_standardSounds 18
#define Q_keyRepeat 19
#define Q_editKey 20
#define Q_gameKey 21
#define Q_backspace 22
#define Q_tab 23
#define Q_clear 24
#define Q_return 25
192
193
194
195
196
197
198
199
200
201


202
203
204




205
206
207
208
209
210
211
192
193
194
195
196
197
198



199
200



201
202
203
204
205
206
207
208
209
210
211







-
-
-
+
+
-
-
-
+
+
+
+







  "popupColors",
  "imageSize",
  "altImage",
  "editTitle",
  "gameTitle",
  "gamma",
  "screenFlags",
  "sfxVolume",
  "audioBuffer",
  "audioRate",
  "audio",
  "rate",
  "audioFormat",
  "musicVolume",
  "musicFile",
  "buffer",
  "mmlVolume",
  "waveVolume",
  "standardSounds",
  "keyRepeat",
  "editKey",
  "gameKey",
  "backspace",
  "tab",
  "clear",
  "return",

Added sound.c version [588b432299].
















































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#if 0
gcc ${CFLAGS:--s -O2} -c -Wno-unused-result sound.c `sdl-config --cflags`
exit
#endif

#include "SDL.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sqlite3.h"
#include "smallxrm.h"
#include "quarks.h"
#include "heromesh.h"

typedef struct {
  Uint8*data;
  Uint32 len; // length in bytes
} WaveSound;

static Uint8 sound_on;
static Sint16 mmlvolume=32767;
static SDL_AudioSpec spec;
static WaveSound*standardsounds;
static Uint16 nstandardsounds;
static WaveSound*usersounds;
static Uint16 nusersounds;
static FILE*l_fp;
static long l_offset,l_size;
static float wavevolume=1.0;
static Uint8 needs_amplify=0;

static Uint8*volatile wavesound;
static volatile Uint32 wavelen;

static void audio_callback(void*userdata,Uint8*stream,int len) {
  if(wavesound) {
    if(wavelen<len) {
      memset(stream+wavelen,0,len-wavelen);
      wavesound=0;
      wavelen=0;
    } else {
      memcpy(stream,wavesound,len);
      wavesound+=len;
      len-=len;
    }
  } else {
    memset(stream,0,len);
  }
}

static int my_seek(SDL_RWops*cxt,int o,int w) {
  switch(w) {
    case RW_SEEK_SET: fseek(l_fp,l_offset+o,SEEK_SET); break;
    case RW_SEEK_CUR: fseek(l_fp,o,SEEK_CUR); break;
    case RW_SEEK_END: fseek(l_fp,l_offset-o,SEEK_SET); break;
  }
  return ftell(l_fp)-l_offset;
}

static int my_read(SDL_RWops*cxt,void*ptr,int size,int maxnum) {
  if(size*maxnum+l_offset>ftell(l_fp)+l_size) maxnum=(ftell(l_fp)-l_offset)/size;
  return fread(ptr,size,maxnum,l_fp);
}

static int my_close(SDL_RWops*cxt) {
  return 0;
}

static SDL_RWops my_rwops={
  .seek=my_seek,
  .read=my_read,
  .close=my_close,
};

static void amplify_wave_sound(const WaveSound*ws) {
  Uint32 n;
  Sint16*b=(Sint16*)ws->data;
  Uint32 m=ws->len/sizeof(Sint16);
  if(!needs_amplify || !b) return;
  for(n=0;n<m;n++) b[n]*=wavevolume;
}

static void load_sound(FILE*fp,long offset,long size,WaveSound*ws) {
  SDL_AudioSpec src;
  SDL_AudioCVT cvt;
  Uint32 len=0;
  Uint8*buf=0;
  ws->data=0;
  ws->len=0;
  l_fp=fp;
  l_offset=offset;
  l_size=size;
  if(!SDL_LoadWAV_RW(&my_rwops,0,&src,&buf,&len)) {
    //fprintf(stderr,"[Cannot load wave audio at %ld (%ld bytes): %s]\n",offset,size,SDL_GetError());
    return;
  }
  memset(&cvt,0,sizeof(SDL_AudioCVT));
  if(SDL_BuildAudioCVT(&cvt,src.format,src.channels,src.freq,spec.format,spec.channels,spec.freq)<0) goto fail;
  cvt.buf=malloc(len*cvt.len_mult);
  cvt.len=len;
  if(!cvt.buf) goto fail;
  memcpy(cvt.buf,buf,len);
  if(SDL_ConvertAudio(&cvt)) goto fail;
  SDL_FreeWAV(buf);
  ws->data=cvt.buf;
  ws->len=cvt.len;
  amplify_wave_sound(ws);
  return;
  fail:
  //fprintf(stderr,"[Failed to convert wave audio at %ld (%ld bytes)]\n",offset,size);
  SDL_FreeWAV(buf);
}

void init_sound(void) {
  const char*v;
  optionquery[1]=Q_audio;
  optionquery[2]=Q_rate;
  v=xrm_get_resource(resourcedb,optionquery,optionquery,3);
  if(!v) return;
  spec.freq=strtol(v,0,10);
  optionquery[2]=Q_buffer;
  v=xrm_get_resource(resourcedb,optionquery,optionquery,3);
  if(!v) return;
  spec.samples=strtol(v,0,10);
  if(!spec.freq || !spec.samples) return;
  fprintf(stderr,"Initializing audio...\n");
  spec.channels=1;
  spec.format=AUDIO_S16SYS;
  spec.callback=audio_callback;
  if(SDL_InitSubSystem(SDL_INIT_AUDIO)) {
    fprintf(stderr,"Cannot initalize audio subsystem.\n");
    return;
  }
  if(SDL_OpenAudio(&spec,0)) {
    fprintf(stderr,"Cannot open audio device.\n");
    return;
  }
  optionquery[2]=Q_waveVolume;
  if(v=xrm_get_resource(resourcedb,optionquery,optionquery,3)) {
    needs_amplify=1;
    wavevolume=strtod(v,0);
  }
  
  fprintf(stderr,"Done.\n");
  wavesound=0;
  SDL_PauseAudio(0);
  sound_on=1;
}

void set_sound_effect(Value v1,Value v2) {
  if(!sound_on) return;
  if(!v2.t && !v2.u && wavesound) return;
  SDL_LockAudio();
  wavesound=0;
  switch(v1.t) {
    case TY_SOUND:
      if(v1.u<nstandardsounds) {
        wavesound=standardsounds[v1.u].data;
        wavelen=standardsounds[v1.u].len;
      }
      break;
    case TY_USOUND:
      if(v1.u<nusersounds) {
        wavesound=usersounds[v1.u].data;
        wavelen=usersounds[v1.u].len;
      }
      break;
    case TY_STRING: case TY_LEVELSTRING:
      if(!mmlvolume) break;
      
      break;
  }
  SDL_UnlockAudio();
}