Skip to content

Instantly share code, notes, and snippets.

@grepwood
Last active August 29, 2015 13:57
Show Gist options
  • Save grepwood/9448799 to your computer and use it in GitHub Desktop.
Save grepwood/9448799 to your computer and use it in GitHub Desktop.
Prototype for SDL_Loading a RIX3
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
/* x86
#if HAVE_MMX || if HAVE_SSE || if HAVE_AVX2
# include <xmmintrin.h>
#endif*/
/* PowerPC
#if HAVE_ALTIVEC
# include <altivec.h>
#endif*/
/* ARM
#if HAVE_NEON
# include <neon.h>
#endif*/
/*#include <SDL2/SDL.h>*/
#include <rix/rix.h>
#include <dataio/BigEndian.h>
/* Returns 0b00011111 subtract failed criterions
* Signature is 0th bit
* File size is 1st bit
* Width is 2nd bit
* Height is 3rd bit
* Control is 4th bit
* We lack use for 5th, 6th and 7th bit
* Consider 31 a 100% match */
char IsFalloutRIX(FILE * Splash) /* File must be set on beginning */
{
char result = 0;
size_t ActualSize = 0;
struct RIXheader RIX = {{0,0,0,0},0,0,0};
if(!ftell(Splash))
{
fseek(Splash,0,SEEK_SET);
}
fread(&RIX.Signature,4,1,Splash);
if(!BigEndian())
{
fread(&RIX.Width,2,1,Splash);
fread(&RIX.Height,2,1,Splash);
fread(&RIX.Unknown,2,1,Splash);
}
else
{
RIX.Width = ReadAlienEndian16(Splash);
RIX.Height = ReadAlienEndian16(Splash);
RIX.Unknown = ReadAlienEndian16(Splash);
}
fseek(Splash,0,SEEK_END);
ActualSize = ftell(Splash);
fseek(Splash,0,SEEK_SET);
if(!strncmp(RIX.Signature,"RIX3",4))
{
result += 1;
}
if(ActualSize == 307978)
{
result += 2;
}
if(RIX.Width == 640)
{
result += 4;
}
if(RIX.Height == 480)
{
result += 8;
}
if(RIX.Unknown == 0x00AF)
{
result += 16;
}
return result;
}
/* MMX */
char * FalloutRIX2BMPMem(FILE * RIX)
{
char RIXPalette[768];
char * bitmap = malloc(921654);
int32_t Position;
uint16_t Counter;
union
{
uint16_t w[8];
uint64_t q[2];
} Index;
union
{
uint8_t b[24];
uint64_t q[3];
} BGR;
/* Simple BMP header for a 640x480x24 pic */
char bmpheader[54] = { 66,77,54,16,14,0,0,0,0,0,54,0,0,0,40,0,0,0,128,2,0,0,224,1,0,0,
1,0,24,0,0,0,0,0,0,16,14,0,19,11,0,0,19,11,0,0,0,0,0,0,0,0,0,0};
memcpy(bitmap,bmpheader,54);
Index.q[0] = 0x0003000300030003;
Index.q[1] = 0x0404040404040404;
__asm__("movq mm7, %0\n" : "=m"(Index.q[0]));
__asm__("movq mm6, %0\n" : "=m"(Index.q[1])); /* We're initializing our multipliers */
fseek(RIX,10,SEEK_SET);
fread(RIXPalette,768,1,RIX);
for(Position = 919734; Position >= 54; Position -= 1920)
{
for(Counter = 0; Counter < 1920; Counter += 24)
{
Index.w[0] = fgetc(RIX);
Index.w[1] = fgetc(RIX);
Index.w[2] = fgetc(RIX);
Index.w[3] = fgetc(RIX);
Index.w[4] = fgetc(RIX);
Index.w[5] = fgetc(RIX);
Index.w[6] = fgetc(RIX);
Index.w[7] = fgetc(RIX);
__asm__("movq mm0, %0\n"
"pmullw mm0, mm7\n"
"movq %0, mm0\n" : "=m"(Index.q[0]));
__asm__("movq mm1, %0\n"
"pmullw mm1, mm7\n"
"movq %0, mm1\n" : "=m"(Index.q[1]));
BGR.b[0] = RIXPalette[Index.w[0]+2];
BGR.b[1] = RIXPalette[Index.w[0]+1];
BGR.b[2] = RIXPalette[Index.w[0]];
BGR.b[3] = RIXPalette[Index.w[1]+2];
BGR.b[4] = RIXPalette[Index.w[1]+1];
BGR.b[5] = RIXPalette[Index.w[1]];
BGR.b[6] = RIXPalette[Index.w[2]+2];
BGR.b[7] = RIXPalette[Index.w[2]+1];
BGR.b[8] = RIXPalette[Index.w[2]];
BGR.b[9] = RIXPalette[Index.w[3]+2];
BGR.b[10] = RIXPalette[Index.w[3]+1];
BGR.b[11] = RIXPalette[Index.w[3]];
BGR.b[12] = RIXPalette[Index.w[4]+2];
BGR.b[13] = RIXPalette[Index.w[4]+1];
BGR.b[14] = RIXPalette[Index.w[4]];
BGR.b[15] = RIXPalette[Index.w[5]+2];
BGR.b[16] = RIXPalette[Index.w[5]+1];
BGR.b[17] = RIXPalette[Index.w[5]];
BGR.b[18] = RIXPalette[Index.w[6]+2];
BGR.b[19] = RIXPalette[Index.w[6]+1];
BGR.b[20] = RIXPalette[Index.w[6]];
BGR.b[21] = RIXPalette[Index.w[7]+2];
BGR.b[22] = RIXPalette[Index.w[7]+1];
BGR.b[23] = RIXPalette[Index.w[7]];
__asm__("movq mm2, %0\n"
"pmulhw mm2, mm6\n"
"movq %0, mm2\n" : "=m"(BGR.q[0]));
__asm__("movq mm3, %0\n"
"pmulhw mm3, mm6\n"
"movq %0, mm3\n" : "=m"(BGR.q[1]));
__asm__("movq mm4, %0\n"
"pmulhw mm4, mm6\n"
"movq %0, mm4\n" : "=m"(BGR.q[2]));
memcpy(bitmap+Position+Counter,BGR.b,24);
}
}
return bitmap;
}
int main(int argc, char * argv[])
{
int result = 0;
FILE * input = NULL;
FILE * output = NULL;
char * memory = NULL;
if(argc != 3)
{
exit(1);
}
input = fopen(argv[1],"rb");
if(IsFalloutRIX(input) == 31)
{
memory = FalloutRIX2BMPMem(input);
output = fopen(argv[2],"wb");
fwrite(memory,921654,1,output);
free(memory);
fclose(output);
}
fclose(input);
return result;
}
@grepwood
Copy link
Author

Revision 6 produces a file whose difference is presented here http://imgur.com/a/Xngv4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment