//############################################################################
//
// LaserBoy !!!
//
// by James Lehman
// Extra Stimulus Inc.
// james@akrobiz.com
//
// began: October 2003
//
// Copyright 2003 to 2024 James Lehman.
// This source is distributed under the terms of the GNU General Public License.
//
// LaserBoy_space.hpp is part of LaserBoy.
//
// LaserBoy is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// LaserBoy is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with LaserBoy. If not, see .
//
//############################################################################
#ifndef __LASERBOY_SPACE_DEFINITIONS__
#define __LASERBOY_SPACE_DEFINITIONS__
//############################################################################
#include "LaserBoy_frame_set.hpp"
#include "LaserBoy_palette_set.hpp"
//############################################################################
class LaserBoy_SDL_GUI;
//############################################################################
class LaserBoy_settings
{
public:
LaserBoy_settings()
: bg_file_name ("." ) // string
, install_GUID (GUID8char() ) // string
, effect_name ( ) // string
, working_directory ( ) // string
, working_subdirectory ( ) // string
, file_name ( ) // string
, font_name ("laserellipse") // string
, current_extension ( ) // string
, wav_channel_map ("XYrgbi" ) // string
, bg_color ( 0, 0, 0) // LaserBoy_color
, mono_text ( 0, 128, 0) // LaserBoy_color
, rendered_bounds (160, 160, 160) // LaserBoy_color
, rendered_clipping (255, 0, 0) // LaserBoy_color
, rendered_blank (128, 128, 128) // LaserBoy_color
, rendered_black ( 16, 16, 16) // LaserBoy_color
, fulcrum ( ) // LaserBoy_3D_double
, view_angle ( ) // LaserBoy_3D_double
, view_scale (1.0 ) // LaserBoy_3D_double
, view_offset ( ) // LaserBoy_3D_double
, view_has_changed (false ) // bool
, rainbow_menus (true )
, move_menu (false )
, alt_menu_c (false )
, alt_menu_h (false )
, alt_menu_k (false )
, alt_menu_l (false )
, show_vectors (true )
, show_vertices (false )
, show_blanking (false )
, show_intro (false )
, show_bridge (false )
, show_coda (false )
, show_cursors (false )
, show_direction (false )
, show_color_cursor (false )
, show_fixed_bounds (false )
, show_fixed_origin (false )
, show_floating_axis (false )
, show_floating_bounds (true )
, infinite_vector (true )
, end_vect_to_delta_max (false )
, destructive_clipping (false )
, show_fulcrum (false )
, show_indices (false )
, show_effects_generation (false )
, show_background_bitmap (true )
, background_bmp_negative (false )
, show_onion_skin (false )
, show_onion_visuals (false )
, show_menu (true )
, show_palette (false )
, show_target_palette (false )
, show_stats (true )
, show_TUI_clue (true )
, track_bmp_view (true )
, show_frame_stats (false )
, show_frame_set_stats (false )
, show_Z_as_order (false )
, show_quad_view (false )
, show_cursor_limits_msg (true )
, ui_visuals_flip_flop (true )
, loop_animation (true )
, approximate_frame_rate (true )
, wav_show_vertices (false )
, wav_show_blanks (false )
, wav_real_time (true )
, wav_show_inverted (true )
, wav_clean_screen (true )
, wav_loop (false )
, auto_scale_dxf (true )
, maintain_real_origin (false )
, save_true_color_dxf (false )
, black_dwell_vertices (false )
, auto_flatten_z (true )
, no_equivalent_vectors (false )
, conglomerate_in_minimize (false )
, fracture_b4_conglomerate (false )
, invert_wav_output (true )
, maintain_first_anchor (false )
, auto_minimize (false )
, auto_opti_ctn (false )
, auto_apply_offsets (true )
, auto_apply_rescales (false )
, no_black_match (true )
, allow_lit_black (true )
, save_2D_as_3D (false )
, save_1_frame_bridge (false )
, save_ild_fmt_4_5 (false )
, save_txt_with_color (false )
, save_txt_unit (false )
, save_txt_color_hex (false )
, save_txt_named_palettes (false )
, bond_word (false )
, black_level (0 ) // int
, number_of_skins (4 ) // int
, sample_rate (48000 ) // int Hz
, lit_dwell_overhang (2 ) // vertices
, dots_setting (LASERBOY_DOTS_IGNORE)
, recolor_index_multiple (1 ) // color index
, output_bmp_size (1000 ) // pixels square
, transparent_menu_font (0 )
, font_size_factor (1 )
, rendered_line_width (1 )
, wav_channel_i (LASERBOY_SIGNAL_MONO_OR_ANALOG)
, unframed_wav_stride (4800 ) // samples 1/10 of sec
, app_runs_count (1 )
, displacement_step (100 ) // int points
, color_frame_shift (1 )
, bmp_file_index (-1 ) // no bmp dir loaded
, lit_delta_max (800 ) // points
, blank_delta_max (1000 ) // points
, max_dwell_microsec (333 ) // microseconds
, max_wag_microsec (50000.0 ) // double 1/20th second
, dwell_on_dot (10.00 ) // vertices
, color_delay_microsec (100.00 ) // aprox -5/48KHz
, insignificant_distance (0.0 ) // points
, insignificant_angle (one_degree ) // radians
, recolor_span_factor (1.0 )
, onion_skin_fade (0.70 ) // ratio 0.0 ~ 1.0
, background_bmp_scale (1.00 )
, rendered_arc_angle (6.0 ) // degrees
, rendered_mono_font_space (0.70 ) // percent of glyph space
, rendered_vari_font_gap (0.20 ) // percent of glyph space
, rendered_vari_font_space (0.50 ) // percent of glyph space
, frames_per_second (16.0 ) // 0 == every frame is shown exactly once
, still_frame_duration (10.0 ) // seconds
, rotation_step (one_degree ) // radians
, magnitude_step (0.01 )
, magnitude_step_up (1.01 )
, magnitude_step_dn (0.99 )
{};
//------------------------------------------------------------------------
~LaserBoy_settings ()
{};
//------------------------------------------------------------------------
bool load_wtf_file (string wtf_file);
bool save_wtf_file (string wtf_file);
//------------------------------------------------------------------------
string bg_file_name ,
install_GUID ,
effect_name ,
color_rescale_file[4], // txt file names for each color channel
working_directory,
working_subdirectory,
file_name,
font_name,
current_extension,
absolute_path_of_LaserBoy,
wav_channel_map;
LaserBoy_color bg_color ,
mono_text ,
rendered_bounds ,
rendered_clipping,
rendered_blank ,
rendered_black ;
LaserBoy_3D_double fulcrum ,
view_angle ,
view_scale ,
view_offset ;
bool view_has_changed ,
rainbow_menus ,
move_menu ,
alt_menu_c ,
alt_menu_h ,
alt_menu_k ,
alt_menu_l ,
show_vectors ,
show_vertices ,
show_blanking ,
show_intro ,
show_bridge ,
show_coda ,
show_cursors ,
show_direction ,
show_color_cursor ,
show_fixed_bounds ,
show_fixed_origin ,
show_floating_axis ,
show_floating_bounds ,
infinite_vector ,
end_vect_to_delta_max ,
destructive_clipping ,
show_fulcrum ,
show_indices ,
show_effects_generation ,
show_background_bitmap ,
background_bmp_negative ,
show_onion_skin ,
show_onion_visuals ,
show_menu ,
show_palette ,
show_target_palette ,
show_stats ,
show_TUI_clue ,
track_bmp_view ,
show_frame_stats ,
show_frame_set_stats ,
show_Z_as_order ,
show_quad_view ,
show_cursor_limits_msg ,
ui_visuals_flip_flop ,
loop_animation ,
approximate_frame_rate ,
wav_show_vertices ,
wav_show_blanks ,
wav_real_time ,
wav_show_inverted ,
wav_clean_screen ,
wav_loop ,
auto_scale_dxf ,
maintain_real_origin ,
save_true_color_dxf ,
black_dwell_vertices ,
auto_flatten_z ,
no_equivalent_vectors ,
conglomerate_in_minimize ,
fracture_b4_conglomerate ,
invert_wav_output ,
maintain_first_anchor ,
auto_minimize ,
auto_opti_ctn ,
auto_apply_offsets ,
auto_apply_rescales ,
no_black_match ,
allow_lit_black ,
save_2D_as_3D ,
save_1_frame_bridge ,
save_ild_fmt_4_5 ,
save_txt_with_color ,
save_txt_unit ,
save_txt_color_hex ,
save_txt_named_palettes ,
bond_word ;
u_int black_level ,
number_of_skins ,
sample_rate ,
lit_dwell_overhang ,
dots_setting ,
recolor_index_multiple ,
output_bmp_size ,
transparent_menu_font ,
font_size_factor ,
rendered_line_width ,
wav_channel_i ,
unframed_wav_stride ,
app_runs_count ,
signal_bit_mask [7]; // XYZrgbi number of bits to mask from the LSB end
int displacement_step ,
color_frame_shift ,
bmp_file_index ,
signal_polarity [7], // -1 unknown, 0 positive, 1 negative
wav_offsets [7]; // in samples
double lit_delta_max ,
blank_delta_max ,
max_dwell_microsec ,
max_wag_microsec ,
dwell_on_dot ,
color_delay_microsec ,
insignificant_distance ,
insignificant_angle ,
recolor_span_factor ,
onion_skin_fade ,
background_bmp_scale ,
rendered_arc_angle , // in degrees
rendered_mono_font_space ,
rendered_vari_font_gap ,
rendered_vari_font_space ,
frames_per_second ,
still_frame_duration ,
rotation_step , // in radians!
magnitude_step ,
magnitude_step_up ,
magnitude_step_dn ;
};
//############################################################################
class LaserBoy_space : public LaserBoy_settings,
public LaserBoy_frame_set,
public LaserBoy_palette_set
{
public:
LaserBoy_space(LaserBoy_SDL_GUI* gui);
//------------------------------------------------------------------------
~LaserBoy_space()
{
bmp_free (&bmp);
bmp_free (&background);
bmp_free (&background_bmp_2D);
bmp_free (&background_bmp_3D);
LaserBoy_frame_set::clear();
LaserBoy_palette_set::clear();
}
//------------------------------------------------------------------------
LaserBoy_frame& operator [] (int index) // does not set frame_index
{ // eliminates ambiguity of space being
if(number_of_frames()) // both a frame_set and palette set
{
if(index >= (int)number_of_frames())
index = 0;
if(index < 0)
index = number_of_frames() - 1;
return LaserBoy_frame_set::at(index);
}
return null_frame;
}
//------------------------------------------------------------------------
LaserBoy_space& operator = (const LaserBoy_frame_set& frames)
{
LaserBoy_frame_set::clear();
LaserBoy_frame_set::insert(LaserBoy_frame_set::end(),
frames.begin(), frames.end()
);
LaserBoy_frame_set::shrink_to_fit();
return *this;
}
//------------------------------------------------------------------------
LaserBoy_space& operator += (const LaserBoy_frame_set& frames)
{
LaserBoy_frame_set::insert(LaserBoy_frame_set::end(),
frames.begin(), frames.end()
);
LaserBoy_frame_set::shrink_to_fit();
return *this;
}
//------------------------------------------------------------------------
LaserBoy_space& operator += (const LaserBoy_frame& frame)
{
LaserBoy_frame_set::push_back(frame);
LaserBoy_frame_set::shrink_to_fit();
return *this;
}
//------------------------------------------------------------------------
LaserBoy_space& operator += (const LaserBoy_palette& palette)
{
LaserBoy_palette_set::push_back(palette);
LaserBoy_palette_set::shrink_to_fit();
return *this;
}
//------------------------------------------------------------------------
bool have_nonzero_offsets()
{
if(wav_offsets[0]) return true;
if(wav_offsets[1]) return true;
if(wav_offsets[2]) return true;
if(wav_offsets[3]) return true;
if(wav_offsets[4]) return true;
if(wav_offsets[5]) return true;
if(wav_offsets[6]) return true;
return false;
}
//------------------------------------------------------------------------
bool f_effect_selected()
{
if(effect_name.size() == 0)
return false;
for(size_t i = 0; i < frame_effect_names.size(); i++)
if(frame_effect_names[i] == effect_name)
return true;
return false;
}
//------------------------------------------------------------------------
bool sf_effect_selected()
{
if(effect_name.size() == 0)
return false;
for(size_t i = 0; i < selected_frames_effect_names.size(); i++)
if(selected_frames_effect_names[i] == effect_name)
return true;
return false;
}
//------------------------------------------------------------------------
bool fs_effect_selected()
{
if(effect_name.size() == 0)
return false;
for(size_t i = 0; i < frame_set_effect_names.size(); i++)
if(frame_set_effect_names[i] == effect_name)
return true;
return false;
}
//------------------------------------------------------------------------
bool file_selected()
{
if(file_name.size() == 0)
return false;
string list_item;
for(size_t list_item_index = 0; list_item_index < working_directory_list.size(); list_item_index++)
{
list_item = working_directory_list[list_item_index].path().filename().string();
if(list_item == file_name)
return true;
}
return false;
}
//------------------------------------------------------------------------
bool subdirectory_selected()
{
if(working_subdirectory.size() == 0)
return false;
if(directory_exists(working_directory + working_subdirectory, absolute_path_of_LaserBoy))
return true;
return false;
}
//------------------------------------------------------------------------
bool load_wtf_file (string wtf_file);
//------------------------------------------------------------------------
void clean_screen ();
//------------------------------------------------------------------------
void rename_all_frames (string prefix);
//------------------------------------------------------------------------
bool omit_palette (int index);
void clear_unused_palettes ();
void sync_rgb_and_palette ();
void sync_frames_to_target ();
void minimize_tables_and_palettes ();
void best_reduce_all_to_palette ();
void set_palette_indexes_by_name ();
//------------------------------------------------------------------------
void load_color_rescale_files ();
LaserBoy_Rescale_Error_Code load_color_rescale_gamma(size_t color_channel,
double gamma
);
LaserBoy_Rescale_Error_Code load_color_rescale_file (size_t color_channel);
int color_rescales_flags ();
//------------------------------------------------------------------------
void load_frame_effects ();
void load_selected_frames_effects ();
void load_frame_set_effects ();
//------------------------------------------------------------------------
LaserBoy_Error_Code call_frame_effect ();
LaserBoy_Error_Code call_selected_frames_effect ();
LaserBoy_Error_Code call_frame_set_effect ();
//------------------------------------------------------------------------
void load_background_bitmap (struct LaserBoy_bmp* bmp);
void render_background_bitmap ();
bool load_background_bitmap (const string& file, bool scale_to_screen);
bool reload_background_bitmap ();
void clear_background_bitmap ();
void recolor_background ();
//------------------------------------------------------------------------
void simplify_view_angle()
{
while(view_angle.x < 0 ) view_angle.x += two_pi;
while(view_angle.x > two_pi) view_angle.x -= two_pi;
while(view_angle.y < 0 ) view_angle.y += two_pi;
while(view_angle.y > two_pi) view_angle.y -= two_pi;
while(view_angle.z < 0 ) view_angle.z += two_pi;
while(view_angle.z > two_pi) view_angle.z -= two_pi;
}
//------------------------------------------------------------------------
LaserBoy_bmp* p_bmp () { return &bmp; }
LaserBoy_bmp* p_background () { return &background; }
LaserBoy_bmp* p_background_bmp_2D() { return &background_bmp_2D; }
LaserBoy_bmp* p_background_bmp_3D() { return &background_bmp_3D; }
//------------------------------------------------------------------------
void undo_wav_temp(std::fstream &in, std::fstream &out, const string& file_name)
{
if(in.is_open())
in.close();
if(out.is_open())
out.close();
remove(file_name.c_str());
rename( (file_name + ".tmp").c_str()
, file_name.c_str()
);
return;
}
//------------------------------------------------------------------------
void set_wav_out_header (LaserBoy_wav_header &header,
bool optimized,
bool timed
);
//------------------------------------------------------------------------
bool apply_wav_offsets_prep (const string& file);
bool overwirte_wav_offsets (const string& file);
bool invert_wav_prep (const string& file);
bool invert_signals_prep (const string& file);
bool clear_wav_polarity_list (const string& file, bool global_flip_flop);
bool apply_color_rescales_prep (const string& file);
bool omit_color_rescales (const string& file);
bool save_wav_rescales_as_txt (const string& file, const string& out_name);
bool save_sys_rescales_as_txt (size_t color_channel);
bool bit_resolution_to_wav_prep (const string& file_in, const string& file_out);
//------------------------------------------------------------------------
void apply_wav_offsets (std::fstream& wav_in,
std::fstream& wav_out,
LaserBoy_wav_header wav_in_header
);
//------------------------------------------------------------------------
void invert_wav (std::fstream& wav_in,
std::fstream& wav_out,
LaserBoy_wav_header wav_in_header
);
//------------------------------------------------------------------------
void invert_signals (std::fstream& wav_in,
std::fstream& wav_out,
LaserBoy_wav_header wav_in_header
);
//------------------------------------------------------------------------
void bit_resolution_to_wav (std::fstream& wav_in,
std::fstream& wav_out,
LaserBoy_wav_header wav_in_header
);
//------------------------------------------------------------------------
void apply_color_rescales (std::fstream& wav_in,
std::fstream& wav_out,
LaserBoy_wav_header wav_in_header
);
//------------------------------------------------------------------------
LaserBoy_SDL_GUI *p_GUI;
struct LaserBoy_bmp bmp , // a memory clone of screen
background , // empty for clearing screen
background_bmp_2D, // possibly a bitmap picture
background_bmp_3D; // possibly rotated, scaled, panned
vector working_directory_list,
bmp_file_list ;
vector frame_effect_names ,
selected_frames_effect_names,
frame_set_effect_names ;
vector frame_effects ;
vector selected_frames_effects ;
vector frame_set_effects ;
short color_rescale_r[256],
color_rescale_g[256],
color_rescale_b[256],
color_rescale_i[256];
short *color_rescale [4];
string last_ild_file_name;
LaserBoy_frame_set font_frames;
u32string font_index ;
};
//############################################################################
#endif
//############################################################################
//////////////////////////////////////////////////////////////////////////////
//############################################################################