~cadence/PE-DIA

0d2c8c164841acb86e8a9674d0b1c0d4118a416b — Cadence Ember 1 year, 24 days ago 4c5b53b
Add GUI for decompiler
2 files changed, 94 insertions(+), 8 deletions(-)

A decompiler-gui.rkt
M decompiler.rkt
A decompiler-gui.rkt => decompiler-gui.rkt +82 -0
@@ 0,0 1,82 @@
#lang racket/base
(require racket/gui
         racket/path
         racket/gui/easy
         racket/gui/easy/operator
         (rename-in racket/gui/easy
                    (dialog gui-dialog))
         "decompiler.rkt")

(define-syntax-rule (render-quietly form ...)
  (void (render form ...)))

(define (display-error e)
  (define/obs @visible? #t)
  (render
   (gui-dialog #:title "Error"
               #:mixin (λ (%) (class % (super-new) (obs-observe! @visible? (λ (visible?) (send this show visible?)))))
                (vpanel #:margin '(10 10)
                        (text (exn-message e))
                        (button "OK" (λ () (:= @visible? #f)))))
    main-window)
  (void))

(define/obs @loaded-path #f)
(define/obs @dialog #f)

(define (load-dialog path)
  (when path
    (with-handlers ([exn:fail:user? display-error])
      (call-with-input-file* path
        (λ (in)
          (:= @dialog (read-dialog in))
          (:= @loaded-path path))))))

(define (save-prompt)
  (define dialog (obs-peek @dialog))
  (define loaded-path (obs-peek @loaded-path))
  (when (and loaded-path dialog)
    (define new-dest (file-name-from-path (path-replace-extension loaded-path ".md")))
    (define path (put-file "Choose destination to export" #f #f new-dest "md" '() '(("Text Files" "*.md;*.txt") ("Any" "*.*"))))
    (when path
      (call-with-output-file path #:mode 'text #:exists 'replace
        (λ (out)
          (write-string (dialog->text dialog) out))))))

(define problem-checkers
  (list
   (λ (i) (and ((length (interchange^-lines i)) . > . max-number-of-lines) "L"))))

(define (dialog-table dialog)
  (for/vector ([interchange (dialog^-interchanges dialog)]
               [n0 (in-naturals 0)])
    (define lines (interchange^-lines interchange))
    (define first-line (if (pair? lines) (car lines) "<empty>"))
    (define problem (or (for/or ([p problem-checkers]) (p interchange)) ""))
    (vector
     problem
     (number->string n0)
     first-line
     (number->string (length (interchange^-lines interchange)))
     (number->string (length (interchange^-replies interchange))))))

(define main-window
  (render
   (window
    #:title "Wonderland Adventures Dialog Decompiler"
    #:size '(500 600)
    (group "Files"
           #:stretch '(#t #f)
           (hpanel #:stretch '(#t #f)
                   (button "Open .dia file" #:stretch '(#t #t)
                           (λ ()
                             (define path (get-file "Choose a .dia file" #f #f #f "dia" '() '(("WA Dialogs" "*.dia") ("Any" "*.*"))))
                             (load-dialog path)))
                   (button "Export dialog as text" #:stretch '(#t #t) #:enabled? @dialog
                           save-prompt)))
    (group "Details"
           (if-view @dialog
                    (table #:column-widths '((2 300))
                           '("Ok?" "N#" "Text" "Lines" "Replies")
                           (@dialog . ~> . dialog-table))
                    (spacer))))))

M decompiler.rkt => decompiler.rkt +12 -8
@@ 2,6 2,16 @@
(require racket/list
         racket/port)

(provide
 read-dialog
 dialog->text
 (struct-out dialog^)
 (struct-out interchange^)
 (struct-out effect^)
 (struct-out reply^)
 chars-per-line
 max-number-of-lines)

;; test structures

(module+ test


@@ 19,9 29,8 @@

;; handler if there's not enough data

(define (end-of-input [message "Tried to read more from the file, but reached the end of the file."])
  (displayln message)
  (exit 1))
(define (end-of-input [message : String "Tried to read more from the file, but reached the end of the file."])
  (raise (exn:fail:user message (current-continuation-marks))))

;; wonderland basic types



@@ 139,8 148,3 @@
                    (reply^-cmd-data-3 reply)
                    (reply^-cmd-data-4 reply)))
          (displayln ""))))))

;; go!
(define in (open-input-file "x.dia"))
(define dialog (read-dialog in))
(displayln (dialog->text dialog))