@@ -156,15 +156,54 @@ void gui_draw(Synth *synth, SDL_Window *window, SDL_GLContext gl_context,
156156 ImGui::SetNextWindowSize (ImVec2 ((float )window_width, (float )window_height), ImGuiCond_Always);
157157 ImGui::Begin (" Synth" , NULL , ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoBringToFrontOnFocus);
158158
159+ // Oscilloscope
160+ if (ImGui::CollapsingHeader (" Oscilloscope" , ImGuiTreeNodeFlags_DefaultOpen)) {
161+ // Set fixed height of 200 pixels, use full available width
162+ ImGui::PushStyleVar (ImGuiStyleVar_ChildBorderSize, 0 .0f );
163+ ImGui::BeginChild (" OscilloscopeChild" , ImVec2 (0 , 200 ), false , ImGuiWindowFlags_NoScrollbar);
164+ ImVec2 content_size = ImGui::GetContentRegionAvail ();
165+ if (content_size.x > 0 && content_size.y > 0 ) {
166+ if ((int )content_size.x != osc_width || 200 != osc_height) {
167+ // Recreate resources if size has changed
168+ if (g_oscilloscope_renderer) SDL_DestroyRenderer (g_oscilloscope_renderer);
169+ if (g_oscilloscope_surface) SDL_FreeSurface (g_oscilloscope_surface);
170+ if (g_oscilloscope_gl_texture) glDeleteTextures (1 , &g_oscilloscope_gl_texture);
171+
172+ osc_width = (int )content_size.x ;
173+ osc_height = 200 ; // Fixed height of 200 pixels
174+
175+ g_oscilloscope_surface = SDL_CreateRGBSurfaceWithFormat (0 , osc_width, osc_height, 32 , SDL_PIXELFORMAT_RGBA32);
176+ g_oscilloscope_renderer = SDL_CreateSoftwareRenderer (g_oscilloscope_surface);
177+
178+ glGenTextures (1 , &g_oscilloscope_gl_texture);
179+ glBindTexture (GL_TEXTURE_2D, g_oscilloscope_gl_texture);
180+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
181+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
182+ glTexImage2D (GL_TEXTURE_2D, 0 , GL_RGBA, osc_width, osc_height, 0 , GL_RGBA, GL_UNSIGNED_BYTE, NULL );
183+ }
184+
185+ if (g_oscilloscope_renderer && g_oscilloscope_surface && g_oscilloscope_gl_texture && g_font) {
186+ SDL_SetRenderDrawColor (g_oscilloscope_renderer, 0 , 0 , 0 , 0 );
187+ SDL_RenderClear (g_oscilloscope_renderer);
188+ oscilloscope_draw (g_oscilloscope_renderer, synth, 0 , 0 , osc_width, osc_height, g_font);
189+
190+ glBindTexture (GL_TEXTURE_2D, g_oscilloscope_gl_texture);
191+ glTexSubImage2D (GL_TEXTURE_2D, 0 , 0 , 0 , osc_width, osc_height, GL_RGBA, GL_UNSIGNED_BYTE, g_oscilloscope_surface->pixels );
192+
193+ ImGui::Image ((void *)(intptr_t )g_oscilloscope_gl_texture, ImVec2 ((float )osc_width, (float )osc_height));
194+ }
195+ }
196+ ImGui::EndChild ();
197+ ImGui::PopStyleVar ();
198+ }
199+
159200 // Oscillators
160201 if (ImGui::CollapsingHeader (" Oscillators" , ImGuiTreeNodeFlags_DefaultOpen)) {
161202 ImGui::Columns (2 , " osc_columns" , true );
162203 for (int i = 0 ; i < 6 ; ++i) {
163204 ImGui::PushID (i);
164205 char title[32 ];
165206 sprintf (title, " OSC %d" , i + 1 );
166- if (i == 4 ) sprintf (title, " BASS" );
167- if (i == 5 ) sprintf (title, " PERC" );
168207
169208 ImGui::BeginChild (title, ImVec2 (0 , 200 ), true , 0 );
170209 ImGui::Text (" %s" , title);
@@ -188,14 +227,21 @@ void gui_draw(Synth *synth, SDL_Window *window, SDL_GLContext gl_context,
188227
189228 ImGui::EndChild ();
190229 ImGui::PopID ();
191- if (i % 2 != 0 ) {
192- ImGui::NextColumn ();
193- }
230+ ImGui::NextColumn ();
194231 }
195232 ImGui::Columns (1 , " " , false );
196233
234+ // Oscillator randomization buttons
235+ ImGui::Separator ();
236+
237+ // Randomize All button spanning full width
238+ if (ImGui::Button (" Randomize All OSCs" , ImVec2 (-1 , 0 ))) {
239+ synth_randomize_parameters (synth);
240+ }
241+
197242 // Individual oscillator randomization buttons
198- ImGui::Columns (4 , " random_buttons" , true );
243+ ImGui::Columns (6 , " random_buttons" , true );
244+
199245 if (ImGui::Button (" Randomize OSC 1" )) {
200246 synth_randomize_oscillator (synth, 0 );
201247 }
@@ -211,11 +257,15 @@ void gui_draw(Synth *synth, SDL_Window *window, SDL_GLContext gl_context,
211257 if (ImGui::Button (" Randomize OSC 4" )) {
212258 synth_randomize_oscillator (synth, 3 );
213259 }
214- ImGui::Columns (1 , " " , false );
215-
216- if (ImGui::Button (" Randomize All Oscillators" )) {
217- synth_randomize_parameters (synth);
260+ ImGui::NextColumn ();
261+ if (ImGui::Button (" Randomize OSC 5" )) {
262+ synth_randomize_oscillator (synth, 4 );
263+ }
264+ ImGui::NextColumn ();
265+ if (ImGui::Button (" Randomize OSC 6" )) {
266+ synth_randomize_oscillator (synth, 5 );
218267 }
268+ ImGui::Columns (1 , " " , false );
219269 }
220270
221271 // ADSR Envelope
@@ -317,7 +367,7 @@ void gui_draw(Synth *synth, SDL_Window *window, SDL_GLContext gl_context,
317367 if (ImGui::CollapsingHeader (" LFOs" , ImGuiTreeNodeFlags_DefaultOpen)) {
318368 ImGui::Columns (3 , " lfo_columns" , true );
319369
320- const char * lfo_names[] = {" Pitch LFO " , " Volume LFO " , " Filter LFO " };
370+ const char * lfo_names[] = {" Pitch" , " Volume" , " Filter" };
321371 const char * waveforms[] = {" SINE" , " TRIANGLE" , " SQUARE" , " SAW" , " RANDOM" };
322372 const char * sync_modes[] = {" Free" , " Retrigger" , " Keyfollow" };
323373
@@ -784,42 +834,6 @@ void gui_draw(Synth *synth, SDL_Window *window, SDL_GLContext gl_context,
784834 ImGui::Columns (1 , " " , false );
785835 }
786836
787- // Oscilloscope
788- ImGui::Begin (" Oscilloscope" );
789- ImVec2 content_size = ImGui::GetContentRegionAvail ();
790- if (content_size.x > 0 && content_size.y > 0 ) {
791- if ((int )content_size.x != osc_width || (int )content_size.y != osc_height) {
792- // Recreate resources if size has changed
793- if (g_oscilloscope_renderer) SDL_DestroyRenderer (g_oscilloscope_renderer);
794- if (g_oscilloscope_surface) SDL_FreeSurface (g_oscilloscope_surface);
795- if (g_oscilloscope_gl_texture) glDeleteTextures (1 , &g_oscilloscope_gl_texture);
796-
797- osc_width = (int )content_size.x ;
798- osc_height = (int )content_size.y ;
799-
800- g_oscilloscope_surface = SDL_CreateRGBSurfaceWithFormat (0 , osc_width, osc_height, 32 , SDL_PIXELFORMAT_RGBA32);
801- g_oscilloscope_renderer = SDL_CreateSoftwareRenderer (g_oscilloscope_surface);
802-
803- glGenTextures (1 , &g_oscilloscope_gl_texture);
804- glBindTexture (GL_TEXTURE_2D, g_oscilloscope_gl_texture);
805- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
806- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
807- glTexImage2D (GL_TEXTURE_2D, 0 , GL_RGBA, osc_width, osc_height, 0 , GL_RGBA, GL_UNSIGNED_BYTE, NULL );
808- }
809-
810- if (g_oscilloscope_renderer && g_oscilloscope_surface && g_oscilloscope_gl_texture && g_font) {
811- SDL_SetRenderDrawColor (g_oscilloscope_renderer, 0 , 0 , 0 , 0 );
812- SDL_RenderClear (g_oscilloscope_renderer);
813- oscilloscope_draw (g_oscilloscope_renderer, synth, 0 , 0 , osc_width, osc_height, g_font);
814-
815- glBindTexture (GL_TEXTURE_2D, g_oscilloscope_gl_texture);
816- glTexSubImage2D (GL_TEXTURE_2D, 0 , 0 , 0 , osc_width, osc_height, GL_RGBA, GL_UNSIGNED_BYTE, g_oscilloscope_surface->pixels );
817-
818- ImGui::Image ((void *)(intptr_t )g_oscilloscope_gl_texture, ImVec2 ((float )osc_width, (float )osc_height));
819- }
820- }
821- ImGui::End ();
822-
823837 // Pattern / Melody
824838 if (ImGui::CollapsingHeader (" Pattern / Melody" , ImGuiTreeNodeFlags_DefaultOpen)) {
825839 ImGui::Columns (2 , " pattern_columns" , true );
0 commit comments