first!
This commit is contained in:
parent
19f0b80394
commit
b75523115a
25 changed files with 1672 additions and 14 deletions
11
LICENSE
11
LICENSE
|
@ -1,11 +0,0 @@
|
||||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
|
||||||
Version 2, December 2004
|
|
||||||
|
|
||||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
|
||||||
|
|
||||||
Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed.
|
|
||||||
|
|
||||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
||||||
|
|
||||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
|
|
@ -1,3 +0,0 @@
|
||||||
# L.P.T
|
|
||||||
|
|
||||||
Visual Novel Engine
|
|
563
README.txt
Normal file
563
README.txt
Normal file
|
@ -0,0 +1,563 @@
|
||||||
|
Installing
|
||||||
|
==========
|
||||||
|
|
||||||
|
Windows
|
||||||
|
-------
|
||||||
|
|
||||||
|
In the ttf folder, double-click each font file, click “Install font”; to install all at once, select all files, right-click, and choose “Install”
|
||||||
|
|
||||||
|
OR
|
||||||
|
|
||||||
|
Use https://chocolatey.org:
|
||||||
|
|
||||||
|
choco install firacode
|
||||||
|
|
||||||
|
|
||||||
|
macOS
|
||||||
|
-----
|
||||||
|
|
||||||
|
In the downloaded TTF folder:
|
||||||
|
|
||||||
|
1. Select all font files
|
||||||
|
2. Right click and select `Open` (alternatively `Open With Font Book`)
|
||||||
|
3. Select "Install Font"
|
||||||
|
|
||||||
|
OR
|
||||||
|
|
||||||
|
Use http://brew.sh:
|
||||||
|
|
||||||
|
`brew tap homebrew/cask-fonts`
|
||||||
|
`brew install font-fira-code`
|
||||||
|
|
||||||
|
|
||||||
|
Ubuntu Zesty (17.04), Debian Stretch (9) or newer
|
||||||
|
-------------------------------------------------
|
||||||
|
|
||||||
|
1. Make sure that the `universe` (for Ubuntu) or `contrib` (for Debian) repository is enabled (see https://askubuntu.com/questions/148638/how-do-i-enable-the-universe-repository or https://wiki.debian.org/SourcesList#Component)
|
||||||
|
2. Install `fonts-firacode` package either by executing `sudo apt install fonts-firacode` in the terminal or via GUI tool (like “Software Center”)
|
||||||
|
|
||||||
|
|
||||||
|
Arch Linux
|
||||||
|
----------
|
||||||
|
|
||||||
|
Fira Code package is available in the official repository: https://www.archlinux.org/packages/community/any/ttf-fira-code/.
|
||||||
|
|
||||||
|
Variant of Fira Code package is available in the AUR: https://aur.archlinux.org/packages/otf-fira-code-git/.
|
||||||
|
|
||||||
|
|
||||||
|
Gentoo
|
||||||
|
------
|
||||||
|
|
||||||
|
emerge -av media-fonts/fira-code
|
||||||
|
|
||||||
|
|
||||||
|
Fedora
|
||||||
|
------
|
||||||
|
|
||||||
|
To install, perform the following commands:
|
||||||
|
|
||||||
|
dnf install fira-code-fonts
|
||||||
|
|
||||||
|
|
||||||
|
Solus
|
||||||
|
-----
|
||||||
|
|
||||||
|
Fira Code package is available in the official repository: `font-firacode-ttf` and `font-firacode-otf`.
|
||||||
|
They can be installed by running:
|
||||||
|
|
||||||
|
sudo eopkg install font-firacode-ttf font-firacode-otf
|
||||||
|
|
||||||
|
|
||||||
|
Void linux
|
||||||
|
----------
|
||||||
|
|
||||||
|
xbps-install font-firacode
|
||||||
|
|
||||||
|
|
||||||
|
Linux Manual Installation
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
With most desktop-oriented distributions, double-clicking each font file in the ttf folder and selecting “Install font” should be enough. If it isn’t, create and run `download_and_install.sh` script:
|
||||||
|
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
fonts_dir="${HOME}/.local/share/fonts"
|
||||||
|
if [ ! -d "${fonts_dir}" ]; then
|
||||||
|
echo "mkdir -p $fonts_dir"
|
||||||
|
mkdir -p "${fonts_dir}"
|
||||||
|
else
|
||||||
|
echo "Found fonts dir $fonts_dir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
for type in Bold Light Medium Regular Retina; do
|
||||||
|
file_path="${HOME}/.local/share/fonts/FiraCode-${type}.ttf"
|
||||||
|
file_url="https://github.com/tonsky/FiraCode/blob/master/distr/ttf/FiraCode-${type}.ttf?raw=true"
|
||||||
|
if [ ! -e "${file_path}" ]; then
|
||||||
|
echo "wget -O $file_path $file_url"
|
||||||
|
wget -O "${file_path}" "${file_url}"
|
||||||
|
else
|
||||||
|
echo "Found existing file $file_path"
|
||||||
|
fi;
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "fc-cache -f"
|
||||||
|
fc-cache -f
|
||||||
|
|
||||||
|
More details: https://github.com/tonsky/FiraCode/issues/4
|
||||||
|
|
||||||
|
|
||||||
|
FreeBSD
|
||||||
|
-------
|
||||||
|
|
||||||
|
Using pkg(8):
|
||||||
|
|
||||||
|
pkg install firacode
|
||||||
|
|
||||||
|
OR
|
||||||
|
|
||||||
|
Using ports:
|
||||||
|
|
||||||
|
cd /usr/ports/x11-fonts/firacode && make install clean
|
||||||
|
|
||||||
|
|
||||||
|
Enabling ligatures
|
||||||
|
==================
|
||||||
|
|
||||||
|
Atom
|
||||||
|
----
|
||||||
|
|
||||||
|
To change your font to Fira Code, open Atom's preferences (`cmd + ,` on a Mac, `ctrl + ,` on PC), make sure the "Settings" tab is selected, or the "Editor" in Atom 1.10+, and scroll down to "Editor Settings". In the "Font Family" field, enter `Fira Code`.
|
||||||
|
|
||||||
|
If you wish to specify a font weight, for example, Light, use `Fira Code Light` as a font name (Windows) or `FiraCode-Light` (macOS).
|
||||||
|
|
||||||
|
Ligatures are enabled by default in Atom 1.9 and above.
|
||||||
|
|
||||||
|
|
||||||
|
VS Code
|
||||||
|
-------
|
||||||
|
|
||||||
|
To open the settings editor, first from the File menu choose Preferences, Settings or use keyboard shortcut `Ctrl + ,` (Windows) or `Cmd + ,` (macOS).
|
||||||
|
|
||||||
|
To enable FiraCode in the settings editor, under "Commonly Used", expand the "Text Editor" settings and then click on "Font". In the "Font Family" input box type `Fira Code`, replacing any content. Tick the check box "Enables/Disables font ligatures" under "Font Ligatures" to enable the special ligatures.
|
||||||
|
|
||||||
|
If you wish to specify a font weight, for example, Light, use `Fira Code Light` as a font name (Windows) or `FiraCode-Light` (macOS).
|
||||||
|
|
||||||
|
|
||||||
|
IntelliJ products
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
1. Enable in Settings → Editor → Font → Enable Font Ligatures
|
||||||
|
2. Select `Fira Code` as "Primary font" under Settings → Editor → Font
|
||||||
|
|
||||||
|
Additionally, if a Color Scheme is selected:
|
||||||
|
|
||||||
|
3. Enable in Settings → Editor → Color Scheme → Color Scheme Font → Enable Font Ligatures
|
||||||
|
4. Select Fira Code as "Primary font" under Settings → Editor → Color Scheme → Color Scheme Font
|
||||||
|
|
||||||
|
|
||||||
|
BBEdit, TextWrangler
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Run in your terminal:
|
||||||
|
|
||||||
|
defaults write com.barebones.bbedit "EnableFontLigatures_Fira Code" -bool YES
|
||||||
|
|
||||||
|
Source: https://www.barebones.com/support/bbedit/ExpertPreferences.html
|
||||||
|
|
||||||
|
|
||||||
|
Brackets
|
||||||
|
--------
|
||||||
|
|
||||||
|
1. From the `View` menu choose `Themes....`
|
||||||
|
2. Paste `'Fira Code'`, at the beginning of `Font Family`
|
||||||
|
|
||||||
|
|
||||||
|
Emacs
|
||||||
|
-----
|
||||||
|
|
||||||
|
There are a few options when it comes down to using ligatures in
|
||||||
|
Emacs. They are listed in order of preferred to less-preferred. Pick one!
|
||||||
|
|
||||||
|
1. Using composition mode in Emacs Mac port
|
||||||
|
|
||||||
|
If you're using the latest Mac port of Emacs (https://bitbucket.org/mituharu/emacs-mac by Mitsuharu Yamamoto) for macOS, you can use:
|
||||||
|
|
||||||
|
(mac-auto-operator-composition-mode)
|
||||||
|
|
||||||
|
This is generally the easiest solution, but can only be used on macOS.
|
||||||
|
|
||||||
|
2. Using prettify-symbols
|
||||||
|
|
||||||
|
These instructions are pieced together by https://github.com/Triavanicus, taking some pieces from https://github.com/minad/hasklig-mode.
|
||||||
|
|
||||||
|
This method requires you to install the Fira Code Symbol font, made by https://github.com/siegebell:
|
||||||
|
https://github.com/tonsky/FiraCode/issues/211#issuecomment-239058632
|
||||||
|
|
||||||
|
(defun fira-code-mode--make-alist (list)
|
||||||
|
"Generate prettify-symbols alist from LIST."
|
||||||
|
(let ((idx -1))
|
||||||
|
(mapcar
|
||||||
|
(lambda (s)
|
||||||
|
(setq idx (1+ idx))
|
||||||
|
(let* ((code (+ #Xe100 idx))
|
||||||
|
(width (string-width s))
|
||||||
|
(prefix ())
|
||||||
|
(suffix '(?\s (Br . Br)))
|
||||||
|
(n 1))
|
||||||
|
(while (< n width)
|
||||||
|
(setq prefix (append prefix '(?\s (Br . Bl))))
|
||||||
|
(setq n (1+ n)))
|
||||||
|
(cons s (append prefix suffix (list (decode-char 'ucs code))))))
|
||||||
|
list)))
|
||||||
|
|
||||||
|
(defconst fira-code-mode--ligatures
|
||||||
|
'("www" "**" "***" "**/" "*>" "*/" "\\\\" "\\\\\\"
|
||||||
|
"{-" "[]" "::" ":::" ":=" "!!" "!=" "!==" "-}"
|
||||||
|
"--" "---" "-->" "->" "->>" "-<" "-<<" "-~"
|
||||||
|
"#{" "#[" "##" "###" "####" "#(" "#?" "#_" "#_("
|
||||||
|
".-" ".=" ".." "..<" "..." "?=" "??" ";;" "/*"
|
||||||
|
"/**" "/=" "/==" "/>" "//" "///" "&&" "||" "||="
|
||||||
|
"|=" "|>" "^=" "$>" "++" "+++" "+>" "=:=" "=="
|
||||||
|
"===" "==>" "=>" "=>>" "<=" "=<<" "=/=" ">-" ">="
|
||||||
|
">=>" ">>" ">>-" ">>=" ">>>" "<*" "<*>" "<|" "<|>"
|
||||||
|
"<$" "<$>" "<!--" "<-" "<--" "<->" "<+" "<+>" "<="
|
||||||
|
"<==" "<=>" "<=<" "<>" "<<" "<<-" "<<=" "<<<" "<~"
|
||||||
|
"<~~" "</" "</>" "~@" "~-" "~=" "~>" "~~" "~~>" "%%"
|
||||||
|
"x" ":" "+" "+" "*"))
|
||||||
|
|
||||||
|
(defvar fira-code-mode--old-prettify-alist)
|
||||||
|
|
||||||
|
(defun fira-code-mode--enable ()
|
||||||
|
"Enable Fira Code ligatures in current buffer."
|
||||||
|
(setq-local fira-code-mode--old-prettify-alist prettify-symbols-alist)
|
||||||
|
(setq-local prettify-symbols-alist (append (fira-code-mode--make-alist fira-code-mode--ligatures) fira-code-mode--old-prettify-alist))
|
||||||
|
(prettify-symbols-mode t))
|
||||||
|
|
||||||
|
(defun fira-code-mode--disable ()
|
||||||
|
"Disable Fira Code ligatures in current buffer."
|
||||||
|
(setq-local prettify-symbols-alist fira-code-mode--old-prettify-alist)
|
||||||
|
(prettify-symbols-mode -1))
|
||||||
|
|
||||||
|
(define-minor-mode fira-code-mode
|
||||||
|
"Fira Code ligatures minor mode"
|
||||||
|
:lighter " Fira Code"
|
||||||
|
(setq-local prettify-symbols-unprettify-at-point 'right-edge)
|
||||||
|
(if fira-code-mode
|
||||||
|
(fira-code-mode--enable)
|
||||||
|
(fira-code-mode--disable)))
|
||||||
|
|
||||||
|
(defun fira-code-mode--setup ()
|
||||||
|
"Setup Fira Code Symbols"
|
||||||
|
(set-fontset-font t '(#Xe100 . #Xe16f) "Fira Code Symbol"))
|
||||||
|
|
||||||
|
(provide 'fira-code-mode)
|
||||||
|
|
||||||
|
Alternative instructions: https://github.com/Profpatsch/blog/blob/master/posts/ligature-emulation-in-emacs/post.md#appendix-b-update-1-firacode-integration
|
||||||
|
|
||||||
|
3. Using composition char table
|
||||||
|
|
||||||
|
Thanks to https://github.com/seanfarley for putting this together; extended by https://github.com/jrblevin.
|
||||||
|
|
||||||
|
Put this lisp in your .emacs:
|
||||||
|
|
||||||
|
(when (window-system)
|
||||||
|
(set-frame-font "Fira Code"))
|
||||||
|
(let ((alist '((33 . ".\\(?:\\(?:==\\|!!\\)\\|[!=]\\)")
|
||||||
|
(35 . ".\\(?:###\\|##\\|_(\\|[#(?[_{]\\)")
|
||||||
|
(36 . ".\\(?:>\\)")
|
||||||
|
(37 . ".\\(?:\\(?:%%\\)\\|%\\)")
|
||||||
|
(38 . ".\\(?:\\(?:&&\\)\\|&\\)")
|
||||||
|
(42 . ".\\(?:\\(?:\\*\\*/\\)\\|\\(?:\\*[*/]\\)\\|[*/>]\\)")
|
||||||
|
(43 . ".\\(?:\\(?:\\+\\+\\)\\|[+>]\\)")
|
||||||
|
(45 . ".\\(?:\\(?:-[>-]\\|<<\\|>>\\)\\|[<>}~-]\\)")
|
||||||
|
(46 . ".\\(?:\\(?:\\.[.<]\\)\\|[.=-]\\)")
|
||||||
|
(47 . ".\\(?:\\(?:\\*\\*\\|//\\|==\\)\\|[*/=>]\\)")
|
||||||
|
(48 . ".\\(?:x[a-zA-Z]\\)")
|
||||||
|
(58 . ".\\(?:::\\|[:=]\\)")
|
||||||
|
(59 . ".\\(?:;;\\|;\\)")
|
||||||
|
(60 . ".\\(?:\\(?:!--\\)\\|\\(?:~~\\|->\\|\\$>\\|\\*>\\|\\+>\\|--\\|<[<=-]\\|=[<=>]\\||>\\)\\|[*$+~/<=>|-]\\)")
|
||||||
|
(61 . ".\\(?:\\(?:/=\\|:=\\|<<\\|=[=>]\\|>>\\)\\|[<=>~]\\)")
|
||||||
|
(62 . ".\\(?:\\(?:=>\\|>[=>-]\\)\\|[=>-]\\)")
|
||||||
|
(63 . ".\\(?:\\(\\?\\?\\)\\|[:=?]\\)")
|
||||||
|
(91 . ".\\(?:]\\)")
|
||||||
|
(92 . ".\\(?:\\(?:\\\\\\\\\\)\\|\\\\\\)")
|
||||||
|
(94 . ".\\(?:=\\)")
|
||||||
|
(119 . ".\\(?:ww\\)")
|
||||||
|
(123 . ".\\(?:-\\)")
|
||||||
|
(124 . ".\\(?:\\(?:|[=|]\\)\\|[=>|]\\)")
|
||||||
|
(126 . ".\\(?:~>\\|~~\\|[>=@~-]\\)")
|
||||||
|
)
|
||||||
|
))
|
||||||
|
(dolist (char-regexp alist)
|
||||||
|
(set-char-table-range composition-function-table (car char-regexp)
|
||||||
|
`([,(cdr char-regexp) 0 font-shape-gstring]))))
|
||||||
|
|
||||||
|
**Note!** If you get `error in process filter: Attempt to shape unibyte text`, check out https://github.com/tonsky/FiraCode/issues/42. Emacs Cider users may avoid this issue by commenting the following line from the above config:
|
||||||
|
|
||||||
|
;; (46 . ".\\(?:\\(?:\\.[.<]\\)\\|[.=-]\\)")
|
||||||
|
|
||||||
|
Char `45` is also known to have issues in macOS Mojave.
|
||||||
|
|
||||||
|
If you are having problems with helm you can disable ligatures in helm:
|
||||||
|
|
||||||
|
(add-hook 'helm-major-mode-hook
|
||||||
|
(lambda ()
|
||||||
|
(setq auto-composition-mode nil)))
|
||||||
|
|
||||||
|
4. Using font-lock keywords
|
||||||
|
|
||||||
|
If none of the above worked, you can try this method.
|
||||||
|
|
||||||
|
This method requires you to install the Fira Code Symbol font, made by https://github.com/siegebell:
|
||||||
|
https://github.com/tonsky/FiraCode/issues/211#issuecomment-239058632
|
||||||
|
|
||||||
|
;;; Fira code
|
||||||
|
;; This works when using emacs --daemon + emacsclient
|
||||||
|
(add-hook 'after-make-frame-functions (lambda (frame) (set-fontset-font t '(#Xe100 . #Xe16f) "Fira Code Symbol")))
|
||||||
|
;; This works when using emacs without server/client
|
||||||
|
(set-fontset-font t '(#Xe100 . #Xe16f) "Fira Code Symbol")
|
||||||
|
;; I haven't found one statement that makes both of the above situations work, so I use both for now
|
||||||
|
|
||||||
|
(defconst fira-code-font-lock-keywords-alist
|
||||||
|
(mapcar (lambda (regex-char-pair)
|
||||||
|
`(,(car regex-char-pair)
|
||||||
|
(0 (prog1 ()
|
||||||
|
(compose-region (match-beginning 1)
|
||||||
|
(match-end 1)
|
||||||
|
;; The first argument to concat is a string containing a literal tab
|
||||||
|
,(concat " " (list (decode-char 'ucs (cadr regex-char-pair)))))))))
|
||||||
|
'(("\\(www\\)" #Xe100)
|
||||||
|
("[^/]\\(\\*\\*\\)[^/]" #Xe101)
|
||||||
|
("\\(\\*\\*\\*\\)" #Xe102)
|
||||||
|
("\\(\\*\\*/\\)" #Xe103)
|
||||||
|
("\\(\\*>\\)" #Xe104)
|
||||||
|
("[^*]\\(\\*/\\)" #Xe105)
|
||||||
|
("\\(\\\\\\\\\\)" #Xe106)
|
||||||
|
("\\(\\\\\\\\\\\\\\)" #Xe107)
|
||||||
|
("\\({-\\)" #Xe108)
|
||||||
|
("\\(\\[\\]\\)" #Xe109)
|
||||||
|
("\\(::\\)" #Xe10a)
|
||||||
|
("\\(:::\\)" #Xe10b)
|
||||||
|
("[^=]\\(:=\\)" #Xe10c)
|
||||||
|
("\\(!!\\)" #Xe10d)
|
||||||
|
("\\(!=\\)" #Xe10e)
|
||||||
|
("\\(!==\\)" #Xe10f)
|
||||||
|
("\\(-}\\)" #Xe110)
|
||||||
|
("\\(--\\)" #Xe111)
|
||||||
|
("\\(---\\)" #Xe112)
|
||||||
|
("\\(-->\\)" #Xe113)
|
||||||
|
("[^-]\\(->\\)" #Xe114)
|
||||||
|
("\\(->>\\)" #Xe115)
|
||||||
|
("\\(-<\\)" #Xe116)
|
||||||
|
("\\(-<<\\)" #Xe117)
|
||||||
|
("\\(-~\\)" #Xe118)
|
||||||
|
("\\(#{\\)" #Xe119)
|
||||||
|
("\\(#\\[\\)" #Xe11a)
|
||||||
|
("\\(##\\)" #Xe11b)
|
||||||
|
("\\(###\\)" #Xe11c)
|
||||||
|
("\\(####\\)" #Xe11d)
|
||||||
|
("\\(#(\\)" #Xe11e)
|
||||||
|
("\\(#\\?\\)" #Xe11f)
|
||||||
|
("\\(#_\\)" #Xe120)
|
||||||
|
("\\(#_(\\)" #Xe121)
|
||||||
|
("\\(\\.-\\)" #Xe122)
|
||||||
|
("\\(\\.=\\)" #Xe123)
|
||||||
|
("\\(\\.\\.\\)" #Xe124)
|
||||||
|
("\\(\\.\\.<\\)" #Xe125)
|
||||||
|
("\\(\\.\\.\\.\\)" #Xe126)
|
||||||
|
("\\(\\?=\\)" #Xe127)
|
||||||
|
("\\(\\?\\?\\)" #Xe128)
|
||||||
|
("\\(;;\\)" #Xe129)
|
||||||
|
("\\(/\\*\\)" #Xe12a)
|
||||||
|
("\\(/\\*\\*\\)" #Xe12b)
|
||||||
|
("\\(/=\\)" #Xe12c)
|
||||||
|
("\\(/==\\)" #Xe12d)
|
||||||
|
("\\(/>\\)" #Xe12e)
|
||||||
|
("\\(//\\)" #Xe12f)
|
||||||
|
("\\(///\\)" #Xe130)
|
||||||
|
("\\(&&\\)" #Xe131)
|
||||||
|
("\\(||\\)" #Xe132)
|
||||||
|
("\\(||=\\)" #Xe133)
|
||||||
|
("[^|]\\(|=\\)" #Xe134)
|
||||||
|
("\\(|>\\)" #Xe135)
|
||||||
|
("\\(\\^=\\)" #Xe136)
|
||||||
|
("\\(\\$>\\)" #Xe137)
|
||||||
|
("\\(\\+\\+\\)" #Xe138)
|
||||||
|
("\\(\\+\\+\\+\\)" #Xe139)
|
||||||
|
("\\(\\+>\\)" #Xe13a)
|
||||||
|
("\\(=:=\\)" #Xe13b)
|
||||||
|
("[^!/]\\(==\\)[^>]" #Xe13c)
|
||||||
|
("\\(===\\)" #Xe13d)
|
||||||
|
("\\(==>\\)" #Xe13e)
|
||||||
|
("[^=]\\(=>\\)" #Xe13f)
|
||||||
|
("\\(=>>\\)" #Xe140)
|
||||||
|
("\\(<=\\)" #Xe141)
|
||||||
|
("\\(=<<\\)" #Xe142)
|
||||||
|
("\\(=/=\\)" #Xe143)
|
||||||
|
("\\(>-\\)" #Xe144)
|
||||||
|
("\\(>=\\)" #Xe145)
|
||||||
|
("\\(>=>\\)" #Xe146)
|
||||||
|
("[^-=]\\(>>\\)" #Xe147)
|
||||||
|
("\\(>>-\\)" #Xe148)
|
||||||
|
("\\(>>=\\)" #Xe149)
|
||||||
|
("\\(>>>\\)" #Xe14a)
|
||||||
|
("\\(<\\*\\)" #Xe14b)
|
||||||
|
("\\(<\\*>\\)" #Xe14c)
|
||||||
|
("\\(<|\\)" #Xe14d)
|
||||||
|
("\\(<|>\\)" #Xe14e)
|
||||||
|
("\\(<\\$\\)" #Xe14f)
|
||||||
|
("\\(<\\$>\\)" #Xe150)
|
||||||
|
("\\(<!--\\)" #Xe151)
|
||||||
|
("\\(<-\\)" #Xe152)
|
||||||
|
("\\(<--\\)" #Xe153)
|
||||||
|
("\\(<->\\)" #Xe154)
|
||||||
|
("\\(<\\+\\)" #Xe155)
|
||||||
|
("\\(<\\+>\\)" #Xe156)
|
||||||
|
("\\(<=\\)" #Xe157)
|
||||||
|
("\\(<==\\)" #Xe158)
|
||||||
|
("\\(<=>\\)" #Xe159)
|
||||||
|
("\\(<=<\\)" #Xe15a)
|
||||||
|
("\\(<>\\)" #Xe15b)
|
||||||
|
("[^-=]\\(<<\\)" #Xe15c)
|
||||||
|
("\\(<<-\\)" #Xe15d)
|
||||||
|
("\\(<<=\\)" #Xe15e)
|
||||||
|
("\\(<<<\\)" #Xe15f)
|
||||||
|
("\\(<~\\)" #Xe160)
|
||||||
|
("\\(<~~\\)" #Xe161)
|
||||||
|
("\\(</\\)" #Xe162)
|
||||||
|
("\\(</>\\)" #Xe163)
|
||||||
|
("\\(~@\\)" #Xe164)
|
||||||
|
("\\(~-\\)" #Xe165)
|
||||||
|
("\\(~=\\)" #Xe166)
|
||||||
|
("\\(~>\\)" #Xe167)
|
||||||
|
("[^<]\\(~~\\)" #Xe168)
|
||||||
|
("\\(~~>\\)" #Xe169)
|
||||||
|
("\\(%%\\)" #Xe16a)
|
||||||
|
("[0\[]\\(x\\)" #Xe16b)
|
||||||
|
("[^:=]\\(:\\)[^:=]" #Xe16c)
|
||||||
|
("[^\\+<>]\\(\\+\\)[^\\+<>]" #Xe16d)
|
||||||
|
("[^\\*/<>]\\(\\*\\)[^\\*/<>]" #Xe16f))))
|
||||||
|
|
||||||
|
(defun add-fira-code-symbol-keywords ()
|
||||||
|
(font-lock-add-keywords nil fira-code-font-lock-keywords-alist))
|
||||||
|
|
||||||
|
(add-hook 'prog-mode-hook
|
||||||
|
#'add-fira-code-symbol-keywords)
|
||||||
|
|
||||||
|
On some systems, `==` will appear incorrectly as a blank space in certain modes unless you add the following lines to your init file:
|
||||||
|
|
||||||
|
(set-language-environment "UTF-8")
|
||||||
|
(set-default-coding-systems 'utf-8)
|
||||||
|
|
||||||
|
|
||||||
|
GoormIDE
|
||||||
|
--------
|
||||||
|
|
||||||
|
In a workspace:
|
||||||
|
|
||||||
|
1. Click goormIDE, then Preferences.
|
||||||
|
2. Go to Theme, then focus Custom Theme CSS.
|
||||||
|
3. Copy & paste the following:
|
||||||
|
|
||||||
|
@font-face{
|
||||||
|
font-family: 'Fira Code';
|
||||||
|
src: url('https://raw.githubusercontent.com/tonsky/FiraCode/master/distr/eot/FiraCode-Regular.eot') format('embedded-opentype'),
|
||||||
|
url('https://raw.githubusercontent.com/tonsky/FiraCode/master/distr/woff2/FiraCode-Regular.woff2') format('woff2'),
|
||||||
|
url('https://raw.githubusercontent.com/tonsky/FiraCode/master/distr/woff/FiraCode-Regular.woff') format('woff'),
|
||||||
|
url('https://raw.githubusercontent.com/tonsky/FiraCode/master/distr/ttf/FiraCode-Regular.ttf') format('truetype');
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor_container pre {
|
||||||
|
-webkit-font-feature-settings: "liga" on, "calt" on;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
font-family: 'Fira Code';
|
||||||
|
}
|
||||||
|
|
||||||
|
4. Click Aplly or OK
|
||||||
|
5. Happy coding!
|
||||||
|
|
||||||
|
|
||||||
|
Cloud9
|
||||||
|
------
|
||||||
|
|
||||||
|
In a workspace:
|
||||||
|
|
||||||
|
1. Click Cloud9, then Preferences (or use keyboard shortcut CTRL + ,)
|
||||||
|
2. Go to Themes, then click on You can also style Cloud9 by editing your stylesheet (this will open a blank styles.css file in the C9 editor)
|
||||||
|
3. Copy & paste the following:
|
||||||
|
|
||||||
|
@font-face{
|
||||||
|
font-family: 'Fira Code';
|
||||||
|
src: url('https://raw.githubusercontent.com/tonsky/FiraCode/master/distr/eot/FiraCode-Regular.eot') format('embedded-opentype'),
|
||||||
|
url('https://raw.githubusercontent.com/tonsky/FiraCode/master/distr/woff2/FiraCode-Regular.woff2') format('woff2'),
|
||||||
|
url('https://raw.githubusercontent.com/tonsky/FiraCode/master/distr/woff/FiraCode-Regular.woff') format('woff'),
|
||||||
|
url('https://raw.githubusercontent.com/tonsky/FiraCode/master/distr/ttf/FiraCode-Regular.ttf') format('truetype');
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ace_editor{
|
||||||
|
-webkit-font-feature-settings: "liga" on, "calt" on;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
font-family: 'Fira Code';
|
||||||
|
}
|
||||||
|
|
||||||
|
4. Back in Preferences tab, click on User Settings, then click on Code Editor (Ace)
|
||||||
|
5. In Font Family field, enter Fira Code
|
||||||
|
6. Optionally, repeat step 5 for Preferences > User Settings > Terminal, if you want Fira Code font in C9 terminal.
|
||||||
|
|
||||||
|
|
||||||
|
MacVim
|
||||||
|
------
|
||||||
|
|
||||||
|
Add this to ~/.gvimrc:
|
||||||
|
|
||||||
|
set macligatures
|
||||||
|
set guifont=Fira\ Code:h12
|
||||||
|
|
||||||
|
MacVim supports ligatures starting from version 7.4.
|
||||||
|
|
||||||
|
|
||||||
|
RStudio
|
||||||
|
-------
|
||||||
|
|
||||||
|
In RStudio:
|
||||||
|
|
||||||
|
1. Go to Tools > Global Options > Appearance
|
||||||
|
2. Select "Fira Code" as Editor Font. In older versions of RStudio, check "Use Ligatures".
|
||||||
|
3. Hit "OK" and enjoy
|
||||||
|
|
||||||
|
|
||||||
|
Sublime Text
|
||||||
|
------------
|
||||||
|
|
||||||
|
Preferences --> Settings
|
||||||
|
|
||||||
|
Add before "ignored_packages":
|
||||||
|
|
||||||
|
"font_face": "Fira Code",
|
||||||
|
"font_options": ["subpixel_antialias"],
|
||||||
|
|
||||||
|
If you want enable antialias, add in font_options: "gray_antialias"
|
||||||
|
|
||||||
|
|
||||||
|
Visual Studio
|
||||||
|
-------------
|
||||||
|
|
||||||
|
1. Launch Visual Studio (2015 or later).
|
||||||
|
2. Launch the Options dialog by opening the "Tools" menu and selecting "Options".
|
||||||
|
3. In the Options dialog, under the "Environment" category, you'll find "Fonts and Colors". Click on that. You'll see a combo-box on the right hand side of the dialog labelled "Font". Select "Fira Code" from that combo-box.
|
||||||
|
4. Click "OK" to dismiss.
|
||||||
|
5. Restart Visual Studio.
|
||||||
|
|
||||||
|
Now, most FiraCode ligatures will work. A notable exception is the hyphen-based ligatures (e.g. the C++ dereference '->'). See https://github.com/tonsky/FiraCode/issues/422 for details.
|
||||||
|
|
||||||
|
|
||||||
|
Troubleshooting
|
||||||
|
===============
|
||||||
|
|
||||||
|
See https://github.com/tonsky/FiraCode/wiki/Troubleshooting
|
8
build.sh
Normal file
8
build.sh
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
cc -Wall -Wextra -I src -o obj/parser.o -c src/parser.c
|
||||||
|
cc -Wall -Wextra -I src -o obj/sdl.o -c src/sdl.c
|
||||||
|
cc -Wall -Wextra -I src -o obj/interface.o -c src/interface.c
|
||||||
|
cc -Wall -Wextra -I src -o obj/lpt_parser.o -c src/lpt_parser.c
|
||||||
|
cc -Wall -Wextra -I src -o obj/input.o -c src/input.c
|
||||||
|
cc -Wall -Wextra -I src -o game obj/*.o src/main.c -l SDL2 -l SDL2_image -l SDL2_ttf -g3
|
BIN
files/backgrounds/chem1.png
Normal file
BIN
files/backgrounds/chem1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 180 KiB |
BIN
files/backgrounds/pc1.png
Normal file
BIN
files/backgrounds/pc1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 613 KiB |
BIN
files/fonts/FiraCode-Medium.ttf
Normal file
BIN
files/fonts/FiraCode-Medium.ttf
Normal file
Binary file not shown.
BIN
files/fonts/FiraCode-Regular.ttf
Normal file
BIN
files/fonts/FiraCode-Regular.ttf
Normal file
Binary file not shown.
BIN
files/images/lpt.png
Normal file
BIN
files/images/lpt.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
20
files/scenes/0.lpt
Normal file
20
files/scenes/0.lpt
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
Background:
|
||||||
|
files/backgrounds/chem1.png
|
||||||
|
|
||||||
|
AddEntity:
|
||||||
|
files/sprites/u.png
|
||||||
|
-0.5 0.5
|
||||||
|
|
||||||
|
AddEntity:
|
||||||
|
files/sprites/x.png
|
||||||
|
0.5 0.2
|
||||||
|
|
||||||
|
AddMessage:
|
||||||
|
ME
|
||||||
|
TEST
|
||||||
|
|
||||||
|
AddMessage:
|
||||||
|
U
|
||||||
|
Я ГОВОРЮЮЮЮЮюю!!
|
||||||
|
|
||||||
|
ClearEntity
|
16
files/scenes/1.lpt
Normal file
16
files/scenes/1.lpt
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#Фон
|
||||||
|
Background:
|
||||||
|
files/backgrounds/chem1.png
|
||||||
|
|
||||||
|
#Добавляет сущность
|
||||||
|
AddEntity:
|
||||||
|
files/sprites/x.png
|
||||||
|
0.3 0.1
|
||||||
|
|
||||||
|
#Добавляет сообщение
|
||||||
|
AddMessage:
|
||||||
|
ME
|
||||||
|
TEST
|
||||||
|
|
||||||
|
#Очищает экран от сущностей
|
||||||
|
ClearEntity
|
BIN
files/sprites/u.png
Normal file
BIN
files/sprites/u.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
BIN
files/sprites/x.png
Normal file
BIN
files/sprites/x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.4 KiB |
8
settings
Normal file
8
settings
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
fullscreen yes
|
||||||
|
fullscreen_custom no
|
||||||
|
vsync yes
|
||||||
|
sound_volume 100
|
||||||
|
music_volume 22
|
||||||
|
screen_h 1080
|
||||||
|
screen_w 1900
|
||||||
|
saved_scene 1
|
67
src/input.c
Normal file
67
src/input.c
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
#include "sdl.h"
|
||||||
|
#include "interface.h"
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
int Input(APP *app, char *run, FONTS *fonts, char flag) {
|
||||||
|
SDL_Event event;
|
||||||
|
|
||||||
|
while (SDL_PollEvent(&event)) {
|
||||||
|
switch (event.type) {
|
||||||
|
case SDL_KEYDOWN:
|
||||||
|
if (event.key.keysym.sym == SDLK_q) {
|
||||||
|
*run = 0;
|
||||||
|
return EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (event.key.keysym.sym == SDLK_k)
|
||||||
|
return SAVE;
|
||||||
|
|
||||||
|
else if (flag == IN_MENU) {
|
||||||
|
if (event.key.keysym.sym == SDLK_s)
|
||||||
|
return SETTINGS;
|
||||||
|
|
||||||
|
else if (event.key.keysym.sym == SDLK_c)
|
||||||
|
return CONTINUE;
|
||||||
|
|
||||||
|
else if (event.key.keysym.sym == SDLK_n)
|
||||||
|
return NEW_GAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (flag == IN_SETTINGS || flag == IN_GAME) {
|
||||||
|
if (event.key.keysym.sym == SDLK_DOWN)
|
||||||
|
return KEY_DOWN;
|
||||||
|
|
||||||
|
else if (event.key.keysym.sym == SDLK_UP)
|
||||||
|
return KEY_UP;
|
||||||
|
|
||||||
|
else if (event.key.keysym.sym == SDLK_RIGHT)
|
||||||
|
return KEY_RIGHT;
|
||||||
|
|
||||||
|
else if (event.key.keysym.sym == SDLK_LEFT)
|
||||||
|
return KEY_LEFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SDL_QUIT:
|
||||||
|
if (flag == IN_MENU)
|
||||||
|
*run = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SDL_WINDOWEVENT:
|
||||||
|
if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
||||||
|
SDL_GetWindowSize(app->window, &app->scr_width, &app->scr_height);
|
||||||
|
SDL_UpdateWindowSurface(app->window);
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseFonts(fonts);
|
||||||
|
InitFonts(fonts, *app);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return INPUT_NORMAL;
|
||||||
|
}
|
29
src/input.h
Normal file
29
src/input.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#ifndef _INPUT_H
|
||||||
|
#define _INPUT_H
|
||||||
|
|
||||||
|
#include "sdl.h"
|
||||||
|
#include "interface.h"
|
||||||
|
|
||||||
|
/* Game modes */
|
||||||
|
enum {
|
||||||
|
IN_MENU,
|
||||||
|
IN_SETTINGS,
|
||||||
|
IN_GAME
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Input events */
|
||||||
|
enum {
|
||||||
|
INPUT_NORMAL,
|
||||||
|
EXIT,
|
||||||
|
SETTINGS,
|
||||||
|
KEY_DOWN,
|
||||||
|
KEY_UP,
|
||||||
|
KEY_LEFT,
|
||||||
|
KEY_RIGHT,
|
||||||
|
SAVE,
|
||||||
|
CONTINUE,
|
||||||
|
NEW_GAME
|
||||||
|
};
|
||||||
|
|
||||||
|
int Input(APP *app, char *run, FONTS *fonts, char flag);
|
||||||
|
#endif
|
95
src/interface.c
Normal file
95
src/interface.c
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "sdl.h"
|
||||||
|
#include "interface.h"
|
||||||
|
|
||||||
|
int TextArray(TEXT text[], size_t n, char flag) {
|
||||||
|
for (size_t i = 0; i < n; i++) {
|
||||||
|
if (flag == TEXT_ARRAY_FREE && text[i].texture)
|
||||||
|
SDL_DestroyTexture(text[i].texture);
|
||||||
|
|
||||||
|
else if (flag == TEXT_ARRAY_SCAN && text[i].init == 0) {
|
||||||
|
fputs("Found uninitialized font\n", stderr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintText(TTF_Font *font, APP *app, TEXT *dst, const char *text) {
|
||||||
|
SDL_Surface *temp = TTF_RenderUTF8_Solid(font, text, dst->color);
|
||||||
|
if (!temp) {
|
||||||
|
fprintf(stderr, "AddBanner Font: %s\n", TTF_GetError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst->texture = SDL_CreateTextureFromSurface(app->render, temp);
|
||||||
|
if (!dst->texture) {
|
||||||
|
SDL_FreeSurface(temp);
|
||||||
|
fprintf(stderr, "AddBanner Font: %s\n", TTF_GetError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_FreeSurface(temp);
|
||||||
|
|
||||||
|
/* Write text size in to a structure */
|
||||||
|
if (TTF_SizeText(font, text, &dst->w, &dst->h) < 0) {
|
||||||
|
SDL_DestroyTexture(dst->texture);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst->init = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddBanner(APP *app, TEXT text, SDL_Rect rect) {
|
||||||
|
/* Box */
|
||||||
|
SDL_SetRenderDrawColor(app->render, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
SDL_RenderDrawRect(app->render, &rect);
|
||||||
|
|
||||||
|
/* Text */
|
||||||
|
if (text.w < rect.w)
|
||||||
|
rect.w = text.w;
|
||||||
|
|
||||||
|
SDL_RenderCopy(app->render, text.texture, NULL, &rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddPseudoButton(APP *app, TEXT text, const int bttn_num) {
|
||||||
|
int rect_x = APPROX2ORIG(app->scr_width, -0.8);
|
||||||
|
SDL_Rect rect = {
|
||||||
|
.x = rect_x,
|
||||||
|
.y = APPROX2ORIG(app->scr_height, (0.75 - (0.2 * bttn_num))),
|
||||||
|
.w = app->scr_width - (rect_x * 2),
|
||||||
|
.h = 45
|
||||||
|
};
|
||||||
|
|
||||||
|
AddBanner(app, text, rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CloseFonts(FONTS *fonts) {
|
||||||
|
if (fonts->font1)
|
||||||
|
TTF_CloseFont(fonts->font1);
|
||||||
|
|
||||||
|
if (fonts->font2)
|
||||||
|
TTF_CloseFont(fonts->font2);
|
||||||
|
|
||||||
|
memset(fonts, 0, sizeof(FONTS));
|
||||||
|
}
|
||||||
|
|
||||||
|
int InitFonts(FONTS *fonts, const APP app) {
|
||||||
|
memset(fonts, 0, sizeof(FONTS));
|
||||||
|
|
||||||
|
size_t font_size = app.scr_width * app.scr_height * 8 / 403200;
|
||||||
|
fonts->font1 = TTF_OpenFont(FONT1, font_size);
|
||||||
|
|
||||||
|
font_size = app.scr_width * app.scr_height * 15 / 403200;
|
||||||
|
fonts->font2 = TTF_OpenFont(FONT1, font_size);
|
||||||
|
|
||||||
|
if (fonts->font1 == NULL || fonts->font2 == NULL) {
|
||||||
|
fprintf(stderr, "Can not open font: %s\n", TTF_GetError());
|
||||||
|
CloseFonts(fonts);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
36
src/interface.h
Normal file
36
src/interface.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#ifndef _INTERFACE_SDL
|
||||||
|
#define _INTERFACE_SDL
|
||||||
|
|
||||||
|
#include "sdl.h"
|
||||||
|
|
||||||
|
#define FONT1 "files/fonts/FiraCode-Regular.ttf"
|
||||||
|
#define FONT2 "files/fonts/FiraCode-Medium.ttf"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TEXT_ARRAY_FREE = 1,
|
||||||
|
TEXT_ARRAY_SCAN
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
TTF_Font *font1;
|
||||||
|
TTF_Font *font2;
|
||||||
|
} FONTS;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SDL_Texture *texture;
|
||||||
|
SDL_Color color;
|
||||||
|
|
||||||
|
int w;
|
||||||
|
int h;
|
||||||
|
|
||||||
|
/* Status of initialization */
|
||||||
|
int init;
|
||||||
|
} TEXT;
|
||||||
|
|
||||||
|
int TextArray(TEXT text[], size_t n, char flag);
|
||||||
|
void PrintText(TTF_Font *font, APP *app, TEXT *dst, const char *text);
|
||||||
|
void AddBanner(APP *app, TEXT text, SDL_Rect rect);
|
||||||
|
void AddPseudoButton(APP *app, TEXT text, const int bttn_num);
|
||||||
|
void CloseFonts(FONTS *fonts);
|
||||||
|
int InitFonts(FONTS *fonts, const APP app);
|
||||||
|
#endif
|
265
src/lpt_parser.c
Normal file
265
src/lpt_parser.c
Normal file
|
@ -0,0 +1,265 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include "interface.h"
|
||||||
|
#include "sdl.h"
|
||||||
|
#include "parser.h"
|
||||||
|
#include "lpt_parser.h"
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PARSER_NORMAL,
|
||||||
|
BACKGROUND,
|
||||||
|
|
||||||
|
ADD_ENTITY,
|
||||||
|
ADD_ENTITY_ARG2,
|
||||||
|
|
||||||
|
ADD_MESSAGE,
|
||||||
|
ADD_MESSAGE_ARG2
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ENTITY {
|
||||||
|
float x;
|
||||||
|
float scale;
|
||||||
|
SDL_Texture *texture;
|
||||||
|
|
||||||
|
struct ENTITY *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
void free_chain(struct ENTITY **ent) {
|
||||||
|
while (*ent != NULL) {
|
||||||
|
struct ENTITY *i = (*ent)->next;
|
||||||
|
|
||||||
|
if ((*ent)->texture)
|
||||||
|
SDL_DestroyTexture((*ent)->texture);
|
||||||
|
|
||||||
|
free(*ent);
|
||||||
|
*ent = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int DisplayScene(SDL_Texture *background, TEXT author, TEXT message, APP *app, FONTS *fonts, CONFIG cfg, struct ENTITY *ent) {
|
||||||
|
char run = LPTP_NORMAL;
|
||||||
|
|
||||||
|
while (run == LPTP_NORMAL) {
|
||||||
|
int status = Input(app, &run, fonts, IN_GAME);
|
||||||
|
switch (status) {
|
||||||
|
case EXIT:
|
||||||
|
run = MENU;
|
||||||
|
/* fallthrough */
|
||||||
|
|
||||||
|
case SAVE:
|
||||||
|
WriteCfg(cfg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_RIGHT:
|
||||||
|
run = NEXT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Background */
|
||||||
|
SDL_SetRenderDrawColor(app->render, 0xFF, 0xFF, 0xFF, 0xFF);
|
||||||
|
SDL_RenderClear(app->render);
|
||||||
|
|
||||||
|
SDL_RenderCopy(app->render, background, NULL, NULL);
|
||||||
|
|
||||||
|
/* Entities */
|
||||||
|
struct ENTITY *bckp = ent;
|
||||||
|
while (bckp != NULL) {
|
||||||
|
struct ENTITY *i = bckp->next;
|
||||||
|
|
||||||
|
int w = 0, h = 0;
|
||||||
|
SDL_QueryTexture(bckp->texture, NULL, NULL, &w, &h);
|
||||||
|
|
||||||
|
SDL_Rect rect = {
|
||||||
|
.x = APPROX2ORIG(app->scr_width, bckp->x),
|
||||||
|
.y = APPROX2ORIG(app->scr_height, 0),
|
||||||
|
.w = w * bckp->scale,
|
||||||
|
.h = h * bckp->scale
|
||||||
|
};
|
||||||
|
|
||||||
|
if (bckp->texture)
|
||||||
|
SDL_RenderCopy(app->render, bckp->texture, NULL, &rect);
|
||||||
|
|
||||||
|
bckp = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dialog */
|
||||||
|
AddPseudoButton(app, message, 0);
|
||||||
|
AddPseudoButton(app, author, 1);
|
||||||
|
|
||||||
|
/* Render */
|
||||||
|
SDL_RenderPresent(app->render);
|
||||||
|
SDL_Delay(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
return run;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lpt_parser(APP *app, FONTS *fonts, CONFIG *cfg) {
|
||||||
|
char path[PATH_MAX + 1];
|
||||||
|
snprintf(path, sizeof(path), "files/scenes/%d.lpt", cfg->saved_scene);
|
||||||
|
|
||||||
|
FILE *fp = OpenFile(path, "r");
|
||||||
|
if (fp == NULL) {
|
||||||
|
fputs("Maybe it's error?? Or endgame\n", stderr);
|
||||||
|
return ENDGAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
char ret = ERROR;
|
||||||
|
|
||||||
|
/* Parser */
|
||||||
|
char *raw_str = NULL;
|
||||||
|
ssize_t bytes = 0;
|
||||||
|
size_t n = 0;
|
||||||
|
size_t line = 0;
|
||||||
|
char flag = PARSER_NORMAL;
|
||||||
|
|
||||||
|
/* For scene */
|
||||||
|
SDL_Texture *background = NULL;
|
||||||
|
|
||||||
|
TEXT author, msg;
|
||||||
|
memset(&author, 0, sizeof(author));
|
||||||
|
msg = author;
|
||||||
|
|
||||||
|
struct ENTITY *entities = NULL;
|
||||||
|
struct ENTITY *ptr = NULL;
|
||||||
|
|
||||||
|
while ((bytes = getline(&raw_str, &n, fp)) > 0) {
|
||||||
|
line++;
|
||||||
|
|
||||||
|
raw_str[strcspn(raw_str, "\n")] = '\0';
|
||||||
|
|
||||||
|
char *str = raw_str;
|
||||||
|
while (isspace(*str))
|
||||||
|
str++;
|
||||||
|
|
||||||
|
if (*str == '#')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (flag == BACKGROUND) {
|
||||||
|
if (background)
|
||||||
|
SDL_DestroyTexture(background);
|
||||||
|
|
||||||
|
background = LoadIMG_SDL(str, app);
|
||||||
|
if (background == NULL)
|
||||||
|
goto LPT_PARSER_CLOSE_UP;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (flag == ADD_MESSAGE) {
|
||||||
|
if (author.init)
|
||||||
|
SDL_DestroyTexture(author.texture);
|
||||||
|
|
||||||
|
memset(&author, 0, sizeof(author));
|
||||||
|
|
||||||
|
PrintText(fonts->font1, app, &author, str);
|
||||||
|
if (author.init == 0)
|
||||||
|
goto LPT_PARSER_CLOSE_UP;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (flag == ADD_MESSAGE_ARG2) {
|
||||||
|
if (msg.init)
|
||||||
|
SDL_DestroyTexture(msg.texture);
|
||||||
|
|
||||||
|
memset(&msg, 0, sizeof(msg));
|
||||||
|
|
||||||
|
PrintText(fonts->font1, app, &msg, str);
|
||||||
|
if (msg.init == 0)
|
||||||
|
goto LPT_PARSER_CLOSE_UP;
|
||||||
|
|
||||||
|
if (DisplayScene(background, author, msg, app, fonts, *cfg, entities) == MENU) {
|
||||||
|
ret = MENU;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (flag == ADD_ENTITY) {
|
||||||
|
entities = malloc(sizeof(struct ENTITY));
|
||||||
|
if (entities == NULL) {
|
||||||
|
fprintf(stderr, "LPT_parser: failed to add entitiy: malloc: %s\n", strerror(errno));
|
||||||
|
goto LPT_PARSER_CLOSE_UP;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(entities, 0, sizeof(struct ENTITY));
|
||||||
|
entities->texture = LoadIMG_SDL(str, app);
|
||||||
|
if (entities->texture == NULL)
|
||||||
|
goto LPT_PARSER_CLOSE_UP;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (flag == ADD_ENTITY_ARG2) {
|
||||||
|
char *tok_rest = str;
|
||||||
|
char *x_pos = strtok_r(tok_rest, " ", &tok_rest);
|
||||||
|
char *scale = strtok_r(tok_rest, " ", &tok_rest);
|
||||||
|
if (scale == NULL || x_pos == NULL) {
|
||||||
|
fprintf(stderr, "SCENE %d:%ld: invalid syntax: %s\n", cfg->saved_scene, line, str);
|
||||||
|
goto LPT_PARSER_CLOSE_UP;
|
||||||
|
}
|
||||||
|
|
||||||
|
entities->x = atof(x_pos);
|
||||||
|
entities->scale = atof(scale);
|
||||||
|
|
||||||
|
entities->next = ptr;
|
||||||
|
ptr = entities;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parsing file */
|
||||||
|
if (flag == PARSER_NORMAL && bytes > 1) {
|
||||||
|
if (!strcmp(str, "Background:"))
|
||||||
|
flag = BACKGROUND;
|
||||||
|
|
||||||
|
else if (!strcmp(str, "AddEntity:"))
|
||||||
|
flag = ADD_ENTITY;
|
||||||
|
|
||||||
|
else if (!strcmp(str, "AddMessage:"))
|
||||||
|
flag = ADD_MESSAGE;
|
||||||
|
|
||||||
|
else if (!strcmp(str, "ClearEntity")) {
|
||||||
|
free_chain(&entities);
|
||||||
|
ptr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "SCENE %d:%ld : invalid syntax: %s\n", cfg->saved_scene, line, str);
|
||||||
|
goto LPT_PARSER_CLOSE_UP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
if (flag == ADD_MESSAGE)
|
||||||
|
flag = ADD_MESSAGE_ARG2;
|
||||||
|
|
||||||
|
else if (flag == ADD_ENTITY)
|
||||||
|
flag = ADD_ENTITY_ARG2;
|
||||||
|
|
||||||
|
else
|
||||||
|
flag = PARSER_NORMAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != MENU)
|
||||||
|
ret = LPTP_NORMAL;
|
||||||
|
|
||||||
|
/* Close up */
|
||||||
|
LPT_PARSER_CLOSE_UP:
|
||||||
|
if (raw_str)
|
||||||
|
free(raw_str);
|
||||||
|
|
||||||
|
if (background)
|
||||||
|
SDL_DestroyTexture(background);
|
||||||
|
|
||||||
|
if (author.init)
|
||||||
|
SDL_DestroyTexture(author.texture);
|
||||||
|
|
||||||
|
if (msg.init)
|
||||||
|
SDL_DestroyTexture(msg.texture);
|
||||||
|
|
||||||
|
free_chain(&entities);
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
return ret;
|
||||||
|
}
|
17
src/lpt_parser.h
Normal file
17
src/lpt_parser.h
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#ifndef _LPT_PARSER_H
|
||||||
|
#define _LPT_PARSER_H
|
||||||
|
|
||||||
|
#include "sdl.h"
|
||||||
|
#include "interface.h"
|
||||||
|
#include "parser.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
LPTP_NORMAL = 1,
|
||||||
|
ERROR,
|
||||||
|
ENDGAME,
|
||||||
|
MENU,
|
||||||
|
NEXT
|
||||||
|
};
|
||||||
|
|
||||||
|
int lpt_parser(APP *app, FONTS *fonts, CONFIG *cfg);
|
||||||
|
#endif
|
318
src/main.c
Normal file
318
src/main.c
Normal file
|
@ -0,0 +1,318 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include "lpt_parser.h"
|
||||||
|
#include "parser.h"
|
||||||
|
#include "sdl.h"
|
||||||
|
#include "interface.h"
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
void AddOption(TTF_Font *font, APP *app, TEXT text, const int bttn_num, const int opt_value, const int flag) {
|
||||||
|
AddPseudoButton(app, text, bttn_num);
|
||||||
|
|
||||||
|
|
||||||
|
/* Create texture for value */
|
||||||
|
char str[16];
|
||||||
|
if (flag == 1)
|
||||||
|
snprintf(str, sizeof(str), "%s", (opt_value) ? "Y" : "N");
|
||||||
|
|
||||||
|
else if (flag == 2)
|
||||||
|
snprintf(str, sizeof(str), "%d%%", opt_value);
|
||||||
|
|
||||||
|
else
|
||||||
|
snprintf(str, sizeof(str), "%d", opt_value);
|
||||||
|
|
||||||
|
TEXT value;
|
||||||
|
memset(&value, 0, sizeof(value));
|
||||||
|
|
||||||
|
PrintText(font, app, &value, str);
|
||||||
|
if (value.init == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
/* Print it */
|
||||||
|
int rect_x = APPROX2ORIG(app->scr_width, -0.8);
|
||||||
|
SDL_Rect rect = {
|
||||||
|
.x = app->scr_width - rect_x - value.w - 20,
|
||||||
|
.y = APPROX2ORIG(app->scr_height, (0.75 - (0.2 * bttn_num))),
|
||||||
|
.w = value.w + 20,
|
||||||
|
.h = 45
|
||||||
|
};
|
||||||
|
|
||||||
|
SDL_RenderCopy(app->render, value.texture, NULL, &rect);
|
||||||
|
SDL_DestroyTexture(value.texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main_menu(APP *app, FONTS *fonts, CONFIG *cfg) {
|
||||||
|
char run = 1;
|
||||||
|
char mode = IN_MENU;
|
||||||
|
size_t index = 0;
|
||||||
|
int *value = NULL;
|
||||||
|
char changed = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* LPT LOGO */
|
||||||
|
SDL_Texture *logo = LoadIMG_SDL("files/images/lpt.png", app);
|
||||||
|
if (logo == NULL)
|
||||||
|
run = -1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Setup menu text */
|
||||||
|
TEXT text_new_game, text_continue, text_settings, text_quit, text_save;
|
||||||
|
memset(&text_new_game, 0, sizeof(text_new_game));
|
||||||
|
text_continue = text_settings = text_quit = text_save = text_new_game;
|
||||||
|
|
||||||
|
PrintText(fonts->font1, app, &text_new_game, "[n] New Game");
|
||||||
|
PrintText(fonts->font1, app, &text_continue, "[c] Continue");
|
||||||
|
PrintText(fonts->font1, app, &text_settings, "[s] Settings");
|
||||||
|
PrintText(fonts->font1, app, &text_save, "[k] Save");
|
||||||
|
PrintText(fonts->font1, app, &text_quit, "[q] Quit");
|
||||||
|
|
||||||
|
TEXT menu_msgs[] = {text_quit, text_settings, text_new_game, text_save, text_continue};
|
||||||
|
size_t menu_size = sizeof(menu_msgs) / sizeof(TEXT);
|
||||||
|
if (TextArray(menu_msgs, menu_size, TEXT_ARRAY_SCAN))
|
||||||
|
run = -1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Setup settings text */
|
||||||
|
TEXT settings, fullscreen, fullscreen_custom, vsync, sound_vol, music_vol, screen_h, screen_w, pointer, text_back;
|
||||||
|
memset(&settings, 0, sizeof(settings));
|
||||||
|
fullscreen = fullscreen_custom = vsync = sound_vol = music_vol = screen_h = screen_w = pointer = text_back = settings;
|
||||||
|
|
||||||
|
PrintText(fonts->font1, app, &fullscreen, "Fullscreen mode:");
|
||||||
|
PrintText(fonts->font1, app, &fullscreen_custom, "Custom resolution for fullscreen: Y");
|
||||||
|
PrintText(fonts->font1, app, &vsync, "VSync:");
|
||||||
|
PrintText(fonts->font1, app, &sound_vol, "Sound volume:");
|
||||||
|
PrintText(fonts->font1, app, &music_vol, "Music volume:");
|
||||||
|
PrintText(fonts->font1, app, &screen_h, "Screen height:");
|
||||||
|
PrintText(fonts->font1, app, &screen_w, "Screen width:");
|
||||||
|
PrintText(fonts->font1, app, &text_back, "[q] Back");
|
||||||
|
PrintText(fonts->font1, app, &settings, "[settings] Restart requied...");
|
||||||
|
PrintText(fonts->font2, app, &pointer, ">");
|
||||||
|
|
||||||
|
TEXT settings_msgs[] = {fullscreen, fullscreen_custom, vsync, sound_vol, music_vol, screen_h, screen_w, text_save, text_back, pointer, settings};
|
||||||
|
int *settings_opt[] = {&cfg->fullscreen, &cfg->fullscreen_custom, &cfg->vsync, &cfg->sound_volume, &cfg->music_volume, &cfg->screen_h, &cfg->screen_w};
|
||||||
|
size_t settings_size = sizeof(settings_msgs) / sizeof(TEXT);
|
||||||
|
if (TextArray(settings_msgs, settings_size, TEXT_ARRAY_SCAN))
|
||||||
|
run = -1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Game loop */
|
||||||
|
while (run > 0) {
|
||||||
|
if (value == NULL)
|
||||||
|
value = settings_opt[1];
|
||||||
|
|
||||||
|
|
||||||
|
/* Input and navigation */
|
||||||
|
int status = Input(app, &run, fonts, mode);
|
||||||
|
switch (status) {
|
||||||
|
case SETTINGS:
|
||||||
|
mode = IN_SETTINGS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_DOWN:
|
||||||
|
if (index > 0) {
|
||||||
|
index--;
|
||||||
|
value = settings_opt[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_UP:
|
||||||
|
if (index < settings_size - 5) {
|
||||||
|
index++;
|
||||||
|
value = settings_opt[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_LEFT:
|
||||||
|
changed = 1;
|
||||||
|
if ((value == &cfg->screen_w && *value > 639) || (value == &cfg->screen_h && *value > 479))
|
||||||
|
(*value)--;
|
||||||
|
|
||||||
|
else if (*value > 0)
|
||||||
|
(*value)--;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_RIGHT:
|
||||||
|
changed = 1;
|
||||||
|
if (value == &cfg->fullscreen || value == &cfg->fullscreen_custom || value == &cfg->vsync)
|
||||||
|
*value = 1;
|
||||||
|
|
||||||
|
else if ((value == &cfg->music_volume && *value < 100) || (value == &cfg->sound_volume && *value < 100))
|
||||||
|
(*value) += 2;
|
||||||
|
|
||||||
|
else if (value == &cfg->screen_w || value == &cfg->screen_h)
|
||||||
|
(*value) += 5;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SAVE:
|
||||||
|
changed = 0;
|
||||||
|
if (WriteCfg(*cfg))
|
||||||
|
run = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NEW_GAME:
|
||||||
|
cfg->saved_scene = 0;
|
||||||
|
/* fallthrough */
|
||||||
|
|
||||||
|
case CONTINUE:
|
||||||
|
char game_run = 1;
|
||||||
|
while (game_run > 0) {
|
||||||
|
game_run = lpt_parser(app, fonts, cfg);
|
||||||
|
if (game_run == ERROR) {
|
||||||
|
run = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (game_run == MENU)
|
||||||
|
break;
|
||||||
|
|
||||||
|
else if (game_run == LPTP_NORMAL)
|
||||||
|
cfg->saved_scene++;
|
||||||
|
|
||||||
|
else if (game_run == ENDGAME) {
|
||||||
|
cfg->saved_scene = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Background */
|
||||||
|
SDL_SetRenderDrawColor(app->render, 0xFF, 0xFF, 0xFF, 0xFF);
|
||||||
|
SDL_RenderClear(app->render);
|
||||||
|
|
||||||
|
|
||||||
|
/* Create GUI */
|
||||||
|
if (mode == IN_MENU) {
|
||||||
|
/* Logo */
|
||||||
|
SDL_Rect rect = {
|
||||||
|
.x = APPROX2ORIG(app->scr_width, -0.5),
|
||||||
|
.y = APPROX2ORIG(app->scr_height, -0.5),
|
||||||
|
.w = 128 * 2,
|
||||||
|
.h = 64 * 2
|
||||||
|
};
|
||||||
|
|
||||||
|
SDL_RenderCopy(app->render, logo, NULL, &rect);
|
||||||
|
|
||||||
|
/* Menu */
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < menu_size - 1; i++)
|
||||||
|
AddPseudoButton(app, menu_msgs[i], i);
|
||||||
|
|
||||||
|
if (cfg->saved_scene > 0)
|
||||||
|
AddPseudoButton(app, menu_msgs[i], i);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (mode == IN_SETTINGS) {
|
||||||
|
/* Menu */
|
||||||
|
AddOption(fonts->font1, app, fullscreen, 0, cfg->fullscreen, 1);
|
||||||
|
AddOption(fonts->font1, app, fullscreen_custom, 1, cfg->fullscreen_custom, 1);
|
||||||
|
AddOption(fonts->font1, app, vsync, 2, cfg->vsync, 1);
|
||||||
|
AddOption(fonts->font1, app, sound_vol, 3, cfg->sound_volume, 2);
|
||||||
|
AddOption(fonts->font1, app, music_vol, 4, cfg->music_volume, 2);
|
||||||
|
AddOption(fonts->font1, app, screen_h, 5, cfg->screen_h, 0);
|
||||||
|
AddOption(fonts->font1, app, screen_w, 6, cfg->screen_w, 0);
|
||||||
|
AddPseudoButton(app, text_back, 7);
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
AddPseudoButton(app, text_save, 8);
|
||||||
|
|
||||||
|
/* Pointer */
|
||||||
|
SDL_Rect rect = {
|
||||||
|
.x = 0,
|
||||||
|
.y = APPROX2ORIG(app->scr_height, (0.75 - (0.2 * index))),
|
||||||
|
.w = pointer.w,
|
||||||
|
.h = pointer.h
|
||||||
|
};
|
||||||
|
|
||||||
|
SDL_RenderCopy(app->render, pointer.texture, NULL, &rect);
|
||||||
|
|
||||||
|
/* Title */
|
||||||
|
rect.y = 0;
|
||||||
|
rect.w = settings.w;
|
||||||
|
rect.h = settings.h;
|
||||||
|
SDL_RenderCopy(app->render, settings.texture, NULL, &rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (run == 0 && mode == IN_SETTINGS) {
|
||||||
|
mode = IN_MENU;
|
||||||
|
run = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Render */
|
||||||
|
SDL_RenderPresent(app->render);
|
||||||
|
SDL_Delay(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Free structures */
|
||||||
|
if (logo)
|
||||||
|
SDL_DestroyTexture(logo);
|
||||||
|
|
||||||
|
TextArray(menu_msgs, menu_size, TEXT_ARRAY_FREE);
|
||||||
|
TextArray(settings_msgs, menu_size, TEXT_ARRAY_FREE);
|
||||||
|
return (run == -1) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
/* Config */
|
||||||
|
CONFIG cfg = {
|
||||||
|
.fullscreen = 1,
|
||||||
|
.fullscreen_custom = 0,
|
||||||
|
.screen_w = 480,
|
||||||
|
.screen_h = 640,
|
||||||
|
.sound_volume = 100,
|
||||||
|
.music_volume = 20,
|
||||||
|
.vsync = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (access(CONFIG_FILE, R_OK) < 0) {
|
||||||
|
fprintf(stderr, "Failed to open %s: %s. Creating...\n", CONFIG_FILE, strerror(errno));
|
||||||
|
WriteCfg(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
ReadCfg(&cfg);
|
||||||
|
|
||||||
|
/* Init SDL */
|
||||||
|
APP app;
|
||||||
|
if (Init_SDL(cfg, &app))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
FONTS fonts;
|
||||||
|
if (InitFonts(&fonts, app))
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
/* Game loop*/
|
||||||
|
if (!ret)
|
||||||
|
ret = main_menu(&app, &fonts, &cfg);
|
||||||
|
|
||||||
|
/* Clean up */
|
||||||
|
CloseFonts(&fonts);
|
||||||
|
CleanUp_SDL(&app);
|
||||||
|
if (ret)
|
||||||
|
fputs("Game returned 1: interal error\n", stderr);
|
||||||
|
|
||||||
|
fputs("Thanks for playing\n", stderr);
|
||||||
|
return ret;
|
||||||
|
}
|
86
src/parser.c
Normal file
86
src/parser.c
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "parser.h"
|
||||||
|
|
||||||
|
#define YesOrNo() ((strcmp(val, "yes") > 0) ? 1 : 0)
|
||||||
|
|
||||||
|
FILE *OpenFile(const char *file, const char *mode) {
|
||||||
|
FILE *fp = fopen(file, mode);
|
||||||
|
if (fp == NULL)
|
||||||
|
fprintf(stderr, "Can not open %s with %s mode\n", file, mode);
|
||||||
|
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ReadCfg(CONFIG *cfg) {
|
||||||
|
memset(cfg, 0, sizeof(CONFIG));
|
||||||
|
|
||||||
|
FILE *fp = OpenFile(CONFIG_FILE, "r");
|
||||||
|
if (fp == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
char *str = NULL;
|
||||||
|
ssize_t bytes = 0;
|
||||||
|
size_t n = 0;
|
||||||
|
|
||||||
|
while ((bytes = getline(&str, &n, fp)) > 0) {
|
||||||
|
char *tok_rest = str;
|
||||||
|
char *var = strtok_r(tok_rest, " ", &tok_rest);
|
||||||
|
char *val = strtok_r(tok_rest, " ", &tok_rest);
|
||||||
|
|
||||||
|
if (var == NULL || val == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (var[0] == '#')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
else if (!strcmp(var, "fullscreen"))
|
||||||
|
cfg->fullscreen = YesOrNo();
|
||||||
|
|
||||||
|
else if (!strcmp(var, "fullscreen_custom"))
|
||||||
|
cfg->fullscreen_custom = YesOrNo();
|
||||||
|
|
||||||
|
else if (!strcmp(var, "vsync"))
|
||||||
|
cfg->vsync = YesOrNo();
|
||||||
|
|
||||||
|
else if (!strcmp(var, "sound_volume"))
|
||||||
|
cfg->sound_volume = atoi(val);
|
||||||
|
|
||||||
|
else if (!strcmp(var, "music_volume"))
|
||||||
|
cfg->music_volume = atoi(val);
|
||||||
|
|
||||||
|
else if (!strcmp(var, "screen_h"))
|
||||||
|
cfg->screen_h = atoi(val);
|
||||||
|
|
||||||
|
else if (!strcmp(var, "screen_w"))
|
||||||
|
cfg->screen_w = atoi(val);
|
||||||
|
|
||||||
|
else if (!strcmp(var, "saved_scene"))
|
||||||
|
cfg->saved_scene = atoi(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str)
|
||||||
|
free(str);
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WriteCfg(const CONFIG cfg) {
|
||||||
|
FILE *fp = OpenFile(CONFIG_FILE, "w");
|
||||||
|
if (fp == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
fprintf(fp, "fullscreen %s\n", (cfg.fullscreen) ? "yes" : "no");
|
||||||
|
fprintf(fp, "fullscreen_custom %s\n", (cfg.fullscreen_custom) ? "yes" : "no");
|
||||||
|
fprintf(fp, "vsync %s\n", (cfg.vsync) ? "yes" : "no");
|
||||||
|
fprintf(fp, "sound_volume %d\n", cfg.sound_volume);
|
||||||
|
fprintf(fp, "music_volume %d\n", cfg.music_volume);
|
||||||
|
fprintf(fp, "screen_h %d\n", cfg.screen_h);
|
||||||
|
fprintf(fp, "screen_w %d\n", cfg.screen_w);
|
||||||
|
fprintf(fp, "saved_scene %d\n", cfg.saved_scene);
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
return 0;
|
||||||
|
}
|
25
src/parser.h
Normal file
25
src/parser.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef _PARSER_H
|
||||||
|
#define _PARSER_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define CONFIG_FILE "settings"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int fullscreen;
|
||||||
|
int fullscreen_custom;
|
||||||
|
int vsync;
|
||||||
|
|
||||||
|
int screen_w;
|
||||||
|
int screen_h;
|
||||||
|
|
||||||
|
int sound_volume;
|
||||||
|
int music_volume;
|
||||||
|
|
||||||
|
int saved_scene;
|
||||||
|
} CONFIG;
|
||||||
|
|
||||||
|
FILE *OpenFile(const char *file, const char *mode);
|
||||||
|
int ReadCfg(CONFIG *cfg);
|
||||||
|
int WriteCfg(const CONFIG cfg);
|
||||||
|
#endif
|
95
src/sdl.c
Normal file
95
src/sdl.c
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "sdl.h"
|
||||||
|
#include "parser.h"
|
||||||
|
|
||||||
|
void CleanUp_SDL(APP *app) {
|
||||||
|
if (app->window)
|
||||||
|
SDL_DestroyWindow(app->window);
|
||||||
|
|
||||||
|
if (app->render)
|
||||||
|
SDL_DestroyRenderer(app->render);
|
||||||
|
|
||||||
|
SDL_Quit();
|
||||||
|
IMG_Quit();
|
||||||
|
TTF_Quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Init_SDL(const CONFIG cfg, APP *app) {
|
||||||
|
memset(app, 0, sizeof(APP));
|
||||||
|
|
||||||
|
int status = 0;
|
||||||
|
if (SDL_Init(SDL_INIT_VIDEO) < 0)
|
||||||
|
goto Init_SDL_CLOSE;
|
||||||
|
|
||||||
|
/* Get display mode if fullscreen enabled in config */
|
||||||
|
app->scr_width = cfg.screen_w;
|
||||||
|
app->scr_height = cfg.screen_h;
|
||||||
|
int fullscreen = 0;
|
||||||
|
|
||||||
|
if (cfg.fullscreen) {
|
||||||
|
if (!cfg.fullscreen_custom) {
|
||||||
|
SDL_DisplayMode dm;
|
||||||
|
if (SDL_GetDesktopDisplayMode(0, &dm) < 0)
|
||||||
|
goto Init_SDL_CLOSE;
|
||||||
|
|
||||||
|
app->scr_width = dm.w;
|
||||||
|
app->scr_height = dm.h;
|
||||||
|
}
|
||||||
|
|
||||||
|
fullscreen = SDL_WINDOW_FULLSCREEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Creating window */
|
||||||
|
app->window = SDL_CreateWindow("LPT", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, app->scr_width, app->scr_height, SDL_WINDOW_RESIZABLE | fullscreen);
|
||||||
|
if (!app->window)
|
||||||
|
goto Init_SDL_CLOSE;
|
||||||
|
SDL_SetWindowMinimumSize(app->window, 640, 480);
|
||||||
|
|
||||||
|
/* Renderer */
|
||||||
|
app->render = SDL_CreateRenderer(app->window, -1, SDL_RENDERER_ACCELERATED | (cfg.vsync) ? SDL_RENDERER_PRESENTVSYNC : 0);
|
||||||
|
if (!app->render)
|
||||||
|
goto Init_SDL_CLOSE;
|
||||||
|
|
||||||
|
/* Image subsystem */
|
||||||
|
status = 1;
|
||||||
|
int flags = IMG_INIT_PNG;
|
||||||
|
if (!(IMG_Init(flags) & flags))
|
||||||
|
goto Init_SDL_CLOSE;
|
||||||
|
|
||||||
|
/* Font subsystem */
|
||||||
|
status = 2;
|
||||||
|
if (TTF_Init() < 0)
|
||||||
|
goto Init_SDL_CLOSE;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
Init_SDL_CLOSE:
|
||||||
|
if (status == 1)
|
||||||
|
fprintf(stderr, "Could not initialize SDL_IMG: %s\n", IMG_GetError());
|
||||||
|
|
||||||
|
if (status == 2)
|
||||||
|
fprintf(stderr, "Could not initialize SDL_TTF: %s\n", TTF_GetError());
|
||||||
|
|
||||||
|
else
|
||||||
|
fprintf(stderr, "Could not initialize SDL: %s\n", SDL_GetError());
|
||||||
|
|
||||||
|
CleanUp_SDL(app);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Texture *LoadIMG_SDL(const char *path, APP *app) {
|
||||||
|
if (path == NULL) {
|
||||||
|
fputs("LoadIMG: path is NULL. Maybe incorrect scene syntax\n", stderr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Texture *text = IMG_LoadTexture(app->render, path);
|
||||||
|
if (text == NULL) {
|
||||||
|
fprintf(stderr, "LoadIMG: %s\n", SDL_GetError());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
24
src/sdl.h
Normal file
24
src/sdl.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef _LPT_SDL
|
||||||
|
#define _LPT_SDL
|
||||||
|
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include <SDL2/SDL_image.h>
|
||||||
|
#include <SDL2/SDL_ttf.h>
|
||||||
|
#include <SDL2/SDL_keycode.h>
|
||||||
|
#include "parser.h"
|
||||||
|
|
||||||
|
#define APPROX2ORIG(res, appr) ((res * appr + res) / 2)
|
||||||
|
#define ORIG2APPROX(res, pix) (pix / res * 2 - 1)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SDL_Window *window;
|
||||||
|
SDL_Renderer *render;
|
||||||
|
|
||||||
|
int scr_height;
|
||||||
|
int scr_width;
|
||||||
|
} APP;
|
||||||
|
|
||||||
|
void CleanUp_SDL(APP *app);
|
||||||
|
int Init_SDL(const CONFIG cfg, APP *app);
|
||||||
|
SDL_Texture *LoadIMG_SDL(const char *path, APP *app);
|
||||||
|
#endif
|
Loading…
Add table
Add a link
Reference in a new issue