Merge pull request #1669 from xexyl/hou15
This commit is contained in:
15 files changed
+920
-616
No files matched your search
@@ -5,4 +5,5 @@ indent
|
|||||||
indent.c
|
indent.c
|
||||||
indent.o
|
indent.o
|
||||||
prog
|
prog
|
||||||
|
prog.alt
|
||||||
prog.orig
|
prog.orig
|
||||||
+11
-3
@@ -57,9 +57,14 @@ CSTD= -std=gnu11
|
|||||||
#
|
#
|
||||||
ARCH=
|
ARCH=
|
||||||
|
|
||||||
|
# Variables to control dimensions of the game
|
||||||
|
#
|
||||||
|
WIDTH= 1024
|
||||||
|
HEIGHT= 800
|
||||||
|
|
||||||
# Defines that are needed to compile
|
# Defines that are needed to compile
|
||||||
#
|
#
|
||||||
CDEFINE= -DW=1024 -Dp=800
|
CDEFINE= -DW=${WIDTH} -Dp=${HEIGHT}
|
||||||
|
|
||||||
# Include files that are needed to compile
|
# Include files that are needed to compile
|
||||||
#
|
#
|
||||||
@@ -116,8 +121,8 @@ OBJ= ${PROG}.o
|
|||||||
DATA=
|
DATA=
|
||||||
TARGET= ${PROG}
|
TARGET= ${PROG}
|
||||||
#
|
#
|
||||||
ALT_OBJ=
|
ALT_OBJ= ${PROG}.alt.o
|
||||||
ALT_TARGET=
|
ALT_TARGET= ${PROG}.alt
|
||||||
|
|
||||||
|
|
||||||
#################
|
#################
|
||||||
@@ -140,6 +145,9 @@ ${PROG}: ${PROG}.c
|
|||||||
alt: data ${ALT_TARGET}
|
alt: data ${ALT_TARGET}
|
||||||
@${TRUE}
|
@${TRUE}
|
||||||
|
|
||||||
|
${PROG}.alt: ${PROG}.alt.c
|
||||||
|
${CC} ${CFLAGS} $< -o $@ ${LDFLAGS}
|
||||||
|
|
||||||
# data files
|
# data files
|
||||||
#
|
#
|
||||||
data: ${DATA}
|
data: ${DATA}
|
||||||
|
|||||||
+84
-30
@@ -4,6 +4,21 @@
|
|||||||
make
|
make
|
||||||
```
|
```
|
||||||
|
|
||||||
|
To change the dimensions you can use the `WIDTH` and `HEIGHT` variables when
|
||||||
|
compiling (default 1024 x 800):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make clobber WIDTH=640 HEIGHT=480
|
||||||
|
```
|
||||||
|
|
||||||
|
to make the game 640 x 480. Obviously changing it to non numbers or negative
|
||||||
|
numbers or too large numbers will cause problems.
|
||||||
|
|
||||||
|
|
||||||
|
There is an alternate version that is based on the author's suggestion to change
|
||||||
|
a value in order to see a bug that they avoided in their entry. See [Alternate
|
||||||
|
code](#alternate-code) below.
|
||||||
|
|
||||||
|
|
||||||
## To use:
|
## To use:
|
||||||
|
|
||||||
@@ -18,38 +33,70 @@ make
|
|||||||
./prog
|
./prog
|
||||||
```
|
```
|
||||||
|
|
||||||
Press and hold the Left Arrow key until you turn 90-degrees to the left
|
Press and hold the Left Arrow key until you turn 90-degrees to the left.
|
||||||
|
|
||||||
When you see a long tunnel, press the function key F2
|
When you see a long tunnel, press the function key F2.
|
||||||
|
|
||||||
Use the Up, Down, Left and Right keys to change your path
|
Use the Up, Down, Left and Right keys to change your path.
|
||||||
|
|
||||||
Press function higher numbered function keys (F3, F4, ...) to go faster
|
Press function higher numbered function keys (F3, F4, ...) to go faster.
|
||||||
|
|
||||||
Press F1 to stop
|
Press F1 to stop.
|
||||||
|
|
||||||
Turn 90-degrees to one side
|
Turn 90-degrees to one side.
|
||||||
|
|
||||||
Press F4 to and drill into some blocks for a bit
|
Press F4 to drill into some blocks for a bit.
|
||||||
|
|
||||||
Press F1 to stop
|
Press F1 to stop.
|
||||||
|
|
||||||
Turn 180-degrees to face the way you came
|
Turn 180-degrees to face the way you came.
|
||||||
|
|
||||||
Press F2 and navigate back down the new hole until you reach the long tunnel again
|
Press F2 and navigate back down the new hole until you reach the long tunnel
|
||||||
|
again.
|
||||||
|
|
||||||
Press F1 to stop
|
Press F1 to stop.
|
||||||
|
|
||||||
etc.
|
etc.
|
||||||
|
|
||||||
Press the ESC key
|
Press the ESC key.
|
||||||
|
|
||||||
|
|
||||||
|
## Alternate code:
|
||||||
|
|
||||||
|
The author suggested that one change `q` to `0x82000820000000` instead of
|
||||||
|
`0x820008202625a0` to see a bug that they avoided, writing:
|
||||||
|
|
||||||
|
```
|
||||||
|
To see this bug in action change the assignment above
|
||||||
|
to q=0x82000820000000`, and look towards the negative
|
||||||
|
direction of the main tunnel.
|
||||||
|
```
|
||||||
|
|
||||||
|
This alt version does this for you.
|
||||||
|
|
||||||
|
|
||||||
|
### Alternate build:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make alt
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Alternate use:
|
||||||
|
|
||||||
|
Use `prog.alt` as you would `prog` above.
|
||||||
|
|
||||||
|
|
||||||
|
### Alternate try:
|
||||||
|
|
||||||
|
Try locating the issue the author suggested exists.
|
||||||
|
|
||||||
|
|
||||||
## Judges' remarks:
|
## Judges' remarks:
|
||||||
|
|
||||||
You are in a twisty maze blocks, almost all alike.
|
You are in a twisty maze blocks, almost all alike.
|
||||||
|
|
||||||
Those blocks are generated by twisty maze of code blocks, almost all different.
|
Those blocks are generated by twisty maze of code blocks, almost all different.
|
||||||
|
|
||||||
Can you find your way around either and understand where you are?
|
Can you find your way around either and understand where you are?
|
||||||
|
|
||||||
@@ -61,12 +108,13 @@ number function keys such as F30 or F31? :-)
|
|||||||
|
|
||||||
## Author's remarks:
|
## Author's remarks:
|
||||||
|
|
||||||
|
|
||||||
### What is it?
|
### What is it?
|
||||||
|
|
||||||
Just run prog with no arguments on an X11-compatible system. The scenery, though
|
Just run `./prog` with no arguments on an X11-compatible system. The scenery, though
|
||||||
pseudo-randomly generated should be strangely familiar, specially to those still
|
pseudo-randomly generated should be strangely familiar, especially to those still
|
||||||
in their teen age. You can navigate using the keyboard arrow keys and the
|
in their teenage years. You can navigate using the keyboard arrow keys and the
|
||||||
function keys. Your speed is a linear function of (n-1) where Fn is the last
|
function keys. Your speed is a linear function of `(n-1)` where `Fn` is the last
|
||||||
function key you have pressed, and you always move in the direction you are
|
function key you have pressed, and you always move in the direction you are
|
||||||
looking at. Be aware that you are probably some kind of a Creeper as is obvious
|
looking at. Be aware that you are probably some kind of a Creeper as is obvious
|
||||||
from looking at the program, hence your movement is destructive to the
|
from looking at the program, hence your movement is destructive to the
|
||||||
@@ -75,18 +123,21 @@ you might find yourself in a 3D maze of twisty little passages, from which there
|
|||||||
is only one Esc(ape) key. Note that in theory if you have a specialty keyboard
|
is only one Esc(ape) key. Note that in theory if you have a specialty keyboard
|
||||||
with 32 function keys you may even press F31 to reach infinite improbability
|
with 32 function keys you may even press F31 to reach infinite improbability
|
||||||
drive speed, though the author had never tested this feature. However a hidden
|
drive speed, though the author had never tested this feature. However a hidden
|
||||||
comment in keysymdef.h suggests the existence of a mythical Sun Keyboard with 35
|
comment in `keysymdef.h` suggests the existence of a mythical Sun Keyboard with 35
|
||||||
function keys :)
|
function keys :)
|
||||||
|
|
||||||
|
|
||||||
### Full disclosure:
|
### Full disclosure:
|
||||||
|
|
||||||
This entry, though pretty thoroughly obfuscated, is not entirely original, nor
|
This entry, though pretty thoroughly obfuscated, is not entirely original, nor
|
||||||
am I Notch. The inspiration for this entry is a demo code written by the Notch
|
am I Notch. The inspiration for this entry is a demo code written by the Notch
|
||||||
himself, which was released with the following license: "you may use the code
|
himself, which was released with the following license: "you may use the code
|
||||||
in here for any purpose in any way you want, at your own risk". That version
|
in here for any purpose in any way you want, at your own risk". That version
|
||||||
will henceforth be referred to as the original. Though the original in itself
|
will henceforth be referred to as the original. Though the original in itself
|
||||||
was quite nice and rather dense piece of code, it was not written in C, nor
|
was quite nice and rather dense piece of code, it was not written in C, nor
|
||||||
entirely and meticulously obfuscated, a state of things I hopefully rectified.
|
entirely and meticulously obfuscated, a state of things I hopefully rectified.
|
||||||
|
|
||||||
|
|
||||||
### Some extra features:
|
### Some extra features:
|
||||||
|
|
||||||
Basing it on the original which already had a wonderful simple and concise ray
|
Basing it on the original which already had a wonderful simple and concise ray
|
||||||
@@ -94,7 +145,7 @@ casting through a generated voxel world rendering, I added a few tweaks of my
|
|||||||
own device:
|
own device:
|
||||||
|
|
||||||
* Two pass optimized rendering. The program first calculates 1/16 of the output
|
* Two pass optimized rendering. The program first calculates 1/16 of the output
|
||||||
image by ray casting, and then, when possible uses texture interpolation on the
|
image by ray casting and then, when possible, uses texture interpolation on the
|
||||||
voxel faces. It speeds up the rendering by at least a factor of 4 on most
|
voxel faces. It speeds up the rendering by at least a factor of 4 on most
|
||||||
scenes, but extra care must be taken when passing rays through the leaves voxels
|
scenes, but extra care must be taken when passing rays through the leaves voxels
|
||||||
...
|
...
|
||||||
@@ -104,17 +155,18 @@ In this version the rendering of those (far face leaves) is correct.
|
|||||||
* Window rendering size specified in Makefile.
|
* Window rendering size specified in Makefile.
|
||||||
* Added the keyboard controls for navigation (and destruction).
|
* Added the keyboard controls for navigation (and destruction).
|
||||||
|
|
||||||
|
|
||||||
### Portability issues:
|
### Portability issues:
|
||||||
|
|
||||||
This entry is rather portable I think on modern platforms. It assumes of course
|
This entry is rather portable I think on modern platforms. It assumes of course
|
||||||
basic X-windows availability. There are several other salient assumptions
|
basic X-windows availability. There are several other salient assumptions
|
||||||
though:
|
though:
|
||||||
|
|
||||||
* The entry assumes `sizeof(int)=4`. This seems to cover pretty much everything
|
* The entry assumes `sizeof(int)==4`. This seems to cover pretty much everything
|
||||||
that supports X-windows so would be broken only on quite ancient machines,
|
that supports X-windows so would be broken only on quite ancient machines,
|
||||||
embedded processors, or some big iron 64 bit system where `sizeof(int)=8`.
|
embedded processors, or some big iron 64 bit system where `sizeof(int)=8`.
|
||||||
* The entry assumes the default visual has 24 bit depth (RGB). This seems to be
|
* The entry assumes the default visual has 24 bit depth (RGB). This seems to be
|
||||||
the case on most X Servers this days.
|
the case on most X Servers these days.
|
||||||
* The entry, does a thing which is an absolute No-No for X-windows program, i.e.
|
* The entry, does a thing which is an absolute No-No for X-windows program, i.e.
|
||||||
assuming it knows some numeric values for keysyms defined in `keysymdef.h`. I
|
assuming it knows some numeric values for keysyms defined in `keysymdef.h`. I
|
||||||
have searched far and wide the lord Google's domain, yet was unable to find a
|
have searched far and wide the lord Google's domain, yet was unable to find a
|
||||||
@@ -130,17 +182,18 @@ the following:
|
|||||||
### Precision issues:
|
### Precision issues:
|
||||||
|
|
||||||
The entry, on purpose, (see the section about SIMD below) does not use enough
|
The entry, on purpose, (see the section about SIMD below) does not use enough
|
||||||
bits of precision, so some times the ray will miss the intersection of two voxel
|
bits of precision, so sometimes the ray will miss the intersection of two voxel
|
||||||
faces and push on through. That's why you may notice some noise along close up
|
faces and push on through. That's why you may notice some noise along close up
|
||||||
voxel edges. Fixing this issue would have taken the entry over the size limit
|
voxel edges. Fixing this issue would have taken the entry over the size limit
|
||||||
regrettably.
|
regrettably.
|
||||||
|
|
||||||
|
|
||||||
### Obfuscations:
|
### Obfuscations:
|
||||||
|
|
||||||
Well, of course you have all the usual suspects, used for extreme compression,
|
Well, of course you have all the usual suspects, used for extreme compression,
|
||||||
and such a nice layout: not very informative identifiers, which are being reused
|
and such a nice layout: not very informative identifiers, which are being reused
|
||||||
all over the place, some rather gruesome looking expressions, a whole load of
|
all over the place, some rather gruesome looking expressions, a whole load of
|
||||||
magic constants with apparently no rhyme nor reason (including a Lagrange
|
magic constants with apparently no rhyme or reason (including a Lagrange
|
||||||
polynomial), and a message from our friendly Cetaceans. However it also includes
|
polynomial), and a message from our friendly Cetaceans. However it also includes
|
||||||
some clever and not so obvious though instructive techniques, to subtly make the
|
some clever and not so obvious though instructive techniques, to subtly make the
|
||||||
code more magical and efficient, at the same time.
|
code more magical and efficient, at the same time.
|
||||||
@@ -151,10 +204,11 @@ inline functions! The irony though, is that when compiling the program on modern
|
|||||||
X86 architectures indeed SSE/AVX is used for the long longs. Following is some
|
X86 architectures indeed SSE/AVX is used for the long longs. Following is some
|
||||||
"Spoiler" information, So if you want to play tough, stop reading at this point.
|
"Spoiler" information, So if you want to play tough, stop reading at this point.
|
||||||
|
|
||||||
|
|
||||||
### Portable SIMD programming:
|
### Portable SIMD programming:
|
||||||
|
|
||||||
So how is this done? Quite simply by using the whole long long arithmetic's
|
So how is this done? Quite simply by using the whole `long long` arithmetic's
|
||||||
capability. I think the C99 standard assures us that long long has at least 64
|
capability. I think the C99 standard assures us that `long long` has at least 64
|
||||||
bits. Most of those bits are unused in normal programs, however here we use them
|
bits. Most of those bits are unused in normal programs, however here we use them
|
||||||
more wisely. For example, in the inner loop of the program you have the innocent
|
more wisely. For example, in the inner loop of the program you have the innocent
|
||||||
looking expression `i+=d`. What it does in fact, is a SIMD addition of two
|
looking expression `i+=d`. What it does in fact, is a SIMD addition of two
|
||||||
@@ -162,7 +216,7 @@ vectors, each with three signed fixed point coordinates, advancing our ray in 3D
|
|||||||
space!
|
space!
|
||||||
|
|
||||||
To spell it out, the macro producing such vectors is `P`, and the assignment
|
To spell it out, the macro producing such vectors is `P`, and the assignment
|
||||||
q=0x820008202625a0 sets our creeper original position to about `(32.5, 32.5019,
|
`q=0x820008202625a0` sets our creeper original position to about `(32.5, 32.5019,
|
||||||
2441.406)`.
|
2441.406)`.
|
||||||
|
|
||||||
Evidently when doing such arithmetics, care must me taken to avoid overflow from
|
Evidently when doing such arithmetics, care must me taken to avoid overflow from
|
||||||
@@ -171,8 +225,8 @@ each dimension this hardly matters. A subtle issue, is how to deal with signed
|
|||||||
quantities. In the `i+=d` expression above `i` has 3 positive components, but
|
quantities. In the `i+=d` expression above `i` has 3 positive components, but
|
||||||
`d` has arbitrary signed components, as our ray may face in any direction. It
|
`d` has arbitrary signed components, as our ray may face in any direction. It
|
||||||
seems things should not work, specially as we defined both `i` and `d` as
|
seems things should not work, specially as we defined both `i` and `d` as
|
||||||
unsigned! However notice that the `T` (and `P`) macros convert `float` to
|
`unsigned`! However notice that the `T` (and `P`) macros convert `float` to
|
||||||
`signed long longs`.
|
`signed long long`s.
|
||||||
|
|
||||||
Once sign is extended from a least component into higher bits, it seems at first
|
Once sign is extended from a least component into higher bits, it seems at first
|
||||||
to be recipe for disaster, however everything works beautifully, and you get
|
to be recipe for disaster, however everything works beautifully, and you get
|
||||||
@@ -184,7 +238,7 @@ tunnel.
|
|||||||
|
|
||||||
Similar technique is used on the RGB components so their brightness can be
|
Similar technique is used on the RGB components so their brightness can be
|
||||||
adjusted simultaneously by the expression: `o=o*b>>8`. Of course some spare bits
|
adjusted simultaneously by the expression: `o=o*b>>8`. Of course some spare bits
|
||||||
are needed between the components, so they are spread in the long long and
|
are needed between the components, so they are spread in the `long long` and
|
||||||
reordered as RBG.
|
reordered as RBG.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
#define So long
|
||||||
|
#define R rand()
|
||||||
|
#include <math.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#define T(i,F) ((So long)(i)<<F)
|
||||||
|
#define O(c,L,i) c*sin(i)+L*cos(i)
|
||||||
|
#define y(n,L) for(n=0; n<L 3; n++)
|
||||||
|
#define P(v,L) d=0; y(l,)d+=T(L*l[v],l*20);
|
||||||
|
#define X(q) q>>10&63|q>>24&4032|q>>38&258048
|
||||||
|
char J[1<<18]; int G[W*p],_,k,I=W/4+1,w=p/4+1; float C,B,e;
|
||||||
|
|
||||||
|
unsigned So long A,n,d, t,h,x, f,o,r,a,l,L,F,i,s,H=1<<18,b=250,D[1<<14],z[W*p],q
|
||||||
|
=0x82000820000000;main(){Display *j=XOpenDisplay(0);Window u=XCreateSimpleWindow
|
||||||
|
(j,RootWindow(j,0),0,0,W,p,1,0,0);XImage *Y=XCreateImage(j,DefaultVisual(j,0),24
|
||||||
|
,2,0,(char*)G,W,p,32,0); XEvent M; for(XMapWindow(j,u); XSelectInput( j,u,1)&&a-
|
||||||
|
65307; ){ if(!H){ if(XCheckWindowEvent(j,u,1,&M)){ a=XLookupKeysym(&M.xkey,0);*(
|
||||||
|
a&1?&C:& B)-=(.05
|
||||||
|
-a/2% 2* .1)*!(a-
|
||||||
|
1& 4092^ 3920);a+
|
||||||
|
2&0xfe0^ 0xfc0||(
|
||||||
|
s=a+2&31 ); }else
|
||||||
|
{ y(k,p+ ){ F=k%w* 4|k/w; float a[6],S=(F-p /2.) /p;
|
||||||
|
y(_,W+){ i=_%I*4|_/I; if( F<p&i<W){ o=1; L= i+F*W;if
|
||||||
|
(l=i&3); else{ l=F&3; o=W ; } h=z[L-o*l]; f =z[L+(4-
|
||||||
|
l)*o]; t =F-p/2||i-W/2; r =h^f; if(!l| !t|( int)r|(!
|
||||||
|
(h- 3&3) &&258063&r>>38)) { float V=(i-W/2. )/p,U=O(
|
||||||
|
S,1,B),m =32768,Q=m; a[4] =O(-1,S,B); a[3]= O(U,V,C)
|
||||||
|
; a[5]=O (-V,U,C); P((a+3 ),s*42); t||(A=d) ;f=0;y(n
|
||||||
|
,){float N=a[n+3], E=1024 /fabs(N); b= N<0; float K=
|
||||||
|
(((q>>20 *n)^~-b)+!b&1023 )/1024.; y(d,)a[d ]=a[d+3]
|
||||||
|
*E; a[n] =round(a[n]); P( a,K); i=q+d; P(a, 1); e=E*
|
||||||
|
K; for(; e<m; i+=d){ l=X(i); t=r=l^(l^l-( 1<<6*n))
|
||||||
|
&63<<6*n ; if(b){ r=l; l=t; } if(J[r])l=r ; if(t=J
|
||||||
|
[l]){x=( n-1)?(i|i>>40)&1023|i>>8&4190208 |4194304
|
||||||
|
:i&1023| i>>28&4190208|(b^l==r)<<23; if(h =D[(x>>6
|
||||||
|
&0xf|x>> 14&0x3f0)+t*768]){ o=h; f=n|l*4| x<<32; m
|
||||||
|
=e; } if (t==8&e<Q)Q=e; } e+=E; } }b=(255 -((f&3)+
|
||||||
|
2)%3*51) *(1-m/32768); o=o*b>>8; G[L]=o>> 32<<8|o&
|
||||||
|
16711935 ; z[L]=3*(Q<=m)|f|b<<56; } else{ d=l*(f<<
|
||||||
|
8>>40)+( 4-l)*(h<<8>>40)>>2&16774143; o=D [(d>> 6&
|
||||||
|
15|d>>14 &1008)+J[(int)h/4]*768]*(b=h>>56 )>>8; G[
|
||||||
|
L]=o>>32 <<8 | o& 16711935 ; z[L]=(
|
||||||
|
int) h|d <<32|b<< 56; } }} } q +=A;
|
||||||
|
XPutImage (j, u+0, DefaultGC (j,J[X(q
|
||||||
|
)]=0),Y, 0,0,0,0, W,p); }} else{ L=
|
||||||
|
--H/768; J[H] =R% 16*(R%4< abs((H>>
|
||||||
|
6&63)-32 )+abs((H
|
||||||
|
>>12&63) -32)-3);
|
||||||
|
i=H &15; F=H %768
|
||||||
|
>>4; if( L<16){if
|
||||||
|
(L-1|!(R %3))b=R%
|
||||||
|
96^255; l=i*i*3+i*81/4&3; a=L>3?L-8?L-5?9858122:12365733-488848*((i+F/4*4)%8&&F%
|
||||||
|
4):R%2*5298487:3352537*L*L-14202379*L+19205553; if(L==4)if(F<l+18)a=6990400;else
|
||||||
|
if(l>F-19)b*=0.7; if(L==3){ if((i-1&15)<14&(F-1&15)<14&!(F&16)){ a=12359778; _=7
|
||||||
|
-i; k=7-F%16; _^=_>>31; k^=k>>31; b=196-R%32+(k>_?k:_)%3*42;} else{ b*=1+R%2*(.5
|
||||||
|
-(i&1)); } } D[H]=(a&16711935|(a&65280)<<24)*(b>>(F>>5))>>8&0xff00ff00ff; } } }}
|
||||||
@@ -15,9 +15,7 @@ make
|
|||||||
### Try:
|
### Try:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cat prog.c
|
./try.sh
|
||||||
|
|
||||||
./prog | diff - prog.c
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -42,14 +40,14 @@ more prog.c
|
|||||||
Where did those underscores come from? Well [RTFS](http://acronyms.thefreedictionary.com/RTFS)!\*\*
|
Where did those underscores come from? Well [RTFS](http://acronyms.thefreedictionary.com/RTFS)!\*\*
|
||||||
|
|
||||||
** Read the Freaking Source (polite form)
|
** Read the Freaking Source (polite form)
|
||||||
** Read The Freakin' Screen (polite form)
|
** Read The Freaking Screen (polite form)
|
||||||
|
|
||||||
If you are still puzzled, look at prog.c with your favorite text editor.
|
If you are still puzzled, look at [prog.c](prog.c) with your favorite text editor.
|
||||||
|
|
||||||
|
|
||||||
## Author's remarks:
|
## Author's remarks:
|
||||||
|
|
||||||
**Follow this instruction literally!**
|
**Follow these instructions literally!**
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cat prog.c
|
cat prog.c
|
||||||
|
|||||||
Executable
+36
@@ -0,0 +1,36 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# try.sh - demonstrate IOCCC winner 2015/endoh2
|
||||||
|
#
|
||||||
|
|
||||||
|
# make sure CC is set so that when we do make CC="$CC" it isn't empty. Doing it
|
||||||
|
# this way allows us to have the user specify a different compiler in an easy
|
||||||
|
# way.
|
||||||
|
if [[ -z "$CC" ]]; then
|
||||||
|
CC="cc"
|
||||||
|
fi
|
||||||
|
|
||||||
|
make CC="$CC" all >/dev/null || exit 1
|
||||||
|
|
||||||
|
# clear screen after compilation so that only the entry is shown
|
||||||
|
clear
|
||||||
|
|
||||||
|
echo "$ cat prog.c" 1>&2
|
||||||
|
cat prog.c
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
echo "$ ./prog | diff -s - prog.c"
|
||||||
|
./prog | diff -s - prog.c
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
echo "$ less -EXF prog.c" 1>&2
|
||||||
|
read -r -n 1 -p "Press any key to continue: "
|
||||||
|
less -EXF prog.c
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
echo "$ wc -c prog.c" 1>&2
|
||||||
|
wc -c prog.c
|
||||||
|
echo 1>&2
|
||||||
|
echo "Can you figure out the inconsistencies?" 1>&2
|
||||||
|
echo "If you can't or you're still confused try" 1>&2
|
||||||
|
echo "opening prog.c in an editor like vim." 1>&2
|
||||||
@@ -135,7 +135,7 @@ all: data ${TARGET}
|
|||||||
${PROG}: ${PROG}.c
|
${PROG}: ${PROG}.c
|
||||||
${CC} ${CFLAGS} $< -o $@ ${LDFLAGS}
|
${CC} ${CFLAGS} $< -o $@ ${LDFLAGS}
|
||||||
|
|
||||||
mullender back_to: ${PROG}.c mullender.c
|
future mullender back_to: ${PROG}.c mullender.c
|
||||||
${CC} ${CFLAGS} $< -o ${PROG} ${LDFLAGS} ${BACK_TO}
|
${CC} ${CFLAGS} $< -o ${PROG} ${LDFLAGS} ${BACK_TO}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -17,14 +17,12 @@ make
|
|||||||
To see the original [mullender](mullender.c) in action:
|
To see the original [mullender](mullender.c) in action:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cc -o prog prog.c mullender.c # or make mullender or make back_to
|
./try.sh
|
||||||
./prog
|
|
||||||
q
|
|
||||||
^C # where ^C is ctrl-C, interrupt.
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Observe what happens when you hit enter or another character! Send INTR to end
|
Observe what happens when you hit enter or another character! You might even try
|
||||||
the program.
|
typing out, one character at a time, `1984/mullender`, and then see what it looks
|
||||||
|
like at the end. Send INTR to end the program.
|
||||||
|
|
||||||
More generally use:
|
More generally use:
|
||||||
|
|
||||||
@@ -34,7 +32,7 @@ cc -o prog prog.c foo.c
|
|||||||
^C # if necessary, where ^C is ctrl-C, interrrupt
|
^C # if necessary, where ^C is ctrl-C, interrrupt
|
||||||
```
|
```
|
||||||
|
|
||||||
to run `prog` as whatever foo.c is in the joke PDP-11 emulator.
|
to compile and run `prog` as whatever foo.c is in the joke PDP-11 emulator.
|
||||||
|
|
||||||
|
|
||||||
## Judges' remarks:
|
## Judges' remarks:
|
||||||
@@ -55,6 +53,7 @@ clue, see the end of the author's remarks.) If in doubt, use
|
|||||||
|
|
||||||
## Author's remarks:
|
## Author's remarks:
|
||||||
|
|
||||||
|
|
||||||
### Hint / Compatibility
|
### Hint / Compatibility
|
||||||
|
|
||||||
* A little-endian system is required due to an external factor.
|
* A little-endian system is required due to an external factor.
|
||||||
@@ -65,6 +64,7 @@ the same reason. But I believe it is reasonably portable.
|
|||||||
the source code from all angles..
|
the source code from all angles..
|
||||||
* Find `main()` function.
|
* Find `main()` function.
|
||||||
|
|
||||||
|
|
||||||
### Spoiler
|
### Spoiler
|
||||||
|
|
||||||
This program is a joke PDP-11 emulator. ("ll-dpd" is embedded in the code.
|
This program is a joke PDP-11 emulator. ("ll-dpd" is embedded in the code.
|
||||||
@@ -80,6 +80,7 @@ clang -o prog prog.c mullender.c
|
|||||||
|
|
||||||
You can enjoy the legendary winner of the first IOCCC, again.
|
You can enjoy the legendary winner of the first IOCCC, again.
|
||||||
|
|
||||||
|
|
||||||
### Internal
|
### Internal
|
||||||
|
|
||||||
This program uses `__attribute__((constructor))`, which is a GCC extension, to
|
This program uses `__attribute__((constructor))`, which is a GCC extension, to
|
||||||
@@ -104,6 +105,7 @@ needed for [mullender.c](mullender.c) to work:
|
|||||||
* 4: Auto-decrement deferred
|
* 4: Auto-decrement deferred
|
||||||
* 6: Index (incomplete)
|
* 6: Index (incomplete)
|
||||||
|
|
||||||
|
|
||||||
### Limitations
|
### Limitations
|
||||||
|
|
||||||
Non-trivial combination of instruction and addressing mode may cause undefined
|
Non-trivial combination of instruction and addressing mode may cause undefined
|
||||||
|
|||||||
Executable
+36
@@ -0,0 +1,36 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# try.sh - demonstrate IOCCC winner 2015/endoh3
|
||||||
|
#
|
||||||
|
|
||||||
|
# make sure CC is set so that when we do make CC="$CC" it isn't empty. Doing it
|
||||||
|
# this way allows us to have the user specify a different compiler in an easy
|
||||||
|
# way.
|
||||||
|
if [[ -z "$CC" ]]; then
|
||||||
|
CC="cc"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# clear screen so that only the entry is shown
|
||||||
|
clear
|
||||||
|
|
||||||
|
read -r -n 1 -p "Press any key to run: less -EXF prog.c (space = next page, q = quit): "
|
||||||
|
echo 1>&2
|
||||||
|
less -EXF prog.c
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
echo "$ make future" 1>&2
|
||||||
|
make future || exit 1
|
||||||
|
|
||||||
|
echo 1>&2
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
echo "Will go back to the future and run 1984/mullender through prog. To quit" 1>&2
|
||||||
|
echo "the program hit ctrl-c/intr." 1>&2
|
||||||
|
echo 1>&2
|
||||||
|
echo "You might want to try hitting enter or another key when the output reaches" 1>&2
|
||||||
|
echo "the end of the line." 1>&2
|
||||||
|
echo 1>&2
|
||||||
|
read -r -n 1 -p "Press any key to continue: "
|
||||||
|
echo 1>&2
|
||||||
|
echo "$ ./prog" 1>&2
|
||||||
|
./prog
|
||||||
+14
-12
@@ -5,6 +5,10 @@ make
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
There is an alt version which is the originally submitted entry. See [Alternate
|
||||||
|
code](#alternate-code) below for details.
|
||||||
|
|
||||||
|
|
||||||
## To use:
|
## To use:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
@@ -15,29 +19,27 @@ make
|
|||||||
### Try:
|
### Try:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./prog @ @ @ @ @ @
|
./try.sh
|
||||||
|
|
||||||
./prog @ @ @ @ @ @ @ @ @ @ @ @
|
|
||||||
|
|
||||||
./prog $(perl -e 'print "@ " x (2*3*5*7);')
|
|
||||||
|
|
||||||
./prog $(< Makefile)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Alternate code:
|
## Alternate code:
|
||||||
|
|
||||||
An alternate version of this entry, `prog.alt.c`, is provided.\
|
An alternate version of this entry, [prog.alt.c](prog.alt.c), is provided.
|
||||||
This alternate code does not contain improvements suggested by [Gil
|
This alternate code does not contain improvements suggested by [Gil
|
||||||
Dogon](/winners.html#Gil_Dogon); it is
|
Dogon](/winners.html#Gil_Dogon); it is the author's original entry.
|
||||||
the author's original entry.
|
|
||||||
|
|
||||||
|
### Alternate build:
|
||||||
|
|
||||||
To compile this alternate version:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make alt
|
make alt
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Alternate use:
|
||||||
|
|
||||||
Use `prog.alt` as you would `prog` above.
|
Use `prog.alt` as you would `prog` above.
|
||||||
|
|
||||||
|
|
||||||
@@ -67,7 +69,7 @@ gcc -o prog prog.c
|
|||||||
Inspired by [Animated Factorization
|
Inspired by [Animated Factorization
|
||||||
Diagrams](http://www.datapointed.net/visualizations/math/factorization/animated-diagrams/).
|
Diagrams](http://www.datapointed.net/visualizations/math/factorization/animated-diagrams/).
|
||||||
|
|
||||||
`prog.alt.c` is the original version that I submitted. [Gil
|
[prog.alt.c](prog.alt.c) is the original version that I submitted. [Gil
|
||||||
Dogon](/winners.html#Gil_Dogon) kindly improved it during the review. Thank
|
Dogon](/winners.html#Gil_Dogon) kindly improved it during the review. Thank
|
||||||
you!
|
you!
|
||||||
|
|
||||||
|
|||||||
Executable
+58
@@ -0,0 +1,58 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# try.sh - demonstrate IOCCC winner 2015/endoh4
|
||||||
|
#
|
||||||
|
|
||||||
|
# make sure CC is set so that when we do make CC="$CC" it isn't empty. Doing it
|
||||||
|
# this way allows us to have the user specify a different compiler in an easy
|
||||||
|
# way.
|
||||||
|
if [[ -z "$CC" ]]; then
|
||||||
|
CC="cc"
|
||||||
|
fi
|
||||||
|
|
||||||
|
make CC="$CC" all >/dev/null || exit 1
|
||||||
|
|
||||||
|
# clear screen after compilation so that only the entry is shown
|
||||||
|
clear
|
||||||
|
|
||||||
|
PERL="$(type -P perl)"
|
||||||
|
|
||||||
|
echo "$ ./prog @" 1>&2
|
||||||
|
./prog @
|
||||||
|
|
||||||
|
echo "$ ./prog @ @" 1>&2
|
||||||
|
./prog @ @
|
||||||
|
|
||||||
|
echo "$ ./prog @ @ @" 1>&2
|
||||||
|
./prog @ @ @
|
||||||
|
|
||||||
|
echo "$ ./prog @ @ @ @ @" 1>&2
|
||||||
|
./prog @ @ @ @ @
|
||||||
|
|
||||||
|
echo "$ ./prog @ @ @ @ @ @" 1>&2
|
||||||
|
./prog @ @ @ @ @ @
|
||||||
|
|
||||||
|
echo "$ ./prog @ @ @ @ @ @ @" 1>&2
|
||||||
|
./prog @ @ @ @ @ @ @
|
||||||
|
|
||||||
|
echo "$ ./prog @ @ @ @ @ @ @ @" 1>&2
|
||||||
|
./prog @ @ @ @ @ @ @ @
|
||||||
|
|
||||||
|
echo "$ ./prog @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @" 1>&2
|
||||||
|
./prog @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
|
||||||
|
|
||||||
|
echo "$ ./prog @ @ @ @ @ @ @ @ @ @ @ @" 1>&2
|
||||||
|
./prog @ @ @ @ @ @ @ @ @ @ @ @
|
||||||
|
|
||||||
|
echo "$ ./prog \"\$(< Makefile)\"" 1>&2
|
||||||
|
read -r -n 1 -p "Press any key to continue: "
|
||||||
|
echo 1>&2
|
||||||
|
./prog "$(< Makefile)"
|
||||||
|
|
||||||
|
if [[ -n "$PERL" ]]; then
|
||||||
|
echo "$ ./prog \$($PERL -e 'print "@ " x (2*3*5*7);')" 1>&2
|
||||||
|
read -r -n 1 -p "Press any key to continue: "
|
||||||
|
echo 1>&2
|
||||||
|
./prog "$($PERL -e 'print "@ " x (2*3*5*7);')"
|
||||||
|
fi
|
||||||
|
|
||||||
+22
-6
@@ -5,10 +5,24 @@ make
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Bugs and (Mis)features:
|
||||||
|
|
||||||
|
The current status of this entry is:
|
||||||
|
|
||||||
|
```
|
||||||
|
STATUS: INABIAF - please **DO NOT** fix
|
||||||
|
```
|
||||||
|
|
||||||
|
For more detailed information see [2015 hou in bugs.md](/bugs.md#2015-hou).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## To use:
|
## To use:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
echo IOCCC | ./prog
|
echo something | ./prog
|
||||||
|
./prog < file
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -37,7 +51,7 @@ Some things that make you go, "huh?"
|
|||||||
|
|
||||||
How are those values magically returned?
|
How are those values magically returned?
|
||||||
|
|
||||||
What happens with a large file? Something over 256K
|
What happens with a large file? Something over 256K.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./prog < large_file
|
./prog < large_file
|
||||||
@@ -50,7 +64,7 @@ Where does that message come from?
|
|||||||
|
|
||||||
This looks like a normal C program.
|
This looks like a normal C program.
|
||||||
|
|
||||||
Almost everything is a double.
|
Almost everything is a `double`.
|
||||||
|
|
||||||
There are tell-tale signs like `pow(2,(?/12))` and `exp(-?*?)` (names redacted).
|
There are tell-tale signs like `pow(2,(?/12))` and `exp(-?*?)` (names redacted).
|
||||||
You can also find a bunch of cosines and polynomial evaluations.
|
You can also find a bunch of cosines and polynomial evaluations.
|
||||||
@@ -59,6 +73,7 @@ It looks like a ????? ???????????, right?
|
|||||||
|
|
||||||
Run and find out.
|
Run and find out.
|
||||||
|
|
||||||
|
|
||||||
### Why obfuscated
|
### Why obfuscated
|
||||||
|
|
||||||
Some poor scripting folks only have access to doubles (Jav?script, L?a, BA?IC,
|
Some poor scripting folks only have access to doubles (Jav?script, L?a, BA?IC,
|
||||||
@@ -72,10 +87,11 @@ isn't a single integer. Even `getchar()` and `EOF` are immediately converted.
|
|||||||
|
|
||||||
Since `bool` counts as an integer type too, there is no boolean either. No
|
Since `bool` counts as an integer type too, there is no boolean either. No
|
||||||
comparison, no `if`, no `?:`, no `||` `&&`. Everything is done in a single loop
|
comparison, no `if`, no `?:`, no `||` `&&`. Everything is done in a single loop
|
||||||
that terminates on printf. Straight up arithmetic.
|
that terminates on `printf(3)`. Straight up arithmetic.
|
||||||
|
|
||||||
|
`floor(3)` and `ceil(3)` are technically double-to-double functions, but they feel
|
||||||
|
like cheating. Yes `cos(3)`, no `floor(3)`.
|
||||||
|
|
||||||
`floor` and `ceil` are technically double-to-double functions, but they feel
|
|
||||||
like cheating. Yes `cos`, no `floor`.
|
|
||||||
|
|
||||||
### Limitations
|
### Limitations
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Executable
+45
@@ -0,0 +1,45 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# try.sh - demonstrate IOCCC winner 2015/hou
|
||||||
|
#
|
||||||
|
|
||||||
|
# make sure CC is set so that when we do make CC="$CC" it isn't empty. Doing it
|
||||||
|
# this way allows us to have the user specify a different compiler in an easy
|
||||||
|
# way.
|
||||||
|
if [[ -z "$CC" ]]; then
|
||||||
|
CC="cc"
|
||||||
|
fi
|
||||||
|
|
||||||
|
make CC="$CC" all >/dev/null || exit 1
|
||||||
|
|
||||||
|
# clear screen after compilation so that only the entry is shown
|
||||||
|
clear
|
||||||
|
|
||||||
|
|
||||||
|
echo "$ echo IOCCC | ./prog" 1>&2
|
||||||
|
echo IOCCC | ./prog
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
echo "$ ./prog < rfc1321.txt" 1>&2
|
||||||
|
./prog < rfc1321.txt
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
echo "$ echo \"\" | ./prog" 1>&2
|
||||||
|
echo "" | ./prog
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
echo "For the next two, observe the magical values: "
|
||||||
|
read -r -n 1 -p "Press any key to continue: "
|
||||||
|
echo 1>&2
|
||||||
|
echo "$ ./prog < prog.c | cut -c-5" 1>&2
|
||||||
|
./prog < prog.c | cut -c-5
|
||||||
|
|
||||||
|
echo "$ ./prog < Makefile | cut -c-4" 1>&2
|
||||||
|
./prog < Makefile | cut -c-4
|
||||||
|
echo 1>&2
|
||||||
|
|
||||||
|
echo "$ wc -c large" 1>&2
|
||||||
|
wc -c large
|
||||||
|
|
||||||
|
echo "$ ./prog < large" 1>&2
|
||||||
|
./prog < large
|
||||||
+543
-551
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user