From a541075fa73de58f1d64d3cc238ab93ede75741e Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Sat, 26 Oct 2019 12:49:22 +0100 Subject: [PATCH] Outline lightning talk. --- 2019-lightning-talk/.gitignore | 8 + 2019-lightning-talk/6400-boot.d/.exists | 0 2019-lightning-talk/6400-boot.term | 26 +++ 2019-lightning-talk/6600-assemble.sh | 3 + 2019-lightning-talk/6600-next | 19 +++ 2019-lightning-talk/6800-next | 22 +++ 2019-lightning-talk/6800-reflection.sh | 3 + 2019-lightning-talk/9000-final.html | 6 + 2019-lightning-talk/9001-final.html | 9 ++ 2019-lightning-talk/9002-final.html | 10 ++ 2019-lightning-talk/9003-final.html | 12 ++ 2019-lightning-talk/assemble.sh | 26 +++ 2019-lightning-talk/bashrc | 21 +++ 2019-lightning-talk/code.js | 72 +++++++++ 2019-lightning-talk/functions | 46 ++++++ 2019-lightning-talk/hello.asm | 14 ++ 2019-lightning-talk/pyrit.asm | 272 ++++++++++++++++++++++++++++++++ 2019-lightning-talk/redhat.png | Bin 0 -> 8766 bytes 2019-lightning-talk/restore | 18 +++ 2019-lightning-talk/run | 25 +++ 2019-lightning-talk/style.css | 272 ++++++++++++++++++++++++++++++++ 21 files changed, 884 insertions(+) create mode 100644 2019-lightning-talk/.gitignore create mode 100644 2019-lightning-talk/6400-boot.d/.exists create mode 100755 2019-lightning-talk/6400-boot.term create mode 100755 2019-lightning-talk/6600-assemble.sh create mode 100755 2019-lightning-talk/6600-next create mode 100755 2019-lightning-talk/6800-next create mode 100755 2019-lightning-talk/6800-reflection.sh create mode 100644 2019-lightning-talk/9000-final.html create mode 100644 2019-lightning-talk/9001-final.html create mode 100644 2019-lightning-talk/9002-final.html create mode 100644 2019-lightning-talk/9003-final.html create mode 100755 2019-lightning-talk/assemble.sh create mode 100644 2019-lightning-talk/bashrc create mode 100644 2019-lightning-talk/code.js create mode 100644 2019-lightning-talk/functions create mode 100644 2019-lightning-talk/hello.asm create mode 100644 2019-lightning-talk/pyrit.asm create mode 100644 2019-lightning-talk/redhat.png create mode 100755 2019-lightning-talk/restore create mode 100755 2019-lightning-talk/run create mode 100644 2019-lightning-talk/style.css diff --git a/2019-lightning-talk/.gitignore b/2019-lightning-talk/.gitignore new file mode 100644 index 0000000..775e73a --- /dev/null +++ b/2019-lightning-talk/.gitignore @@ -0,0 +1,8 @@ +/bindings +/history +/6200-vddk.d/fedora.vmdk +/6200-vddk.d/fedora.vmdk.xz +/6200-vddk.d/fedora.vmdk.lck +/6200-vddk.d/mp +/6400-boot.d/qemu.sh +/6400-boot.d/root diff --git a/2019-lightning-talk/6400-boot.d/.exists b/2019-lightning-talk/6400-boot.d/.exists new file mode 100644 index 0000000..e69de29 diff --git a/2019-lightning-talk/6400-boot.term b/2019-lightning-talk/6400-boot.term new file mode 100755 index 0000000..ab4ecb4 --- /dev/null +++ b/2019-lightning-talk/6400-boot.term @@ -0,0 +1,26 @@ +#!/bin/bash - + +source functions + +# Title. +export title="Tiny VMs" + +kernel="$(ls -1vr /boot/vmlinuz-* | head -1)" +echo "qemu-kvm -display none -kernel $kernel -drive file=nbd:unix:\$unixsocket,snapshot=on -append 'console=ttyS0 root=/dev/sda1 rw' -serial stdio" > 6400-boot.d/qemu.sh +chmod +x 6400-boot.d/qemu.sh + +# History. +remember 'mkdir -p root/dev root/sbin root/bin root/usr/sbin root/usr/bin' +remember 'sudo mknod root/dev/console c 5 1' +remember 'cp /sbin/busybox root/sbin/' +remember 'ln root/sbin/busybox root/bin/ls' +remember 'ln root/sbin/busybox root/bin/sh' +remember 'ln root/sbin/busybox root/bin/init' +remember 'ls -lR root' +remember "nbdkit -U - linuxdisk root --run 'export unixsocket; ./qemu.sh'" + +./restore +pushd 6400-boot.d >/dev/null +terminal +popd >/dev/null +./restore diff --git a/2019-lightning-talk/6600-assemble.sh b/2019-lightning-talk/6600-assemble.sh new file mode 100755 index 0000000..cbc7376 --- /dev/null +++ b/2019-lightning-talk/6600-assemble.sh @@ -0,0 +1,3 @@ +#!/bin/bash - + +xfce4-terminal --disable-server -x ./6600-next diff --git a/2019-lightning-talk/6600-next b/2019-lightning-talk/6600-next new file mode 100755 index 0000000..92b07ec --- /dev/null +++ b/2019-lightning-talk/6600-next @@ -0,0 +1,19 @@ +#!/bin/bash - + +source functions + +# Title. +export title="Assemble!" + +# History. +remember 'less assemble.sh' +remember 'emacs -nw hello.asm' +remember "nbdkit sh assemble.sh file=hello.asm --run 'qemu-system-i386 -hda \$nbd'" +remember 'less pyrit.asm' +remember "nbdkit sh assemble.sh file=pyrit.asm --run 'qemu-system-i386 -hda \$nbd'" + +banner "Demo Credit: Pyrit by Jan Kadlec (Řrřola) " +banner "https://www.pouet.net/prod.php?which=78045" +echo + +terminal diff --git a/2019-lightning-talk/6800-next b/2019-lightning-talk/6800-next new file mode 100755 index 0000000..478e115 --- /dev/null +++ b/2019-lightning-talk/6800-next @@ -0,0 +1,22 @@ +#!/bin/bash - + +source functions + +# Title. +export title="Reflection" + +# History. +remember 'nbdkit info base64exportname' + +for program in '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' +do + remember "qemu-system-i386 -drive snapshot=on,file.driver=nbd,file.host=localhost,file.port=10809,file.export=$program" +done + +banner "Demo Credit: Oscar Toledo Gutierrez" +banner "https://github.com/nanochess " +echo + +terminal diff --git a/2019-lightning-talk/6800-reflection.sh b/2019-lightning-talk/6800-reflection.sh new file mode 100755 index 0000000..29fe3da --- /dev/null +++ b/2019-lightning-talk/6800-reflection.sh @@ -0,0 +1,3 @@ +#!/bin/bash - + +xfce4-terminal --disable-server -x ./6800-next diff --git a/2019-lightning-talk/9000-final.html b/2019-lightning-talk/9000-final.html new file mode 100644 index 0000000..b53d996 --- /dev/null +++ b/2019-lightning-talk/9000-final.html @@ -0,0 +1,6 @@ + + + + +

What did we learn?

+ diff --git a/2019-lightning-talk/9001-final.html b/2019-lightning-talk/9001-final.html new file mode 100644 index 0000000..901a344 --- /dev/null +++ b/2019-lightning-talk/9001-final.html @@ -0,0 +1,9 @@ + + + + +

What did we learn?

+ + diff --git a/2019-lightning-talk/9002-final.html b/2019-lightning-talk/9002-final.html new file mode 100644 index 0000000..1f02187 --- /dev/null +++ b/2019-lightning-talk/9002-final.html @@ -0,0 +1,10 @@ + + + + +

What did we learn?

+ + diff --git a/2019-lightning-talk/9003-final.html b/2019-lightning-talk/9003-final.html new file mode 100644 index 0000000..63bff26 --- /dev/null +++ b/2019-lightning-talk/9003-final.html @@ -0,0 +1,12 @@ + + + + +

What did we learn?

+ + diff --git a/2019-lightning-talk/assemble.sh b/2019-lightning-talk/assemble.sh new file mode 100755 index 0000000..699d5b9 --- /dev/null +++ b/2019-lightning-talk/assemble.sh @@ -0,0 +1,26 @@ +#!/bin/bash - + +f=$tmpdir/source.asm +s=$tmpdir/final.asm +b=$tmpdir/binary + +case "$1" in + config) + if [ "$2" = "file" ]; then + ln -sf "$(realpath "$3")" $f + else + echo "unknown parameter $2=$2" >&2 + exit 1 + fi ;; + config_complete) + echo 'org 07c00h' > $s + cat $f >> $s + echo 'times 510-($-$$) db 0' >> $s + echo 'db 055h,0aah' >> $s + nasm -f bin $s -o $b ;; + get_size) echo 512 ;; + pread) dd if=$b skip=$4 count=$3 iflag=count_bytes,skip_bytes ;; + can_write) ;; + pwrite) exit 1 ;; + *) exit 2 ;; +esac diff --git a/2019-lightning-talk/bashrc b/2019-lightning-talk/bashrc new file mode 100644 index 0000000..a52a5e9 --- /dev/null +++ b/2019-lightning-talk/bashrc @@ -0,0 +1,21 @@ +# -*- shell-script -*- + +# Colour ls. +if [ -f /etc/profile.d/colorls.sh ]; then . /etc/profile.d/colorls.sh; fi + +# Fancy prompt colours (see +# https://wiki.archlinux.org/index.php/Color_Bash_Prompt) +titlecol=$'\e[1;37;41m' ;# colour for the title +promptcol=$'\e[0;32m' ;# colour for the prompt +commandcol=$'\e[1;31m' ;# colour for the typed command +outputcol=$'\e[0m' ;# colour for command output + +export PS1="\n\[$promptcol\]\$ \[$commandcol\]" + +trap 'echo -ne "$outputcol"' DEBUG + +# Load key bindings (if any). +bind -f $talkdir/bindings + +# Same as the banner function, but we cannot reuse it. +printf "%s %s %s\\n" $titlecol "$title" $outputcol diff --git a/2019-lightning-talk/code.js b/2019-lightning-talk/code.js new file mode 100644 index 0000000..ccbe20a --- /dev/null +++ b/2019-lightning-talk/code.js @@ -0,0 +1,72 @@ +function plugins () +{ + document.write ("\ +
\ +

plugins available in nbdkit 1.15.6

\ + \ +
\ +"); +} + +function filters (layer) +{ + document.write ("\ +
\ +

filters available in nbdkit 1.15.6

\ + \ +
\ +"); +} diff --git a/2019-lightning-talk/functions b/2019-lightning-talk/functions new file mode 100644 index 0000000..94948e2 --- /dev/null +++ b/2019-lightning-talk/functions @@ -0,0 +1,46 @@ +# -*- shell-script -*- +# This creates some standard functions. See also $talkdir/bashrc +# which runs in the same bash context as the terminal. + +# Place any local environment variables and settings in "local". +if [ -f local ]; then source local; fi + +# Environment variables. +export HISTFILE=$talkdir/history +export PATH=$talkdir:$PATH +export EDITOR="emacs -nw" + +# remember +# +# This function does two things: (1) It adds the command and arguments +# to the shell history, so that commands can be recalled using up +# arrow or reverse search. (2) It makes a function key recall the +# command. The first command is assigned to F2, the second to F3 and +# so forth. + +rm -f $HISTFILE +touch $HISTFILE +rm -f $talkdir/bindings +touch bindings + +fnum=2 +keys=(- OP OQ OR OS '[15~' '[17~' '[18~' '[19~' '[20~' '[21~') + +remember () +{ + echo "$@" >> $HISTFILE + echo "$@" | sed -e 's/"/\\"/g; s/$/"/' \ + -e 's/^/"\\e'"${keys[$fnum]}"'":"\\C-k \\C-u/' >> $talkdir/bindings + ((fnum++)) +} + +terminal () +{ + chmod -w $HISTFILE + /bin/bash --rcfile $talkdir/bashrc "$@" +} + +banner () +{ + printf "%s %s %s\\n" $'\e[1;37;41m' "$1" $'\e[0m' +} diff --git a/2019-lightning-talk/hello.asm b/2019-lightning-talk/hello.asm new file mode 100644 index 0000000..258d5ed --- /dev/null +++ b/2019-lightning-talk/hello.asm @@ -0,0 +1,14 @@ + mov ah,0 ; clear screen + mov al,3 + int 0x10 + mov ah,0x13 ; print string + mov bl,0xa + mov al,1 + mov cx,len + mov dh,0 + mov dl,0 + mov bp,hello + int 0x10 + hlt +hello: db "*** Hello KVM Forum ***",0xd,0xa +len: equ $-hello diff --git a/2019-lightning-talk/pyrit.asm b/2019-lightning-talk/pyrit.asm new file mode 100644 index 0000000..0288bb0 --- /dev/null +++ b/2019-lightning-talk/pyrit.asm @@ -0,0 +1,272 @@ +; Pyrit + +; a 256-byte intro by Rrrola + +; greets to everyone who's computer is too fast :) + +; This is loosely based on my intro 'Gem' (shown on Demobit), +; but the code is much better. + +; Vector3: X right, Y down, Z forward. +; On the FP stack it looks like {Y X Z} (Y is often used in comparisons). +; In memory it looks like {Z X Y}, which saves a displacement byte. +; (u'v) is the dot product: ux*vx + uy*vy + uz*vz. + + xor ax,ax + xor bx,bx + mov cx,0ffh + mov di,-2 +; mov ss,dx + mov sp,di + mov si,100h + mov bp,091ch + +; assume al=0 bx=0 sp=di=-2 si=0100h bp=09??h + +;Set video mode and earth+sky palette + dec di ; u16[100h] = -20401, u16[10Ch] = -30515 + mov al,13h + dec di ; initial pixel_adr@di = -4 + +P:shr cl,1 ; B@cl = 0..8..31,31..0 + + int 10h ; set video mode / color: bx=index dh=R ch=G cl=B + + movsx cx,bl ; 0..127,128..255 (palette index) + xor ch,cl ; 0..127,127..0 + mov cl,ch + mov ax,cx + mul ax ; R@dh = 0..16..63,63..16..0 + + shr cx,1 ; G@ch = 0..63,63..0 + + inc bl ; keep default color 0 + js Q ; R@dh = 0..63,63..16..0 + xchg cl,dh ; B@cl = 0..16..63,63..0 +Q:mov ax,1010h + jnz P ;bx=0 cx=0 + + ; Constants expected at a fixed address below. + mov ax,0b04fh + mov word[100h],ax + mov ax,04f13h + mov word[102h],ax + mov ax,0e9d0h + mov word[104h],ax + mov ax,010cdh + mov word[106h],ax + mov ax,0be0fh + mov word[108h],ax + mov ax,030cbh + mov word[10ah],ax + mov ax,088cdh + mov word[10ch],ax + mov ax,089e9h + mov word[10eh],ax + +;Each frame: Generate normals to p0..p11=[bp+200h,300h,...]. +M:mov ax,0x4731 ; highest 9 bits: float32 exponent 1/256 (for T) + ; lower byte = 2*number of rotations+1 + ; lowest 4 bits must be 0x1 for 'test cl,al' + mov dx,0xA000-10-20-20-4 + mov es,dx ; dx:bx = YX:XX = 0x9fca:0 + pusha ; adr: -18 -16 -14 -12 -10 -8 -6 -4 -2 + ; stack: di si bp sp bx dx cx ax 0 + ; data: -4 100 9?? -2 0 9fca {T/256} + mov cx,12 +G:add bp,si ; i@cx = 12...1; bp points to p[12-i]; carry=0 + pusha + +;Generate 12 planes with unit normals. + +; fld1 ; platonic dodecahedron: exact is atan((1+sqrt5)/2)=1.017rad + fld dword[di-2] ;|t=T/256: morphing shape: cube, platonic12, rhombic12 + + fsincos + + fldz ;|a=0 b c (a*a+b*b+c*c = 1) +; fldlg2 ;irregular shape + +N:test cl,al ;=1 ;|a b c + jnz K + fchs +K:fstp st3 ;|b c +-a (scramble so that all 12 planes are generated) + loop N ;cl=0 ;|z x y + +;Do a bunch of slow rotations. z x y -> cx-sy cy+sx z + +R:fstp st3 ;|x y z +Z:fld st1 ;|y x y z ;|x sy x cy z + fld dword[di-2] ;|t=T/256 + fsincos ;|c=cos(t) s=sin(t) y x y z ;|c s x sy x cy z + fmulp st4 ;|s y x cy z ;|s x sy cx cy z + fmulp ;|sy x cy z ;|sx sy cx cy z + add al,0x7F ; loop 2x + jo Z + faddp st3 ;|sy cx cy+sx z + fsubp ;|new.z=cx-sy .x=cy+sx .y=z + jc R ; loop 24x + +S:fstp dword[bp+si] ;[bp+100]=.z [bp+104]=.x [bp+108]=.y + sub si,di + jpo S + + popa + loop G + popa + +; the visible pixels are A0000..AF9FF, I want X=0 Y=0 in the center +;Each pixel: cx=T dx:bx=YX:XX(init=9fca:0) di=adr(init=-4) +X:inc dx ; part of "dx:bx += 0x0000CCCD" +X2: + stosb + + pusha ; adr: -18 -16 -14 -12 -10 -8 -6 -4 -2 + fninit ; stack: di si bp sp bx dx cx ax 0 + mov bx,es ; s16: pixadr 100 9?? -2 ..X..Y T result + mov di,-4 ;di = address of pushed ax + +;Compute ray direction. + fild word[BIG] ; store 28799 as a double, read as two floats + fst qword[bx] ; t_front@float[bx] = 0, t_back@float[bx+4] = 6.879 + fild word[di+4-9] + fild word[di+4-8] ;|y=Y x=X z=BIG + +;Intersect the pyrite. + call GEM + popa ; color -> pushed ax +; mov al,dl ; show only palette + +;; Faster, but lower quality: draw each pixel twice. +; stosb +; add bx,0xCCCD; dx:bx = YXX += 0000CCCD +; adc dx,0 + + add bx,0xCCCD; dx:bx = YXX += 0000CCCD + jnc X2 + jnz X ; do 65536 pixels + + in al,60h + dec ax ; ah=0 (checkboard uses positive color indices) + loopnz M ; T-- +; ret ; fallthrough + +GEM: +;Hit the pyrite. + xchg ax,cx ; ax = T + +; Faster (+4 or +8 bytes): test the shape only in the center of the screen + add dh,dh + jo B + add dl,dl + jo B + +;Ray-plane intersection. +;Find the front plane with maximum t and back plane with minimum t. +; tf@[bx], tb@[bx+4] ray parameter t +; pf@[bx+si], pb@[bx+4+si] pointer to plane + mov cx,12 ; i@cx = 12...1 +I:add bp,si ; bp points to p[i] + fldlg2 ;|pd=0.301 y x z + fadd dword[bp+si] ;|N=pd-(ro'p[i]) y x z ; ro = 0 0 -1 + + push si ; Dot product: +D:fld dword[bp+si] ;|p[i].z ... + fmul st4 ;|rd.z*p[i].z ... + sub si,di ; 100 104 108 + jpo D ;|(rd*p[i]).y .x .z N rd.y .x .z + pop si + faddp + faddp ;|D=(rd'p[i]) N y x z + +;If we hit the plane from the front (D<0), update tf. Otherwise update tb. + push bx + fst dword[bp+di]; -> p[i].dot_rd (will be read later) + test [bp+di+2],sp ; sf=1 if we're in front of the plane + js FRONT + sub bx,di ; bx = address of tf?tb +FRONT: ; D<0: if tf*D < N { tf=N/D; pf=current; } maximalize tf + fld st0 ; D>=0: if tb*D < N { tb=N/D; pb=current; } minimalize tb + fmul dword[bx] ;|(tf?tb)*D D N y x z + +;;DosBOX-compatible FPU comparison, +5 bytes (+3 but we need ax) +; push ax +; fcomp st2 ;|D N y x z +; fnstsw ax +; sahf ; cf = (tf?tb)*D < N +; pop ax +; jc NEXT + + fcomip st2 + jc NEXT + +;another alternative, +6 bytes +; fsub st2 +; fstp dword[bp-8] +; test [bp-6],sp ; sf=1 if <0 +; js NEXT + + + fdivr st1 ;|t=N/D N y x z + fst dword[bx] ; -> tf?tb + mov [bx+si],bp ; pf?pb = current +NEXT: + fcompp + pop bx ;|y x z + + mov dx,[bx+6] + cmp dx,[bx+2] ; if tf>tb { no_hit: early exit } + jng B ;si=100 ;|y x z + + loop I + +;Reflect: reflect(i,n) = i - 2*n*(i'n) + mov bx,[bx+si] ; pf +Y:fld dword[bx+di] ;|(rd'pf) rd.y .x .z ; reads pf->dot_rd + fmul dword[bx+si] ;|(rd'pf)*pf.z rd.y .x .z + fadd st0 ;|2*(rd'pf)*pf.z rd.y .x .z + fsubr st3 ;|R.z=rd.z-2*(rd'pf)*pf.z rd.y .x .z + sub si,di ;100 104 108 + jpo Y ;si=10C ;|(R=i-2*n(i'n)).y R.x R.z rd.y .x .z + +;Environment map: chessboard below, sky gradient above. +B: +; Subtle highlight on the pyrite. + fld st0 + fimul word[C] ; 16993 (background) or 20036 (pyrit) + fistp dword[di] ;|y x z + sar dword[di],22 ; if y>=-0.5 { chessboard } else { sky } + js E ; the sky is just y (= y^2 after gamma) + +; Everything the same brightness. (-6 bytes) +; fist word[di] ;|y x z +; sar word[di],8 ; if y>=-0.5 { chessboard } else { sky } +; js E ; the sky is just y (= y^2 after gamma) + +; Dark background version. +; fist word[di] ;|y x z +; shld cx,si,16-3 +; xor cl,9 ; hit?8:9 - make the background darker +; sar word[di],cl ; if y>=-0.5 { chessboard } else { sky } +; js E ; the sky is just y (= y^2 after gamma) + + fidivr word[si] ;|C/y x z (C = hit?-30515:-20401) + fmul st1,st0 + fmul st2 ;|u=z*C/y v=x*C/y z + + fistp dword[bp+di] + sub al,[bp+di+1] + fistp dword[bp+di] + xor al,[bp+di+1] ; xortex@ax = (T-u) XOR v + +; aam -32-24 ; more interesting floor texture + and al,9<<3 + add al,10<<3 ; tex = (xortex AND 0b1001) + 10 [10|11|18|19] + mul byte[di] + mov [di],ah ; pushed al = tex*y + +E:ret + +BIG dw 28799 +C dw 16993 +C2 dw 20036 diff --git a/2019-lightning-talk/redhat.png b/2019-lightning-talk/redhat.png new file mode 100644 index 0000000000000000000000000000000000000000..c955eb021fe842672e0fbb454f780f82fd12b0e7 GIT binary patch literal 8766 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 /dev/null + +if [ -d "$talkdir/6400-boot.d/root" ]; then + sudo rm -rf $talkdir/6400-boot.d/root +fi + +sleep 0.5; killall nbdkit >& /dev/null + +exit 0 diff --git a/2019-lightning-talk/run b/2019-lightning-talk/run new file mode 100755 index 0000000..d771700 --- /dev/null +++ b/2019-lightning-talk/run @@ -0,0 +1,25 @@ +#!/bin/bash - +# Run the talk. + +set -e + +# Avoid GNOME keyring stupidity +export GNOME_KEYRING_CONTROL= +export GNOME_KEYRING_PID= + +# No proxy. +#unset http_proxy +#unset https_proxy +#unset ftp_proxy + +# Clean up after previous run. +talkdir=$PWD ./restore + +# Precreate any files necessary. +#(nothing) + +# Run techtalk. The demos require nbdkit 1.15.6, libnbd 1.1.5, and qemu 4.2, +# which are not present in Fedora 30, so point to self-built versions. +export PATH=$HOME/d/nbdkit:$HOME/d/qemu:$PATH +$HOME/d/libnbd/run techtalk-pse +#~/d/techtalk-pse/techtalk-pse diff --git a/2019-lightning-talk/style.css b/2019-lightning-talk/style.css new file mode 100644 index 0000000..e33ca15 --- /dev/null +++ b/2019-lightning-talk/style.css @@ -0,0 +1,272 @@ +/* Red Hat red is rgb(238,0,0). */ + +body { + background: url(redhat.png) no-repeat; + background-position: 98% 6px; + background-size: auto 48px; + /* font-size: 28pt; */ /* For max */ + font-size: 20pt; /* For 1024x768 */ + font-family: Red Hat Text, liberation, helvetica; + /* font-family: helvetica; */ + + /* Can be used to scale the whole document. */ + /*transform: translate(-10%,-10%) scale(0.75,0.75);*/ +} + +body td, body th { /* why?? */ + font-size: 24pt; + padding-bottom: 8px; +} + +h1 { + color: rgb(238,0,0); + /*font-size: 48px;*/ + font-size: 40px; + top: 8; + left: 0; + border-bottom: 2px solid rgb(238,0,0); +} + +h2 { + color: rgb(238,0,0); + font-size: 32px; + font-style: italic; + border-bottom: 2px solid rgb(238,0,0); +} + +b { + color: rgb(238,0,0); +} + +/* Title page. */ +div#titlepage { + margin-top: 100px; + width: 80%; + margin-left: 10%; +} + +div#titlepage p.title { + color: rgb(238,0,0); + font-weight: bold; + font-size: 48px; + text-align: left; +} + +div#titlepage p.author { + font-size: 36px; + text-align: left; +} + +div#titlepage p.abstract { + font-size: 28px; + text-align: left; +} + +/* Code */ +pre.code { + margin-left: 1em; + background: #eee; +} + +code { + color: rgb(238,0,0); +} + +/* Bullet points */ +li { + padding-bottom: 16px; +} + +/* Plugins box. */ +div.plugins { + background: #f8f8ff; + border: 1px solid rgb(238,0,0); + border-radius: 15px; + margin-left: auto; + margin-right: auto; + width: 800px; + height: 400px; + /* Position relative is needed so that items may be + positioned inside. */ + position: relative; +} + +div.plugins p#caption { + position: absolute; + bottom: -5px; right: 5px; + color: rgb(238,0,0); + text-align: right; + font-size: 16px; + font-weight: bold; +} + +div.plugins ul { + position: absolute; + top: 10%; + width: 700px; + height: 380px; + column-count: 4; + list-style-type: none; + margin: 0; +} + +div.plugins ul li { + padding: 0px; + margin: 5px; +} + +div.plugins ul li.highlighted { + border: 1px solid rgb(238,0,0); + background: #fff; + padding-left: 10px; + color: rgb(238,0,0); + border-radius: 20px; + font-weight: bold; +} + +/* Filters box. */ +div.filters { + background: #f8fff8; + border: 1px solid rgb(238,0,0); + border-radius: 15px; + margin-left: auto; + margin-right: auto; + width: 800px; + height: 280px; + /* Position relative is needed so that items may be + positioned inside. */ + position: relative; +} + +div.filters p.filtercaption { + position: absolute; + bottom: -5px; right: 5px; + color: rgb(238,0,0); + text-align: right; + font-size: 16px; + font-weight: bold; +} + +div.filters ul { + position: absolute; + top: 10%; + width: 700px; + height: 260px; + column-count: 4; + list-style-type: none; + margin: 0; +} + +div.filters ul li { + padding: 0px; + margin: 5px; +} + +div.filters ul li.highlighted { + border: 1px solid rgb(238,0,0); + background: #fff; + padding-left: 10px; + color: rgb(238,0,0); + border-radius: 20px; + font-weight: bold; +} + +/* Colored highlighting */ +div.plugins ul li.bg_r, +div.filters ul li.bg_r { + background: #b00; + color: white; +} + +div.plugins ul li.bg_g, +div.filters ul li.bg_g { + background: #0b0; + color: white; +} + +div.plugins ul li.bg_b, +div.filters ul li.bg_b { + background: #00b; + color: white; +} + +/* For images which must be centered on the page. */ +div.allcenter { + display: flex; + justify-content: center; + align-items: center; + height: 50vw; +} + +div.all-center img { +} + +/* Outlined text. */ +.outline { + text-shadow: 2px 2px 0 rgb(238,0,0), + -2px 2px 0 rgb(238,0,0), + 2px -2px 0 rgb(238,0,0), + -2px -2px 0 rgb(238,0,0), + 0px 2px 0 rgb(238,0,0), + 0px -2px 0 rgb(238,0,0), + -2px 0px 0 rgb(238,0,0), + 2px 0px 0 rgb(238,0,0), + 4px 4px 0 rgb(238,0,0), + -4px 4px 0 rgb(238,0,0), + 4px -4px 0 rgb(238,0,0), + -4px -4px 0 rgb(238,0,0), + + 0px 4px 0 rgb(238,0,0), + 0px -4px 0 rgb(238,0,0), + -4px 0px 0 rgb(238,0,0), + 4px 0px 0 rgb(238,0,0), + 2px 4px 0 rgb(238,0,0), + -2px 4px 0 rgb(238,0,0), + 2px -4px 0 rgb(238,0,0), + -2px -4px 0 rgb(238,0,0), + 4px 2px 0 rgb(238,0,0), + -4px 2px 0 rgb(238,0,0), + 4px -2px 0 rgb(238,0,0), + -4px -2px 0 rgb(238,0,0), + + 4px 4px 0 rgb(255,128,128), + -4px 4px 0 rgb(255,128,128), + 4px -4px 0 rgb(255,128,128), + -4px -4px 0 rgb(255,128,128), + 0px 4px 0 rgb(255,128,128), + 0px -4px 0 rgb(255,128,128), + -4px 0px 0 rgb(255,128,128), + 4px 0px 0 rgb(255,128,128), + 8px 8px 0 rgb(255,128,128), + -8px 8px 0 rgb(255,128,128), + 8px -8px 0 rgb(255,128,128), + -8px -8px 0 rgb(255,128,128), + + 0px 8px 0 rgb(255,128,128), + 0px -8px 0 rgb(255,128,128), + -8px 0px 0 rgb(255,128,128), + 8px 0px 0 rgb(255,128,128), + 4px 8px 0 rgb(255,128,128), + -4px 8px 0 rgb(255,128,128), + 4px -8px 0 rgb(255,128,128), + -4px -8px 0 rgb(255,128,128), + 8px 4px 0 rgb(255,128,128), + -8px 4px 0 rgb(255,128,128), + 8px -4px 0 rgb(255,128,128), + -8px -4px 0 rgb(255,128,128); +} + +/* Warning symbol. */ +span.warning { + background-color: yellow; + font-weight: bold; +} + +/* Attribution for artwork etc. */ +p.attribution { + position: absolute; + right: 10px; + bottom: 10px; + text-align: right; + font-size: 10pt; +} -- 1.8.3.1