formatter: Format `deftype` correctly (#3391)

New configuration options to format column widths in deftype field
definitions. Also force each field/method/state to be inlined.
pull/3394/head
Tyler Wilding 2024-02-27 20:12:44 -05:00 committed by GitHub
parent 8f1aba639c
commit ccd47f8465
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 580 additions and 558 deletions

View File

@ -87,6 +87,13 @@ tasks:
- cmd: python ./scripts/ci/lint-trailing-whitespace.py --fix
- cmd: python ./third-party/run-clang-format/run-clang-format.py -r common decompiler game goalc test tools lsp -i
- task: format-json
format-gsrc:
desc: "Run formatter on gsrc file"
preconditions:
- sh: test -f {{.FORMATTER_BIN_RELEASE_DIR}}/formatter{{.EXE_FILE_EXTENSION}}
msg: "Couldn't locate formatter executable in '{{.FORMATTER_BIN_RELEASE_DIR}}/formatter'"
cmds:
- "{{.FORMATTER_BIN_RELEASE_DIR}}/formatter --write --file '{{.FILE}}'"
# DECOMPILING
decomp:
cmds:

View File

@ -30,7 +30,19 @@ int hang_indentation_width(const FormatterTreeNode& curr_node) {
return 1 + hang_indentation_width(first_elt);
}
// TODO - compute length of each node and store it
// TODO - this doesn't account for paren's width contribution!
int get_total_form_inlined_width(const FormatterTreeNode& curr_node) {
if (curr_node.token) {
return curr_node.token->length();
}
int width = 1;
for (const auto& ref : curr_node.refs) {
width += get_total_form_inlined_width(ref);
}
return width + 1;
}
// TODO - compute length of each node and store it AOT
void apply_formatting_config(
FormatterTreeNode& curr_node,
std::optional<std::shared_ptr<formatter_rules::config::FormFormattingConfig>>
@ -51,6 +63,7 @@ void apply_formatting_config(
curr_node.formatting_config = predefined_config.value();
}
} else if (config_from_parent) {
// TODO - doesn't merge just replaces, a bit inflexible
predefined_config = *config_from_parent.value();
curr_node.formatting_config = predefined_config.value();
}
@ -70,7 +83,7 @@ void apply_formatting_config(
// NOTE - any modifications here to child elements could be superseeded later in the recursion!
// In order to maintain your sanity, only modify things here that _arent_ touched by default
// configurations. These are explicitly prepended with `parent_mutable_`
if (!predefined_config) {
if (!predefined_config && !curr_node.formatting_config.config_set) {
if (curr_node.metadata.is_top_level) {
curr_node.formatting_config.indentation_width = 0;
curr_node.formatting_config.hang_forms = false;
@ -123,18 +136,37 @@ void apply_formatting_config(
}
}
}
}
// TODO - this doesn't account for paren's width contribution!
int get_total_form_inlined_width(const FormatterTreeNode& curr_node) {
if (curr_node.token) {
return curr_node.token->length();
// Precompute the column widths for things like deftype fields
if (curr_node.formatting_config.determine_column_widths_for_list_elements) {
// iterate through each ref and find the max length of each index (may be a token, may not be!)
// then store that info in each list element's `list_element_column_widths` to be used when
// printing out the tokens (pad width)
// Find the maximum number of columns
int max_columns = 0;
for (const auto& field : curr_node.refs) {
if (field.refs.size() > max_columns) {
max_columns = field.refs.size();
}
}
// Now find the column max widths
std::vector<int> column_max_widths = {};
for (int col = 0; col < max_columns; col++) {
column_max_widths.push_back(0);
for (const auto& field : curr_node.refs) {
if (field.refs.size() > col) {
const auto width = get_total_form_inlined_width(field.refs.at(col));
if (width > column_max_widths.at(col)) {
column_max_widths[col] = width;
}
}
}
}
// Apply column info to every list
for (auto& field : curr_node.refs) {
field.formatting_config.list_element_column_widths = column_max_widths;
field.formatting_config.config_set = true;
}
}
int width = 1;
for (const auto& ref : curr_node.refs) {
width += get_total_form_inlined_width(ref);
}
return width + 1;
}
bool form_contains_comment(const FormatterTreeNode& curr_node) {
@ -166,6 +198,9 @@ bool form_contains_node_that_prevents_inlining(const FormatterTreeNode& curr_nod
bool can_node_be_inlined(const FormatterTreeNode& curr_node, int cursor_pos) {
using namespace formatter_rules;
if (curr_node.formatting_config.force_inline) {
return true;
}
// First off, we cannot inline the top level
if (curr_node.metadata.is_top_level) {
return false;
@ -314,6 +349,17 @@ std::vector<std::string> apply_formatting(const FormatterTreeNode& curr_node,
form_lines = new_form_lines;
}
// Add any column padding
if (!curr_node.formatting_config.list_element_column_widths.empty()) {
for (int i = 0; i < form_lines.size(); i++) {
const auto& token = form_lines.at(i);
if (i < form_lines.size() - 1) {
form_lines[i] = str_util::pad_right(
token, curr_node.formatting_config.list_element_column_widths.at(i), ' ');
}
}
}
// Apply necessary indentation to each line and add parens
if (!curr_node.metadata.is_top_level) {
std::string form_surround_start = "(";
@ -346,9 +392,9 @@ std::vector<std::string> apply_formatting(const FormatterTreeNode& curr_node,
return form_lines;
}
std::string join_formatted_lines(const std::vector<std::string> lines) {
// TODO - respect original file line endings
return fmt::format("{}", fmt::join(lines, "\n"));
std::string join_formatted_lines(const std::vector<std::string>& lines,
const std::string& line_ending) {
return fmt::format("{}", fmt::join(lines, line_ending));
}
std::optional<std::string> formatter::format_code(const std::string& source) {
@ -388,7 +434,8 @@ std::optional<std::string> formatter::format_code(const std::string& source) {
const auto formatted_lines = apply_formatting(formatting_tree.root);
// 4. Now we joint he lines together, it's easier when formatting to leave all lines independent
// so adding indentation is easier
const auto formatted_source = join_formatted_lines(formatted_lines);
const auto formatted_source =
join_formatted_lines(formatted_lines, file_util::get_majority_file_line_endings(source));
return formatted_source;
} catch (std::exception& e) {
lg::error("Unable to format code - {}", e.what());

View File

@ -2,8 +2,6 @@
#include <set>
#include "rule_config.h"
#include "common/util/string_util.h"
#include "third-party/fmt/core.h"

View File

@ -1,31 +1,25 @@
#include "rule_config.h"
#include "common/formatter/formatter_tree.h"
namespace formatter_rules {
namespace config {
// TODO - this could be greatly simplified with C++20's designated initialization
FormFormattingConfig new_permissive_flow_rule() {
FormFormattingConfig cfg;
cfg.hang_forms = false;
cfg.combine_first_two_lines = true;
return cfg;
static FormFormattingConfig new_permissive_flow_rule() {
return {.config_set = true, .hang_forms = false, .combine_first_two_lines = true};
}
FormFormattingConfig new_flow_rule(int start_index) {
FormFormattingConfig cfg;
cfg.hang_forms = false;
cfg.inline_until_index = [start_index](const std::vector<std::string>& /*curr_lines*/) {
return start_index;
};
return cfg;
static FormFormattingConfig new_flow_rule(int start_index) {
return {.config_set = true,
.hang_forms = false,
.inline_until_index = [start_index](const std::vector<std::string>& /*curr_lines*/) {
return start_index;
}};
}
FormFormattingConfig new_flow_rule_prevent_inlining_indexes(
static FormFormattingConfig new_deftype_rule(
int start_index,
const std::vector<int>& inlining_preventation_indices) {
FormFormattingConfig cfg;
cfg.config_set = true;
cfg.hang_forms = false;
cfg.inline_until_index = [start_index](std::vector<std::string> curr_lines) {
if (curr_lines.size() >= 4 && curr_lines.at(3) == "()") {
@ -35,19 +29,29 @@ FormFormattingConfig new_flow_rule_prevent_inlining_indexes(
};
for (const auto& index : inlining_preventation_indices) {
auto temp_config = std::make_shared<FormFormattingConfig>();
temp_config->config_set = true;
temp_config->prevent_inlining = true;
temp_config->hang_forms = false;
temp_config->indentation_width = 1;
auto temp_list_config = std::make_shared<FormFormattingConfig>();
temp_list_config->force_inline = true;
temp_list_config->hang_forms = false;
temp_config->default_index_config = temp_list_config;
if (index == 3) {
temp_config->determine_column_widths_for_list_elements = true;
}
cfg.index_configs.emplace(index, temp_config);
}
return cfg;
}
FormFormattingConfig new_binding_rule(int form_head_width) {
static FormFormattingConfig new_binding_rule(int form_head_width) {
FormFormattingConfig cfg;
cfg.config_set = true;
cfg.hang_forms = false;
cfg.combine_first_two_lines = true;
auto binding_list_config = std::make_shared<FormFormattingConfig>();
binding_list_config->config_set = true;
binding_list_config->hang_forms = false;
binding_list_config->indentation_width = 1;
binding_list_config->indentation_width_for_index = [form_head_width](FormFormattingConfig /*cfg*/,
@ -70,12 +74,14 @@ FormFormattingConfig new_binding_rule(int form_head_width) {
return cfg;
}
FormFormattingConfig new_pair_rule(bool combine_first_two_expr) {
static FormFormattingConfig new_pair_rule(bool combine_first_two_expr) {
FormFormattingConfig cfg;
cfg.config_set = true;
cfg.hang_forms = false;
cfg.prevent_inlining = true;
cfg.combine_first_two_lines = combine_first_two_expr;
auto pair_config = std::make_shared<FormFormattingConfig>();
pair_config->config_set = true;
pair_config->hang_forms = false;
pair_config->indentation_width = 1;
cfg.default_index_config = pair_config;
@ -86,7 +92,7 @@ const std::unordered_map<std::string, FormFormattingConfig> opengoal_form_config
{"case", new_pair_rule(true)},
{"cond", new_pair_rule(false)},
{"defmethod", new_flow_rule(3)},
{"deftype", new_flow_rule_prevent_inlining_indexes(3, {3, 4, 5})},
{"deftype", new_deftype_rule(3, {3, 4, 5, 6})},
{"defun", new_flow_rule(3)},
{"defun-debug", new_flow_rule(3)},
{"defbehavior", new_flow_rule(4)},
@ -98,6 +104,7 @@ const std::unordered_map<std::string, FormFormattingConfig> opengoal_form_config
{"let", new_binding_rule(4)},
{"rlet", new_binding_rule(5)},
{"when", new_flow_rule(2)},
{"begin", new_flow_rule(0)},
{"with-dma-buffer-add-bucket", new_flow_rule(2)}};
} // namespace config
} // namespace formatter_rules

View File

@ -7,12 +7,15 @@
#include <unordered_map>
#include <vector>
// TODO - some way to apply a config to all list elements (index configs with -1?)
namespace formatter_rules {
namespace config {
struct FormFormattingConfig {
// new
bool hang_forms = true; // TODO - remove this eventually, it's only involved in setting the
// indentation width, which we can do via the indentation_width function
bool config_set = false;
bool force_inline = false;
bool hang_forms =
true; // TODO - remove this eventually, it's only involved in setting the
// indentation width, which we can do via the new indentation_width function
int indentation_width =
2; // 2 for a flow // TODO - also remove this, prefer storing the first node's width in the
// metadata on the first pass, that's basically all this does
@ -30,6 +33,9 @@ struct FormFormattingConfig {
int parent_mutable_extra_indent = 0;
std::optional<std::shared_ptr<FormFormattingConfig>> default_index_config;
std::unordered_map<int, std::shared_ptr<FormFormattingConfig>> index_configs = {};
bool determine_column_widths_for_list_elements = false;
std::vector<int> list_element_column_widths = {};
};
extern const std::unordered_map<std::string, FormFormattingConfig> opengoal_form_config;

View File

@ -245,4 +245,13 @@ std::string titlize(const std::string& str) {
}
return new_str;
}
std::string pad_right(const std::string& input, const int width, const char padding_char) {
if (input.length() >= width) {
return input; // No need to pad if input length is already greater or equal to width
} else {
int padding_width = width - input.length();
return input + std::string(padding_width, padding_char);
}
}
} // namespace str_util

View File

@ -35,4 +35,5 @@ std::string to_lower(const std::string& str);
/// Is this a valid character for a hex number?
bool hex_char(char c);
std::string titlize(const std::string& str);
std::string pad_right(const std::string& input, const int width, const char padding_char);
} // namespace str_util

View File

@ -10,10 +10,14 @@
;; NOTE - for editable
(declare-type light-sphere structure)
(declare-type light-hash basic)
(define-extern lookup-light-sphere-by-name (function string light-hash light-sphere))
;; NOTE - for editable-player
(define-extern update-light-hash (function light-hash none))
(define-extern reset-light-hash (function light-hash none))
;; DECOMP BEGINS
@ -23,93 +27,67 @@
;; Note that the data is transposed to be faster for use in the VU code.
;; the w components are unused for lighting information - you can put whatever you want in them...
(deftype vu-lights (structure)
((direction vector 3 :inline)
(color vector 3 :inline)
(ambient vector :inline)
(fade-int uint32 :offset 44)
(fade-flags uint32 :offset 28)
)
)
((direction vector 3 :inline)
(color vector 3 :inline)
(ambient vector :inline)
(fade-int uint32 :offset 44)
(fade-flags uint32 :offset 28)))
(deftype light (structure)
((direction vector :inline)
(color rgbaf :inline)
(extra vector :inline)
(level float :overlay-at (-> extra data 0))
(luminance float :overlay-at (-> extra data 2))
(priority float :overlay-at (-> extra data 3))
(bytes uint8 4 :overlay-at (-> extra data 1))
(mask uint16 :overlay-at (-> extra data 1))
(palette-index int8 :overlay-at (-> bytes 3))
)
)
((direction vector :inline)
(color rgbaf :inline)
(extra vector :inline)
(level float :overlay-at (-> extra data 0))
(luminance float :overlay-at (-> extra data 2))
(priority float :overlay-at (-> extra data 3))
(bytes uint8 4 :overlay-at (-> extra data 1))
(mask uint16 :overlay-at (-> extra data 1))
(palette-index int8 :overlay-at (-> bytes 3))))
;; new jak 2 light, is applied to stuff in the sphere.
(deftype light-sphere (structure)
((name string)
(bsphere vector :inline)
(direction vector :inline)
(color vector :inline)
(decay-start float :offset 4)
(ambient-point-ratio float :offset 8)
(brightness float :offset 12)
(bytes uint8 4 :overlay-at (-> color data 3))
(mask uint16 :overlay-at (-> color data 3))
(palette-index int8 :overlay-at (-> bytes 3))
)
)
((name string)
(bsphere vector :inline)
(direction vector :inline)
(color vector :inline)
(decay-start float :offset 4)
(ambient-point-ratio float :offset 8)
(brightness float :offset 12)
(bytes uint8 4 :overlay-at (-> color data 3))
(mask uint16 :overlay-at (-> color data 3))
(palette-index int8 :overlay-at (-> bytes 3))))
;; hash bucket for fast "which light am I in?" checks.
(deftype light-hash-bucket (structure)
((index uint16)
(count uint16)
)
:pack-me
)
((index uint16)
(count uint16))
:pack-me)
(deftype light-hash (basic)
((num-lights uint16)
(num-indices uint16)
(num-buckets uint16)
(bucket-step uint8 2)
(base-trans vector :inline)
(axis-scale vector :inline)
(dimension-array vector4w :inline)
(bucket-array (inline-array light-hash-bucket))
(index-array pointer)
(light-sphere-array (inline-array light-sphere))
)
)
((num-lights uint16)
(num-indices uint16)
(num-buckets uint16)
(bucket-step uint8 2)
(base-trans vector :inline)
(axis-scale vector :inline)
(dimension-array vector4w :inline)
(bucket-array (inline-array light-hash-bucket))
(index-array pointer)
(light-sphere-array (inline-array light-sphere))))
(deftype light-hash-work (structure)
((ones vector4w :inline)
)
)
((ones vector4w :inline)))
(define *light-hash* (the-as light-hash #f))
(defmethod print ((this light))
(format
#t
"#<light [~F] ~F ~F ~F "
(-> this extra x)
(-> this direction x)
(-> this direction y)
(-> this direction z)
)
(format #t "#<light [~F] ~F ~F ~F " (-> this extra x) (-> this direction x) (-> this direction y) (-> this direction z))
(format #t "~F ~F ~F @ #x~X>" (-> this color x) (-> this color y) (-> this color z) this)
this
)
this)
(deftype light-group (structure)
((dir0 light :inline)
(dir1 light :inline)
(dir2 light :inline)
(ambi light :inline)
(lights light 4 :inline :overlay-at dir0)
)
)
((dir0 light :inline)
(dir1 light :inline)
(dir2 light :inline)
(ambi light :inline)
(lights light 4 :inline :overlay-at dir0)))

View File

@ -12,202 +12,142 @@
;; DECOMP BEGINS
(deftype mood-channel (structure)
((data float 24)
(vecs vector4 6 :inline :overlay-at (-> data 0))
)
)
((data float 24)
(vecs vector4 6 :inline :overlay-at (-> data 0))))
(deftype mood-channel-group (structure)
((data mood-channel 4 :inline)
)
)
((data mood-channel 4 :inline)))
(deftype mood-fog (structure)
((fog-color vector :inline)
(fog-dists vector :inline)
(fog-start meters :overlay-at (-> fog-dists data 0))
(fog-end meters :overlay-at (-> fog-dists data 1))
(fog-max float :overlay-at (-> fog-dists data 2))
(fog-min float :overlay-at (-> fog-dists data 3))
(erase-color vector :inline)
)
)
((fog-color vector :inline)
(fog-dists vector :inline)
(fog-start meters :overlay-at (-> fog-dists data 0))
(fog-end meters :overlay-at (-> fog-dists data 1))
(fog-max float :overlay-at (-> fog-dists data 2))
(fog-min float :overlay-at (-> fog-dists data 3))
(erase-color vector :inline)))
(deftype mood-fog-table (structure)
((data mood-fog 8 :inline)
(data-raw uint128 24 :overlay-at data)
)
)
((data mood-fog 8 :inline)
(data-raw uint128 24 :overlay-at data)))
(deftype mood-color (structure)
((lgt-color vector :inline)
(amb-color vector :inline)
)
)
((lgt-color vector :inline)
(amb-color vector :inline)))
(deftype mood-direction-table (structure)
((data vector 4 :inline)
)
)
((data vector 4 :inline)))
(deftype mood-color-table (structure)
((data mood-color 8 :inline)
(data-raw uint128 16 :overlay-at data)
)
)
((data mood-color 8 :inline)
(data-raw uint128 16 :overlay-at data)))
(deftype mood-sky-table (structure)
((data vector 8 :inline)
)
)
((data vector 8 :inline)))
(deftype mood-clouds (structure)
((cloud-min float)
(cloud-max float)
)
)
((cloud-min float)
(cloud-max float)))
(deftype mood-weather (structure)
((data float 2)
(cloud float :overlay-at (-> data 0))
(fog float :overlay-at (-> data 1))
)
((data float 2)
(cloud float :overlay-at (-> data 0))
(fog float :overlay-at (-> data 1)))
:pack-me
:allow-misaligned
)
:allow-misaligned)
(deftype mood-iweather (structure)
((data int32 2)
(cloud int32 :overlay-at (-> data 0))
(fog int32 :overlay-at (-> data 1))
)
:allow-misaligned
)
((data int32 2)
(cloud int32 :overlay-at (-> data 0))
(fog int32 :overlay-at (-> data 1)))
:allow-misaligned)
(deftype mood-range (structure)
((data float 4)
(min-cloud float :overlay-at (-> data 0))
(max-cloud float :overlay-at (-> data 1))
(min-fog float :overlay-at (-> data 2))
(max-fog float :overlay-at (-> data 3))
(quad uint128 :overlay-at (-> data 0))
)
)
((data float 4)
(min-cloud float :overlay-at (-> data 0))
(max-cloud float :overlay-at (-> data 1))
(min-fog float :overlay-at (-> data 2))
(max-fog float :overlay-at (-> data 3))
(quad uint128 :overlay-at (-> data 0))))
(deftype mood-filters-table (structure)
((data vector 8 :inline)
)
)
((data vector 8 :inline)))
(deftype mood-table (basic)
((mood-fog-table mood-fog-table)
(mood-color-table mood-color-table)
(mood-channel-group mood-channel-group)
(mood-direction-table mood-direction-table)
(mood-sky-table mood-sky-table)
(mood-interp-table sky-color-day)
)
)
((mood-fog-table mood-fog-table)
(mood-color-table mood-color-table)
(mood-channel-group mood-channel-group)
(mood-direction-table mood-direction-table)
(mood-sky-table mood-sky-table)
(mood-interp-table sky-color-day)))
(deftype mood-context-core (structure)
((current-fog mood-fog :inline)
(current-sky-color vector :inline)
(current-env-color vector :inline)
(current-prt-color vector :inline)
(current-shadow-color vector :inline)
)
)
((current-fog mood-fog :inline)
(current-sky-color vector :inline)
(current-env-color vector :inline)
(current-prt-color vector :inline)
(current-shadow-color vector :inline)))
(deftype mood-context-core2 (mood-context-core)
((light-group light-group 8 :inline)
)
)
((light-group light-group 8 :inline)))
(deftype mood-context-core3 (mood-context-core2)
((times vector 8 :inline)
)
)
((times vector 8 :inline)))
(deftype mood-context (mood-context-core3)
"`state` holds an arbitrary state structure, ie `[[sewer-states]]` and is used
when updating the mood. This means that an individual state structure must be less than 128 bytes"
((itimes vector4w 4 :inline)
(state uint32 32)
(data uint128 123 :overlay-at (-> current-fog fog-color data 0))
)
)
((itimes vector4w 4 :inline)
(state uint32 32)
(data uint128 123 :overlay-at (-> current-fog fog-color data 0))))
(deftype mood-control-work (structure)
((weather mood-weather :inline)
(iweather mood-iweather :inline)
(interp mood-weather :inline)
(index int32 4)
(color-interp float)
(color-index int32 2)
(channel-interp float)
(channel-index int32 2)
(cloud-interp float)
(cloud-index int32 2)
)
)
((weather mood-weather :inline)
(iweather mood-iweather :inline)
(interp mood-weather :inline)
(index int32 4)
(color-interp float)
(color-index int32 2)
(channel-interp float)
(channel-index int32 2)
(cloud-interp float)
(cloud-index int32 2)))
(deftype mood-control (mood-table)
((mood-clouds mood-clouds)
(current-interp mood-weather :inline)
(target-interp mood-weather :inline)
(speed-interp mood-weather :inline)
(range mood-range :inline)
(time-until-random mood-weather :inline)
(time-until-random-min mood-weather :inline)
(time-until-random-max mood-weather :inline)
(display-flag symbol)
(overide-weather-flag symbol)
(overide mood-weather :inline)
(lightning-index int32)
(lightning-val int32)
(lightning-time int32)
(lightning-time2 float)
(lightning-flash float)
(lightning-id sound-id)
(lightning-count0 uint32)
(lightning-count1 uint32)
(lightning-count2 uint32)
(rain-id sound-id)
(sound-pitch float)
(fogs mood-fog-table 9)
(colors mood-color-table 3)
(channels mood-channel-group 3)
(clouds mood-clouds 9)
)
((mood-clouds mood-clouds)
(current-interp mood-weather :inline)
(target-interp mood-weather :inline)
(speed-interp mood-weather :inline)
(range mood-range :inline)
(time-until-random mood-weather :inline)
(time-until-random-min mood-weather :inline)
(time-until-random-max mood-weather :inline)
(display-flag symbol)
(overide-weather-flag symbol)
(overide mood-weather :inline)
(lightning-index int32)
(lightning-val int32)
(lightning-time int32)
(lightning-time2 float)
(lightning-flash float)
(lightning-id sound-id)
(lightning-count0 uint32)
(lightning-count1 uint32)
(lightning-count2 uint32)
(rain-id sound-id)
(sound-pitch float)
(fogs mood-fog-table 9)
(colors mood-color-table 3)
(channels mood-channel-group 3)
(clouds mood-clouds 9))
(:methods
(init-weather! (_type_) none :behavior process)
(update-mood-weather! (_type_ float float float float) none)
(update-mood-range! (_type_ float float float float) none)
(set-time-for-random-weather! (_type_ float float) none)
(apply-mood-clouds-and-fog (_type_ mood-control-work) none)
(apply-mood-color (_type_ mood-control-work) none)
(apply-mood-channels (_type_ mood-control-work) none)
(adjust-num-clouds! (_type_ mood-control-work) none)
(gen-lightning-and-thunder! (_type_) number)
(play-or-stop-lightning! (_type_ sound-spec vector) sound-id)
)
)
(init-weather! (_type_) none :behavior process)
(update-mood-weather! (_type_ float float float float) none)
(update-mood-range! (_type_ float float float float) none)
(set-time-for-random-weather! (_type_ float float) none)
(apply-mood-clouds-and-fog (_type_ mood-control-work) none)
(apply-mood-color (_type_ mood-control-work) none)
(apply-mood-channels (_type_ mood-control-work) none)
(adjust-num-clouds! (_type_ mood-control-work) none)
(gen-lightning-and-thunder! (_type_) number)
(play-or-stop-lightning! (_type_ sound-spec vector) sound-id)))

View File

@ -8,96 +8,66 @@
;; DECOMP BEGINS
(deftype vu-lights (structure)
((direction vector 3 :inline)
(color vector 3 :inline)
(ambient vector :inline)
)
)
((direction vector 3 :inline)
(color vector 3 :inline)
(ambient vector :inline)))
(deftype light (structure)
"extra: {?, shadow, ?, ?}"
((direction vector :inline)
(color rgbaf :inline)
(extra vector :inline)
(level float :overlay-at (-> extra data 0))
(luminance float :overlay-at (-> extra data 2))
(priority float :overlay-at (-> extra data 3))
(bytes uint8 4 :overlay-at (-> extra data 1))
(mask uint16 :overlay-at (-> extra data 1))
(palette-index int8 :overlay-at (-> bytes 3))
)
)
((direction vector :inline)
(color rgbaf :inline)
(extra vector :inline)
(level float :overlay-at (-> extra data 0))
(luminance float :overlay-at (-> extra data 2))
(priority float :overlay-at (-> extra data 3))
(bytes uint8 4 :overlay-at (-> extra data 1))
(mask uint16 :overlay-at (-> extra data 1))
(palette-index int8 :overlay-at (-> bytes 3))))
(deftype light-shadow-mask (uint32)
()
)
(deftype light-shadow-mask (uint32) ())
(deftype light-sphere (structure)
((name string)
(bsphere vector :inline)
(direction vector :inline)
(color vector :inline)
(decay-start float :offset 4)
(ambient-point-ratio float :offset 8)
(brightness float :offset 12)
(bytes uint8 4 :overlay-at (-> color data 3))
(mask uint16 :overlay-at (-> color data 3))
(palette-index int8 :overlay-at (-> bytes 3))
(shadow uint32 :overlay-at (-> direction data 0))
)
)
((name string)
(bsphere vector :inline)
(direction vector :inline)
(color vector :inline)
(decay-start float :offset 4)
(ambient-point-ratio float :offset 8)
(brightness float :offset 12)
(bytes uint8 4 :overlay-at (-> color data 3))
(mask uint16 :overlay-at (-> color data 3))
(palette-index int8 :overlay-at (-> bytes 3))
(shadow uint32 :overlay-at (-> direction data 0))))
(deftype light-hash-bucket (structure)
((index uint16)
(count uint16)
)
)
((index uint16)
(count uint16)))
(deftype light-hash (basic)
((num-lights uint16)
(num-indices uint16)
(num-buckets uint16)
(bucket-step uint8 2)
(base-trans vector :inline)
(axis-scale vector :inline)
(dimension-array vector4w :inline)
(bucket-array (inline-array light-hash-bucket))
(index-array pointer)
(light-sphere-array (inline-array light-sphere))
)
)
((num-lights uint16)
(num-indices uint16)
(num-buckets uint16)
(bucket-step uint8 2)
(base-trans vector :inline)
(axis-scale vector :inline)
(dimension-array vector4w :inline)
(bucket-array (inline-array light-hash-bucket))
(index-array pointer)
(light-sphere-array (inline-array light-sphere))))
(deftype light-hash-work (structure)
((ones vector4w :inline)
)
)
((ones vector4w :inline)))
(define *light-hash* (the-as light-hash #f))
(defmethod print ((this light))
(format
#t
"#<light [~F] ~F ~F ~F "
(-> this extra x)
(-> this direction x)
(-> this direction y)
(-> this direction z)
)
(format #t "#<light [~F] ~F ~F ~F " (-> this extra x) (-> this direction x) (-> this direction y) (-> this direction z))
(format #t "~F ~F ~F @ #x~X>" (-> this color x) (-> this color y) (-> this color z) this)
this
)
this)
(deftype light-group (structure)
((dir0 light :inline)
(dir1 light :inline)
(dir2 light :inline)
(ambi light :inline)
(lights light 4 :inline :overlay-at dir0)
)
)
((dir0 light :inline)
(dir1 light :inline)
(dir2 light :inline)
(ambi light :inline)
(lights light 4 :inline :overlay-at dir0)))

View File

@ -6,271 +6,190 @@
;; dgos: GAME
(declare-type sky-color-day structure)
(define-extern movie? (function symbol))
;; DECOMP BEGINS
(deftype mood-channel (structure)
((data float 24)
(vecs vector4 6 :overlay-at (-> data 0))
)
)
((data float 24)
(vecs vector4 6 :overlay-at (-> data 0))))
(deftype mood-channel-group (structure)
((data mood-channel 4 :inline)
)
)
((data mood-channel 4 :inline)))
(deftype mood-fog (structure)
((fog-color vector :inline)
(fog-dists vector :inline)
(fog-start meters :overlay-at (-> fog-dists data 0))
(fog-end meters :overlay-at (-> fog-dists data 1))
(fog-max float :overlay-at (-> fog-dists data 2))
(fog-min float :overlay-at (-> fog-dists data 3))
(erase-color vector :inline)
)
)
((fog-color vector :inline)
(fog-dists vector :inline)
(fog-start meters :overlay-at (-> fog-dists data 0))
(fog-end meters :overlay-at (-> fog-dists data 1))
(fog-max float :overlay-at (-> fog-dists data 2))
(fog-min float :overlay-at (-> fog-dists data 3))
(erase-color vector :inline)))
(deftype mood-fog-table (structure)
((data mood-fog 8 :inline)
)
)
((data mood-fog 8 :inline)))
(deftype mood-color (structure)
((lgt-color vector :inline)
(amb-color vector :inline)
)
)
((lgt-color vector :inline)
(amb-color vector :inline)))
(deftype mood-direction-table (structure)
((data vector 4 :inline)
)
)
((data vector 4 :inline)))
(deftype mood-color-table (structure)
((data mood-color 8 :inline)
)
)
((data mood-color 8 :inline)))
(deftype mood-sky-table (structure)
((data vector 8 :inline)
)
)
((data vector 8 :inline)))
(deftype mood-clouds (structure)
((cloud-min float)
(cloud-max float)
)
)
((cloud-min float)
(cloud-max float)))
(deftype mood-weather (structure)
((data float 2)
(cloud float :overlay-at (-> data 0))
(fog float :overlay-at (-> data 1))
)
((data float 2)
(cloud float :overlay-at (-> data 0))
(fog float :overlay-at (-> data 1)))
:pack-me
:allow-misaligned
)
:allow-misaligned)
(deftype mood-iweather (structure)
((data int32 2)
(cloud int32 :overlay-at (-> data 0))
(fog int32 :overlay-at (-> data 1))
)
:allow-misaligned
)
((data int32 2)
(cloud int32 :overlay-at (-> data 0))
(fog int32 :overlay-at (-> data 1)))
:allow-misaligned)
(deftype mood-range (structure)
((data float 4)
(min-cloud float :overlay-at (-> data 0))
(max-cloud float :overlay-at (-> data 1))
(min-fog float :overlay-at (-> data 2))
(max-fog float :overlay-at (-> data 3))
(quad uint128 :overlay-at (-> data 0))
)
)
((data float 4)
(min-cloud float :overlay-at (-> data 0))
(max-cloud float :overlay-at (-> data 1))
(min-fog float :overlay-at (-> data 2))
(max-fog float :overlay-at (-> data 3))
(quad uint128 :overlay-at (-> data 0))))
(deftype mood-filters-table (structure)
((data vector 8 :inline)
)
)
((data vector 8 :inline)))
(deftype mood-table (basic)
((mood-fog-table mood-fog-table)
(mood-color-table mood-color-table)
(mood-channel-group mood-channel-group)
(mood-direction-table mood-direction-table)
(mood-sky-table mood-sky-table)
(mood-interp-table sky-color-day)
)
)
((mood-fog-table mood-fog-table)
(mood-color-table mood-color-table)
(mood-channel-group mood-channel-group)
(mood-direction-table mood-direction-table)
(mood-sky-table mood-sky-table)
(mood-interp-table sky-color-day)))
(deftype light-state (structure)
((time float)
(fade float)
)
)
((time float)
(fade float)))
(deftype flicker-state (structure)
((flicker-off uint8)
(flicker-on uint8)
)
)
((flicker-off uint8)
(flicker-on uint8)))
(deftype florescent-state (structure)
((value float)
(delay int8)
(delay2 int8)
)
)
((value float)
(delay int8)
(delay2 int8)))
(deftype electricity-state (structure)
((value float)
(scale float)
)
)
((value float)
(scale float)))
(deftype pulse-state (structure)
((pulse float)
(brightness float)
(target-brightness float)
(speed float)
)
)
((pulse float)
(brightness float)
(target-brightness float)
(speed float)))
(deftype strobe-state (structure)
((time float)
)
)
((time float)))
(deftype flames-state (structure)
((time float)
(index uint8)
(length uint8)
(height uint8)
)
)
((time float)
(index uint8)
(length uint8)
(height uint8)))
(deftype mood-context-core (structure)
((current-fog mood-fog :inline)
(current-sky-color vector :inline)
(current-env-color vector :inline)
(current-prt-color vector :inline)
(current-shadow-color vector :inline)
)
)
((current-fog mood-fog :inline)
(current-sky-color vector :inline)
(current-env-color vector :inline)
(current-prt-color vector :inline)
(current-shadow-color vector :inline)))
(deftype mood-context-core2 (mood-context-core)
((light-group light-group 8 :inline)
)
)
((light-group light-group 8 :inline)))
(deftype mood-context-core3 (mood-context-core2)
((times vector 8 :inline)
)
)
((times vector 8 :inline)))
(deftype mood-context (mood-context-core3)
((itimes vector4w 4 :inline)
(state uint32 32)
)
)
((itimes vector4w 4 :inline)
(state uint32 32)))
(deftype mood-control-work (structure)
((color vector4w :inline)
(weather mood-weather :inline)
(iweather mood-iweather :inline)
(interp mood-weather :inline)
(index int32 4)
(color-interp float)
(color-index int32 2)
(channel-interp float)
(channel-index int32 2)
(cloud-interp float)
(cloud-index int32 2)
)
)
((color vector4w :inline)
(weather mood-weather :inline)
(iweather mood-iweather :inline)
(interp mood-weather :inline)
(index int32 4)
(color-interp float)
(color-index int32 2)
(channel-interp float)
(channel-index int32 2)
(cloud-interp float)
(cloud-index int32 2)))
(deftype mood-control (mood-table)
((mood-clouds mood-clouds)
(current-interp mood-weather :inline)
(target-interp mood-weather :inline)
(speed-interp mood-weather :inline)
(range mood-range :inline)
(time-until-random mood-weather :inline)
(time-until-random-min mood-weather :inline)
(time-until-random-max mood-weather :inline)
(current-special-interp float)
(target-special-interp float)
(rate-special-interp float)
(display-flag symbol)
(overide-weather-flag symbol)
(pad int32)
(overide mood-weather :inline)
(lightning-index int32)
(lightning-val int32)
(lightning-time int32)
(lightning-time2 float)
(lightning-time3 float)
(lightning-flash float)
(lightning-id sound-id)
(lightning-count0 uint32)
(lightning-count1 uint32)
(lightning-count2 uint32)
(rain-id sound-id)
(sound-pitch float)
(fogs mood-fog-table 9)
(colors mood-color-table 3)
(channels mood-channel-group 3)
(clouds mood-clouds 9)
)
((mood-clouds mood-clouds)
(current-interp mood-weather :inline)
(target-interp mood-weather :inline)
(speed-interp mood-weather :inline)
(range mood-range :inline)
(time-until-random mood-weather :inline)
(time-until-random-min mood-weather :inline)
(time-until-random-max mood-weather :inline)
(current-special-interp float)
(target-special-interp float)
(rate-special-interp float)
(display-flag symbol)
(overide-weather-flag symbol)
(pad int32)
(overide mood-weather :inline)
(lightning-index int32)
(lightning-val int32)
(lightning-time int32)
(lightning-time2 float)
(lightning-time3 float)
(lightning-flash float)
(lightning-id sound-id)
(lightning-count0 uint32)
(lightning-count1 uint32)
(lightning-count2 uint32)
(rain-id sound-id)
(sound-pitch float)
(fogs mood-fog-table 9)
(colors mood-color-table 3)
(channels mood-channel-group 3)
(clouds mood-clouds 9))
(:methods
(mood-control-method-9 () none)
(mood-control-method-10 () none)
(mood-control-method-11 () none)
(mood-control-method-12 () none)
(set-special-interps! (_type_ float float symbol) none)
(weather-event-concluded? (_type_) symbol)
(mood-control-method-15 () none)
(mood-control-method-16 () none)
(mood-control-method-17 () none)
(mood-control-method-18 () none)
(mood-control-method-19 () none)
(mood-control-method-20 () none)
(mood-control-method-21 () none)
(mood-control-method-22 () none)
(mood-control-method-23 () none)
(mood-control-method-24 () none)
)
)
(mood-control-method-9 () none)
(mood-control-method-10 () none)
(mood-control-method-11 () none)
(mood-control-method-12 () none)
(set-special-interps! (_type_ float float symbol) none)
(weather-event-concluded? (_type_) symbol)
(mood-control-method-15 () none)
(mood-control-method-16 () none)
(mood-control-method-17 () none)
(mood-control-method-18 () none)
(mood-control-method-19 () none)
(mood-control-method-20 () none)
(mood-control-method-21 () none)
(mood-control-method-22 () none)
(mood-control-method-23 () none)
(mood-control-method-24 () none)))
(defmethod set-special-interps! ((this mood-control) (target-interp float) (rate-interp float) (set-current-interp? symbol))
"Sets the `*-special-interp` values with the given values
@ -282,15 +201,10 @@
(let ((clamped-interp (fmax 0.0 (fmin 1.0 target-interp))))
(set! (-> this target-special-interp) clamped-interp)
(set! (-> this rate-special-interp) rate-interp)
(if set-current-interp?
(set! (-> this current-special-interp) clamped-interp)
)
)
(if set-current-interp? (set! (-> this current-special-interp) clamped-interp)))
0
(none)
)
(none))
(defmethod weather-event-concluded? ((this mood-control))
"@returns [[#t]] if [[this::override-weather-flag]] is set, we aren't in a cutscene and [[this::current-special-interp]] is equal to `0.0`"
(and (-> this overide-weather-flag) (not (movie?)) (= (-> this current-special-interp) 0.0))
)
(and (-> this overide-weather-flag) (not (movie?)) (= (-> this current-special-interp) 0.0)))

View File

@ -8,4 +8,5 @@ vars:
TYPESEARCH_BIN_RELEASE_DIR: './build/tools'
OFFLINETEST_BIN_RELEASE_DIR: './build'
GOALCTEST_BIN_RELEASE_DIR: './build'
FORMATTER_BIN_RELEASE_DIR: './build/tools'
EXE_FILE_EXTENSION: ''

View File

@ -8,4 +8,5 @@ vars:
TYPESEARCH_BIN_RELEASE_DIR: './build/tools'
OFFLINETEST_BIN_RELEASE_DIR: './build'
GOALCTEST_BIN_RELEASE_DIR: './build'
FORMATTER_BIN_RELEASE_DIR: './build/tools'
EXE_FILE_EXTENSION: ''

View File

@ -8,4 +8,5 @@ vars:
TYPESEARCH_BIN_RELEASE_DIR: './out/build/Release/bin'
OFFLINETEST_BIN_RELEASE_DIR: './out/build/Release/bin'
GOALCTEST_BIN_RELEASE_DIR: './out/build/Release/bin'
FORMATTER_BIN_RELEASE_DIR: './out/build/Release/bin'
EXE_FILE_EXTENSION: '.exe'

View File

@ -68,3 +68,16 @@ Single Item Form
---
(println)
===
begin
===
(begin
"hello" (println "world"))
---
(begin
"hello"
(println "world"))

View File

@ -0,0 +1,52 @@
===
TODO - Basic State
===
(defstate active (enemy)
:virtual #t
:event enemy-event-handler
:enter (behavior ()
(set-time! (-> self state-time))
(logclear! (-> self enemy-flags) (enemy-flag cam-attack-mode))
(when (logtest? (-> self enemy-flags) (enemy-flag enable-on-active))
(logclear! (-> self enemy-flags) (enemy-flag enable-on-active))
(let ((gp-0 (-> self on-active)))
(if gp-0
(script-eval gp-0 :vector (-> self root trans))
)
)
)
(when (not (logtest? (enemy-flag chase-startup) (-> self enemy-flags)))
(if (logtest? (-> self enemy-flags) (enemy-flag actor-pause-backup))
(logior! (-> self mask) (process-mask actor-pause))
(logclear! (-> self mask) (process-mask actor-pause))
)
)
)
:trans (behavior ()
(when (time-elapsed? (-> self state-time) (seconds 0.1))
(let ((v1-3 (-> self focus aware)))
(cond
((< (the-as int v1-3) 1)
(go-virtual idle)
)
((< 1 (the-as int v1-3))
(go-virtual notice)
)
)
)
)
)
:code (behavior ()
(ja-channel-push! 1 (seconds 0.1))
(sleep-code)
)
:post (behavior ()
(idle-control-method-10 (-> self idle-anim-player) self)
(enemy-simple-post)
)
)
---
TODO

View File

@ -15,7 +15,7 @@ Types - With Methods
---
(deftype popup-menu (basic)
((entries (array popup-menu-entry))
((entries (array popup-menu-entry))
(curr-entry-index int32))
(:methods
(draw! (_type_) none)
@ -33,3 +33,75 @@ Types - Empty
---
(deftype popup-menu-label (popup-menu-entry) ())
===
Types - With Methods and States
===
(deftype popup-menu (basic)
((entries-incredibly-long-name-wow-what-a-long-name-very-very-long-long-long (array popup-menu-entry) :inline :overlay-at event-param-point)
(curr-entry-index int32))
(:methods
(method-with-a-really-long-name-method-with-a-really-long-name-method-with-a-really-long-name-with-a-really-long-name-with-a-really-long-name (_type_) none :replace)
(move-up! (_type_) none)
(move-down! (_type_) none)
(press! (_type_) none)
(get-widest-label (_type_ font-context) float))
(:states
state-with-a-really-long-name-method-with-a-really-long-name-method-with-a-really-long-name-with-a-really-long-name-with-a-really-long-name-with-a-really-long-name
(state-with-a-really-long-name-method-with-a-really-long-name-method-with-a-really-long-name-with-a-really-long-name-with-a-really-long-name-with-a-really-long-name symbol symbol symbol)
(target-attack-uppercut float float)
(target-attack-uppercut-jump float float)
(target-board-clone-anim handle)
target-board-duck-stance
target-board-falling
(target-board-flip float float symbol)
(target-board-get-off object symbol)
target-board-get-on
(target-board-grab symbol)
(target-board-grenade handle)
target-board-halfpipe
(target-board-hit vector attack-info)
target-board-hit-ground)
(:state-methods
state-method-with-a-really-long-name-method-with-a-really-long-name-method-with-a-really-long-name-with-a-really-long-name-with-a-really-long-name-with-a-really-long-name
(state-method-with-a-really-long-name-method-with-a-really-long-name-method-with-a-really-long-name-with-a-really-long-name-with-a-really-long-name-with-a-really-long-name float symbol symbol)
pov-camera-playing
pov-camera-start-playing
pov-camera-startup
)
)
---
(deftype popup-menu (basic)
((entries-incredibly-long-name-wow-what-a-long-name-very-very-long-long-long (array popup-menu-entry) :inline :overlay-at event-param-point)
(curr-entry-index int32))
(:methods
(method-with-a-really-long-name-method-with-a-really-long-name-method-with-a-really-long-name-with-a-really-long-name-with-a-really-long-name (_type_) none :replace)
(move-up! (_type_) none)
(move-down! (_type_) none)
(press! (_type_) none)
(get-widest-label (_type_ font-context) float))
(:states
state-with-a-really-long-name-method-with-a-really-long-name-method-with-a-really-long-name-with-a-really-long-name-with-a-really-long-name-with-a-really-long-name
(state-with-a-really-long-name-method-with-a-really-long-name-method-with-a-really-long-name-with-a-really-long-name-with-a-really-long-name-with-a-really-long-name symbol symbol symbol)
(target-attack-uppercut float float)
(target-attack-uppercut-jump float float)
(target-board-clone-anim handle)
target-board-duck-stance
target-board-falling
(target-board-flip float float symbol)
(target-board-get-off object symbol)
target-board-get-on
(target-board-grab symbol)
(target-board-grenade handle)
target-board-halfpipe
(target-board-hit vector attack-info)
target-board-hit-ground)
(:state-methods
state-method-with-a-really-long-name-method-with-a-really-long-name-method-with-a-really-long-name-with-a-really-long-name-with-a-really-long-name-with-a-really-long-name
(state-method-with-a-really-long-name-method-with-a-really-long-name-method-with-a-really-long-name-with-a-really-long-name-with-a-really-long-name-with-a-really-long-name float symbol symbol)
pov-camera-playing
pov-camera-start-playing
pov-camera-startup))

View File

@ -102,6 +102,11 @@ bool run_tests(const fs::path& file_path, const bool only_important_tests) {
if (only_important_tests && !str_util::starts_with(test.name, "!")) {
continue;
}
if (str_util::contains(test.output, "TODO")) {
// ignore the output
fmt::print(" ⚠️ - {}\n", test.name);
continue;
}
const auto formatted_result = formatter::format_code(test.input);
if (formatted_result && str_util::starts_with(test.name, "!?")) {
fmt::print("FORMATTED RESULT:\n\n{}\n\n", formatted_result.value());