(SYSTEM:set-gc-report-time-threshold 5)


;; collect garbage after each rendered frame?
(constant aggressive-gc #t)

;; use maximum map size? (to test GC and render times).
;; average 128x128 cave processing time is ~9 msecs.
;; average 256x256 cave processing time is ~31 msecs.
;; average 40x22 cave processing time is ~1 msecs.
(constant use-max-map-size #f)

;; maximum map size is 256x256 instead of 128x128?
(constant use-256x256-map #f)

;; use fast loop in "game:step"? ~2 times faster that the slow version.
(constant fast-step-loop #t)

;; use "sticky keys" mode for keyboard controls handling?
(constant sticky-keyboard-handiling #f)

;(constant fixed-level-speed 200)
(define fixed-level-speed 170)
;; ignore requested level speed, and use the one specified above?
(define use-fixed-level-speed #f)

(constant full-level-scale #f)

(define master-volume 0.3)


(constant flash-duration-frames 6)

(constant frame-time {1000 / 60})
;; one game tick is 200 msecs, 5 ticks per second.
;(constant game-time {1000 / 5})
;; 2 frames delay (NOT game ticks!)
(constant anim-delay 2)
;; player offset from the center to start scrolling
(constant scroll-offset-x {3 * 16})
(constant scroll-offset-y {3 * 16})


(constant window-scale-x (if full-level-scale 1.6 2))
(constant window-scale-y (if full-level-scale 1.6 2))
(constant window-width-orig 1024)
(constant window-height-orig 722)


define strip-last-name(str)
  cond
    {string-length(str) = 0}
      ""
    {str[{string-length(str) - 1}] = 47}
      str
    else
      strip-last-name substring(str 0 {string-length(str) - 1})

(define my-path strip-last-name(*cli-arg-vector*[0]))

define make-data-path(fname)
  string-append(my-path fname)

define make-main-path(fname)
  string-append(my-path fname)


(define bd-file #nil)
(define start-cave 1)

let arg-loop <* aidx 1 \\ argv *cli-arg-vector* *>
  cond
    {aidx = vector-length(argv)}
      #void
    {null? bd-file}
      gset! bd-file argv[aidx]
      arg-loop {aidx + 1} argv
    else
      gset! start-cave string->number(argv[aidx])
      assert {fixnum? start-cave} "starting cave should be a number"
      assert between?(start-cave 1 255) "invalid starting cave number"


; simple exponential running average
define make-running-average()
  define fade-off {15 / 100}  ;; percents
  define value #f
  case-lambda
    ()
      if {false? value}
        0
        trunc(value)
    (new-value)
      if {null? new-value}
        {value := 0}
        if {false? value}
          {value := new-value}
          {value := {{fade-off * new-value} + {{1.0 - fade-off} * value}}}
      trunc(value)

(define frame-time-report make-running-average())


define do-gc()
  ;define stt {- ticks-msec()}
  ::SYSTEM:collect-garbage()
  ;inc! stt ticks-msec()
  ;if {stt > 4}
  ;  printf "GC: %o\n" stt


(load "flexgui/flexgui-main.lsp")
(import 'flexgui:flexlay)
(import 'flexgui:lgfx)

(require 'enum)
(load "bd-02-console.lsp")
(load "bd-05-optlist.lsp")
(load "bd-10-defs-00-consts.lsp")
(load "bd-10-defs-10-eximg.lsp")
(load "bd-10-defs-20-etype.lsp")
(load "bd-10-defs-30-sounds.lsp")
(load "bd-20-edef-10-edef.lsp")
(load "bd-20-edef-16-evect.lsp")
(load "bd-20-edef-20-defines.lsp")
(load "bd-30-cave-options.lsp")
(load "bd-36-bdcff-parser.lsp")
(load "bd-40-soundman.lsp")
(load "bd-42-game.lsp")
(load "bd-50-objects.lsp")
(load "bd-60-utils-10-gfx-recolor.lsp")
(load "bd-62-player-props-db.lsp")
(load "bd-64-cave-db.lsp")
(load "bd-70-play-engine.lsp")
(load "bd-80-gui-select-game.lsp")


define load-the-bdcff(fname)
  define bdcff-stt {- ticks-msec()}
  printf "loading BDCFF: %s\n" fname
  bdcff-loader:load-file fname
  {bdcff-stt := {bdcff-stt + ticks-msec()}}
  printf "loaded in %o msecs.\n" bdcff-stt


if {string? bd-file}
   (load-the-bdcff bd-file)

(play-engine:init-resources)
(play-engine:init-console)

(open-cave-db)
(open-props-db)


define play-the-bdcff(cave fname)
  ;define bdcff-stt {- ticks-msec()}
  ;bdcff-loader:load-file fname
  ;{bdcff-stt := {bdcff-stt + ticks-msec()}}
  ;printf "loaded in %o msecs.\n" bdcff-stt
  ;;
  gset! selected-game-id #f
  (play-engine:reinit)
  (play-engine:run-game-loop {cave - 1} 0)


define play-from-gui()
  game:wipe-replay()
  game-select-gui()
  if (and flexgui:lgfx:window?()
          {fixnum? selected-game-id}
          {fixnum? selected-cave-index})
    then
      printf "loading BDCFF for game #%d\n" selected-game-id
      define bdcff-stt {- ticks-msec()}
      bdcff-loader:load-string("game.bd" get-game-bdcff(selected-game-id))
      {bdcff-stt := {bdcff-stt + ticks-msec()}}
      printf "loaded in %o msecs.\n" bdcff-stt
      ;printf "selected-cave-index=%o\n" selected-cave-index
      if {false? selected-cave-index}
        play-from-gui()
        else
          (update-bdcff-credits selected-game-id)
          (play-engine:reinit)
          (play-engine:run-game-loop selected-cave-index 0)
          play-from-gui()


cond
  {string? bd-file}
    ;(load-the-bdcff bd-file)
    (play-the-bdcff start-cave bd-file)
  else
    (play-from-gui)
    ;(play-tutorial)
    ;(play-the-bdcff 20 "../_zzz_bdash/_shithub_gdash_export_crli/caves/Rory_Agsten/RTA_Dash_1.bd")
    ;; predictable slime test. seems to work ok.
    ;(play-the-bdcff 14 "bdcff-old/AFL_Boulderdash.bd")


(close-props-db)
(close-cave-db)

(lgfx:close-window)
