Table of contents
Bisqwit: For now, I am opposed against mechanically changing all quotes [1]. I have noticed
that some machine translators, such as Excite, cannot cope with the typographically proper quotes. Thus I try to avoid inserting them in contexts that I think I would like to be understood through machine translation too ― that being the important pages such as MovieRules.
This is one of the reasons why I actually try to avoid quotes altogether, by replacing
Notice that the
[1]: Actually, against all mechanical changes, such as timeattack→TAS or nesvideos→tasvideos…
This is one of the reasons why I actually try to avoid quotes altogether, by replacing
it'swith
it is, for example.
Notice that the
<q>
tag (that comes from the «« »» markup) does not suffer from this limitation.[1]: Actually, against all mechanical changes, such as timeattack→TAS or nesvideos→tasvideos…
This program was motivated out of a desire to program something that transfers input by specifying only the target frame where to start to overwrite and the source frame from where to transfer.
It is currently experimental, and it looks bad, but it works (with VBM files). It does not work with anything but VBM files. Back-up your movie files if you use something like this.
P.S. The downloaded ROM came with the misspelling "Tommorow". I didn't spell it wrong; I just didn't bother to fix it. :)
P.P.S. The filenames listed are only examples. Use whatever fits the situation.
vbmfuse.cc:
#include <stdio.h>
long rlong(FILE *f);
int main()
{
FILE *f, *g; //source; target
unsigned long d, frame;
int y;
if(!(f=fopen("zzzz.vbm","rb")))
{
printf("No source");
goto qq2;
}
if(!(g=fopen("1626 - Tom Clancy's Splinter Cell - Pandora Tommorow (U)(Chameleon).vbm","rb+")))
{
printf("No target");
goto qq1;
}
fseek(f,0x3C,0);
d=rlong(f);
printf("Target frame:");
scanf("%d", &frame);
fseek(g,0x3C,0);
d=rlong(g);
printf("Source frame:");
scanf("%d", &frame);
fseek(f,0x3C,0);
d=rlong(f);
fseek(g,d+frame*2,0);
fseek(f,d+frame*2,0);
while(1)
{
y=fgetc(f);
if(feof(f)) break;
fputc(y,g);
}
fseek(g,0xE,0);
fputc(0x10, g);
qq:
fclose(g);
qq1:
fclose(f);
qq2:
return(0);
}
long rlong(FILE *f)
{
unsigned long d=0;
d+=fgetc(f);
d+=fgetc(f)*256;
d+=fgetc(f)*256*256;
d+=fgetc(f)*256*256*256;
return(d);
}
Inappropriately named quotes2.cc, this program changes code or code-like text to adapt to this wiki. It does this by indenting each line by one space, breaking some double-brackets, and doubling [ and ].
Don't use this program and then try to %%SRC_EMBED it. %%SRC_EMBED function operates differently from the wiki.
quotes2.cc:
#include <stdio.h>
#include <string.h>
int main (int argc, char *argv[])
{
FILE *fp, *fq;
char fn[100];
char c[15]="_COPY.txt";
char x,y;
if(argc<2)
return 1;
strncpy(fn,argv[1],80);
printf("%s", fn);
if(!(fp = fopen(fn,"rb")))
return 1;
strncat(fn,c,12);
if(!(fq = fopen(fn,"wb")))
{
fclose(fq);
return 1;
}
y=0;
while(1)
{
x=y;
y=fgetc(fp);
if(feof(fp))
break;
if(y=='\n')
{
fputc(y,fq);
fputc(' ',fq);
}
else if(( x=='{' || x=='(' || x=='}' || x==')' ) && y==x)
{
fputc('\'',fq); fputc('\'',fq);
fputc('\'',fq); fputc('\'',fq);
fputc(y,fq);
}
else if(( y=='[' || y==']'))
{
fputc(y,fq); fputc(y,fq);
}
else
{
fputc(y,fq);
}
}
fclose(fq);
fclose(fp);
return 0;
}
This program puts random numbers for each byte into a file. I used this for my Mega Man X submission and one of my avatars.
garbagegenerator.cc:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
srand(unsigned(time(0)));
FILE *fp;
int i,j;
long k;
if(!(fp=fopen("wxyz","wb")))
return 1;
printf("How many bytes of garbage do you want?");
scanf("%d",&k);
for(i=1;i<=k;i++)
fputc(rand()%256,fp);
fclose(fp);
return(0);
}
This program simulates the slot machine in Space Quest 1 EGA.
All probabilities were discovered by decompilation of SQ1 using AGI Studio.
The resulting ratio of successes to trials appears to confirm the value given
by the slot machine solver program (0.00666, 1 in 150). If
bz
is set to 40 and the
success point at 250, the ratio drops to about 0.0062 (1 in 160).
sq1slotmachine2.cc:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define LIMIT 1000000
int main()
{
long i,success=0, skulls=0;
int bz, c, bet;
srand(unsigned(time(0)));
for(i=1;i<=LIMIT;i++)
{
bz=42;
while(1)
{
c=rand()%100+1;
bet=3;
if (c<=2) {skulls++; bz=0;}
else if (c<=70) bz-=bet;
else if (c<=77) bz+=2*bet;
else if (c<=81) bz+=4*bet;
else if (c<=83) bz+=9*bet;
else if (c<=84) bz+=19*bet;
if (bz<=0) break;
if (bz>=249) {success++; break;}
}
}
printf("%d %f %d",success, ((float)success)/LIMIT, skulls);
getchar();
return(0);
}
This program implements a Markov matrix representation for the slot machine
in Space Quest 1 EGA.
All probabilities were discovered by decompilation of SQ1 using AGI Studio.
Repeatedly squaring this matrix 50 times
(way too much, 15 is sufficient) brings the matrix to a limit (single-precision floating point). Note that there
are two absorbing states: 0 (lose) and 83 (win). All other states represent
buckazoids (currency in SQ1) divided by 3.
Starting from 42 buckazoids, the probability of making it to 249 buckazoids is about
0.006656957131849 (1 in 150.218783175827).
The theory behind the matrix representation is that there is a base matrix which represents 1-step (2^0-step) probability from one state to another. Every time the matrix is squared, it doubles the number of steps from n-step probability to 2*n-step probability. Squaring the base matrix 50 times results in a 2^50-step probability matrix. For most matrices, the probability values reach a limit.
Read the resulting output file with word-wrap off. The row numbers are prior states and the column numbers are final states. Only the final states 0 and 83 should have positive numbers.
sq1slotmachine.cc
#include <stdio.h>
void initarray();
int min(int a, int b);
void squarearray();
void printarray();
FILE *fp;
double m[84][84];
int main()
{
int x;
if(!(fp=fopen("wxyz2.txt","w")))
return 1;
initarray();
for(x=1;x<=50;x++)
squarearray();
printarray();
return(0);
}
void printarray()
{
//header
int i,j;
fprintf(fp,"\t");
for(i=0;i<=83;i++)
fprintf(fp,"%d\t",i);
fprintf(fp,"\n");
//rest
for(i=0;i<=83;i++)
{
fprintf(fp, "%d\t",i);
for(j=0;j<=83;j++)
fprintf(fp, "%.5f\t",m[i][j]);
fprintf(fp, "\n");
}
}
void initarray()
{
int i,j;
for(i=0;i<=83;i++)
for(j=0;j<=83;j++)
m[i][j]=0;
m[0][0]=1; //lose
m[83][83]=1; //win
for(i=1;i<83;i++)
{
m[i][0]+=0.02; //skulls
m[i][i-1]+=0.68; //nothing
m[i][i]+=0.16; //1 cherry
m[i][min(83,i+2)]+=0.07; //2 cherries
m[i][min(83,i+4)]+=0.04; //3 cherries
m[i][min(83,i+9)]+=0.02; //eyes
m[i][min(83,i+19)]+=0.01; //diamonds
}
}
void squarearray()
{
int i,j,k;
double n[84][84];
double sum;
for(i=0;i<=83;i++)
for(j=0;j<=83;j++)
{
sum=0;
for(k=0;k<=83;k++)
sum+=m[i][k]*m[k][j];
n[i][j]=sum;
}
for(i=0;i<=83;i++)
for(j=0;j<=83;j++)
m[i][j]=n[i][j];
}
int min(int a, int b)
{
return ((a<b)?a:b);
}
This program calculates a score for an .smv based on left-right-left wobbling.
Left-right-left scores 1 point.
Right-left-right scores 1 point.
(Left+right)=right
#include <stdio.h>
#include <string.h>
long rlong(FILE *f);
int main (int argc, char *argv[])
{
FILE *fp;
char fn[200];
unsigned int x,y,z;
long score=0, offset;
if(argc<2)
{
printf("sdikuthw");
getchar();
return 1;
}
strncpy(fn,argv[1],180);
if((fp = fopen(fn,"rb"))==NULL)
{
printf("%s",fn);
getchar();
return 1;
}
fseek(fp,0x1C,0);
offset=rlong(fp);
fseek(fp,offset,0);
x=fgetc(fp);
x=256*x+fgetc(fp);
y=fgetc(fp);
y=256*y+fgetc(fp);
z=fgetc(fp);
z=256*z+fgetc(fp);
while(1)
{
if ( ( ((x&3)==1)&&((y&3)==2)&&((z&3)==1) ) || ( ((x&3)==2)&&((y&3)==1)&&((z&3)==2) ) )
score++;
if ( ( ((x&3)==3)&&((y&3)==2)&&((z&3)==3) ) || ( ((x&3)==2)&&((y&3)==3)&&((z&3)==2) ) )
score++; //leftright
x=y;
y=z;
z=fgetc(fp);
z=256*z+fgetc(fp);
if(feof(fp))
break;
}
printf("%d",score);
getchar();
return(0);
}
long rlong(FILE *f)
{
unsigned long d=0;
d+=fgetc(f);
d+=fgetc(f)*256;
d+=fgetc(f)*256*256;
d+=fgetc(f)*256*256*256;
return(d);
}
This program generates a colorful 80x80 .bmp.
rainbow.cc:
#include <stdio.h>
#include <math.h>
#include <string.h>
long hue(int angle, float r);
float arg(float x, float y);
float rad(float x, float y);
int main()
{
FILE *f;
int x,y;
float zarg, zrad;
long h;
unsigned char red,blue,green;
char header[]={0x42,0x4d,0x0a,0xb7,0x02,0,0,0,0,0,
0x36,0,0,0,0x28,0,0,0,0x50,0,0,0,0x50,0,0,0,
0x01,0,0x18,0,0,0,0,0,0xd4,0xb6,0x02,
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0};
if(!(f=fopen("rainbow.bmp","wb")))
{
printf("fail");
getchar();
return(1);
}
fwrite(header,1,54,f);
for(x=1;x<=80;x++)
{
for(y=1;y<=80;y++)
{
zarg=arg((float)(x-40),(float)(y-40));
zrad=rad((float)(x-40),(float)(y-40));
h=hue((int)(((float)240/360)*zarg),zrad/40);
red=h%256;
h/=256;
green=h%256;
h/=256;
blue=h%256;
fputc(blue,f);
fputc(green,f);
fputc(red,f);
}
}
/*
float s;
s=arg(1,1);
printf("%f\n",s);
printf("%X",hue(111));
*/
fclose(f);
getchar();
return(0);
}
float rad(float x, float y)
{
return(sqrt(x*x+y*y));
}
float arg(float x, float y)
{
float c;
if(x==0 && y==0) return(0);
c=(180/3.141592654)*acos(x/sqrt(x*x+y*y));
if(y>=0) return(c); else return(360-c);
}
long hue(int angle, float r)
{
unsigned char red=0, blue=0, green=0;
unsigned long s;
if(angle>=0 && angle<40) //r g^ b
{
red=255;
green=(char)(((float)255/40)*angle);
blue=0;
}
if(angle>=40 && angle<80) //rv g b
{
red=(char)(((float)255/40)*(80-angle));
green=255;
blue=0;
}
if(angle>=80 && angle<120) //r g b^
{
red=0;
green=255;
blue=(char)(((float)255/40)*(angle-80));
}
if(angle>=120 && angle<160) //r gv b
{
red=0;
green=(char)(((float)255/40)*(160-angle));
blue=255;
}
if(angle>=160 && angle<200) //r^ g b
{
red=(char)(((float)255/40)*(angle-160));
green=0;
blue=255;
}
if(angle>=200 && angle<240) //r g bv
{
red=255;
green=0;
blue=(char)(((float)255/40)*(240-angle));
}
if(r>=0 && r<1)
{
blue=(char)(blue*r);
green=(char)(green*r);
red=(char)(red*r);
}
if(r>=1 && r<2)
{
blue=(char)(255-(255-blue)*(2-r));
green=(char)(255-(255-green)*(2-r));
red=(char)(255-(255-red)*(2-r));
}
s=blue;
s=s*256+green;
s=s*256+red;
return(s);
}
Bisqwit: May I humbly suggest the following refactoring for that code:
#include <complex>
#include <cstdio>
/* hsv_to_rgb:
* Converts from HSV (hue, saturation, value) colorspace
* to RGB values (red, green, blue).
*/
template<typename IntType>
static void hsv_to_bgr
(double h, double s, double v,
IntType bgr[3])
{
v *= 255.0;
if (s == 0.0)
bgr[0] = bgr[1] = bgr[2] = IntType(v);
else
{
while (h < 0)h += 360;
h = fmod(h, 360.0) / 60.0;
int i = (int)h;
double frac = h - i;
double p = v - v * s, qt = v * s * frac;
bgr[ (10-i)%6/2 ] = IntType(v); // max
bgr[ (7-i)%6/2 ] = IntType(p); // min
bgr[ (i+1)%3 ] = IntType(
(i&1) ? v - qt // max downto min
: p + qt ); // min upto max
}
}
int main()
{
static const char fn[] = "rainbow.tga";
const int Xdim = 80, Ydim = 80;
std::FILE* fp = fopen(fn, "wb");
if(!fp) { perror(fn); return -1; }
static const unsigned char tgaBuf[] = {
0,0,2, 0,0, 0,0, 0, 0,0, 0,0,
Xdim&255, Xdim>>8,
Ydim&255, Ydim>>8,
24,32};
std::fwrite(tgaBuf, 1, sizeof(tgaBuf), fp);
for(int y=0; y<Ydim; ++y)
for(int x=0; x<Xdim; ++x)
{
std::complex<double> c ( 1.0-y*2.0/Ydim, x*2.0/Xdim-1.0 );
/* Using complex numbers here because it hides the trigonometric
* calculations (angle, distance) rather nicely.
* Note: Y axis is reversed because Tga file origin is in lower left corner.
*/
double h = std::arg(c) * 180.0 / 3.141592653; /* Radians to degrees */
double v = std::abs(c);
double s = 1.0;
if(v > 1.0)
{
s = std::max(0.0, s - (v-1.0) / 0.414); // vary saturation for corners (optional)
v = 1.0; // clamp brightness to maximum
}
unsigned char bgr[3] /* blue, green, red */;
hsv_to_bgr(h, s, v, bgr);
std::fwrite(bgr, 1, 3, fp);
}
std::fclose(fp);
}