2015-02-25 14:21:22 +00:00
|
|
|
/*
|
|
|
|
Based on work of Marcus Comstedt
|
|
|
|
http://mc.pp.se, http://mc.pp.se/dc/sw.html, http://mc.pp.se/dc/files/scramble.c
|
|
|
|
License: Gotta verify
|
|
|
|
|
|
|
|
Adapted by Stefanos Kornilios Mitsis Poiitidis (skmp) for reicast
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "descrambl.h"
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
#define MAXCHUNK (2048*1024)
|
|
|
|
|
2022-07-21 08:43:45 +00:00
|
|
|
static u32 seed;
|
2015-02-25 14:21:22 +00:00
|
|
|
|
2022-07-21 08:43:45 +00:00
|
|
|
static void my_srand(u32 n)
|
2015-02-25 14:21:22 +00:00
|
|
|
{
|
|
|
|
seed = n & 0xffff;
|
|
|
|
}
|
|
|
|
|
2022-07-21 08:43:45 +00:00
|
|
|
static u32 my_rand()
|
2015-02-25 14:21:22 +00:00
|
|
|
{
|
|
|
|
seed = (seed * 2109 + 9273) & 0x7fff;
|
|
|
|
return (seed + 0xc000) & 0xffff;
|
|
|
|
}
|
|
|
|
|
2022-07-21 08:43:45 +00:00
|
|
|
static void load_chunk(const u8* &src, u8 *ptr, u32 sz)
|
2015-02-25 14:21:22 +00:00
|
|
|
{
|
2015-02-25 18:47:09 +00:00
|
|
|
verify(sz <= MAXCHUNK);
|
2015-02-25 14:21:22 +00:00
|
|
|
|
|
|
|
static int idx[MAXCHUNK / 32];
|
|
|
|
|
|
|
|
/* Convert chunk size to number of slices */
|
|
|
|
sz /= 32;
|
|
|
|
|
|
|
|
/* Initialize index table with unity,
|
|
|
|
so that each slice gets loaded exactly once */
|
2020-06-17 20:58:26 +00:00
|
|
|
for (u32 i = 0; i < sz; i++)
|
2015-02-25 14:21:22 +00:00
|
|
|
idx[i] = i;
|
|
|
|
|
2020-06-17 20:58:26 +00:00
|
|
|
for (int i = sz - 1; i >= 0; --i)
|
2015-02-25 14:21:22 +00:00
|
|
|
{
|
|
|
|
/* Select a replacement index */
|
|
|
|
int x = (my_rand() * i) >> 16;
|
|
|
|
|
|
|
|
/* Swap */
|
2020-03-29 17:29:14 +00:00
|
|
|
std::swap(idx[i], idx[x]);
|
2015-02-25 14:21:22 +00:00
|
|
|
|
|
|
|
/* Load resulting slice */
|
|
|
|
memcpy(ptr + 32 * idx[i], src, 32);
|
|
|
|
src += 32;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-21 08:43:45 +00:00
|
|
|
void descrambl_buffer(const u8 *src, u8 *dst, u32 size)
|
2015-02-25 14:21:22 +00:00
|
|
|
{
|
2022-07-21 08:43:45 +00:00
|
|
|
u32 chunksz;
|
2015-02-25 14:21:22 +00:00
|
|
|
|
2022-07-21 08:43:45 +00:00
|
|
|
my_srand(size);
|
2015-02-25 14:21:22 +00:00
|
|
|
|
|
|
|
/* Descramble 2 meg blocks for as long as possible, then
|
|
|
|
gradually reduce the window down to 32 bytes (1 slice) */
|
|
|
|
for (chunksz = MAXCHUNK; chunksz >= 32; chunksz >>= 1)
|
2022-07-21 08:43:45 +00:00
|
|
|
while (size >= chunksz)
|
2015-02-25 14:21:22 +00:00
|
|
|
{
|
|
|
|
load_chunk(src, dst, chunksz);
|
2022-07-21 08:43:45 +00:00
|
|
|
size -= chunksz;
|
2015-02-25 14:21:22 +00:00
|
|
|
dst += chunksz;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Load final incomplete slice */
|
2022-07-21 08:43:45 +00:00
|
|
|
if (size)
|
|
|
|
memcpy(dst, src, size);
|
2020-06-17 20:58:26 +00:00
|
|
|
}
|