mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +09:00
Improvement to light blending (can mix sunlight to transparent and luminous tile), failed attempt to perturb terrain, need better algorithm
Former-commit-id: a8b456401859802fe5d19b7d12a41033f2ed3e44 Former-commit-id: 4f4a976e6f295f45519744216704c864afb6d621
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -31,3 +31,9 @@ Crafted tool/weapon size is dependent on the baseRaceMass.
|
||||
* Gemstone tier
|
||||
|
||||
Topaz -> R·G·B -> Diamond·Amethyst
|
||||
|
||||
|
||||
* Colouring
|
||||
|
||||
Natural: Use 4096
|
||||
Magical/Surreal: Use 24 Bits
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
res/graphics/health_bar_colouring_4096.png
Normal file
BIN
res/graphics/health_bar_colouring_4096.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 94 KiB |
BIN
res/graphics/terrain/terrain.raw
Normal file
BIN
res/graphics/terrain/terrain.raw
Normal file
Binary file not shown.
BIN
res/graphics/terrain/terrain24.png
Normal file
BIN
res/graphics/terrain/terrain24.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 96 KiB |
BIN
res/graphics/terrain/terrain_12.raw
Normal file
BIN
res/graphics/terrain/terrain_12.raw
Normal file
Binary file not shown.
@@ -2,7 +2,7 @@
|
||||
|
||||
"LANGUAGE_EN";"[LanguageName] in english";"English";"French";"Spanish";"German";"Italian ";"Portuguese (Brazil)";"Portuguese";"Russian";"Greek";"Turkish";"Danish";"Norwegian";"Swedish";"Dutch";"Polish";"Finnish";"Japanese";"Simplified Chinese";"Traditional Chinese";"Korean";"Czech";"Hungarian";"Romanian";"Thai";"Bulgarian";"Hebrew";"Japanese Kana";"Icelandic"
|
||||
"LANGUAGE_ID";"IETF language tag(s) without dash";"enUS";"frFR";"esES";"deDE";"itIT";"ptBR";"ptPT";"ruRU";"elGR";"trTR";"daDK";"noNB";"svSE";"nlNL";"plPL";"fiFI";"jaJP";"zhCN";"zhTW";"koKR";"csCZ";"huHU";"roRO";"thTH";"bgBG";"heIL";"jakanaJP";"isIC"
|
||||
"LANGUAGE_THIS";"MyLanguage'; in native text";"English";"Français";"Español";"Deutsch";"Italiano";"Português Brasileiro";"Português";"Pусский";"Ελληνικά";"Türkçe";"Dansk";"Norsk Bokmål";"Svenska";"Nederlands";"Polski";"Suomi";"日本語";"简体中文";"繁體中文";"한국어";"Čeština";"Magyar";"Română";"ภาษาไทย";"Български";"עברית";"にほんご";"íslenska"
|
||||
"LANGUAGE_THIS";"MyLanguage'; in native text";"English";"Français";"Español";"Deutsch";"Italiano";"Português Brasileiro";"Português";"Pусский";"Ελληνικά";"Türkçe";"Dansk";"Norsk Bokmål";"Svenska";"Nederlands";"Polski";"Suomi";"日本語";"简体中文";"繁體中文";"한국어";"Čeština";"Magyar";"Română";"ภาษาไทย";"Български";"עברית";"にほんご";"Íslenska"
|
||||
"LANGUAGE_DIRECTION";"ltr or rtl (text direction used by game code)";"ltr";"ltr";"ltr";"ltr";"ltr";"ltr";"ltr";"ltr";"ltr";"ltr";"ltr";"ltr";"ltr";"ltr";"ltr";"ltr";"ltr";"ltr";"ltr";"ltr";"ltr";"ltr";"ltr";"ltr";"ltr";"rtl";"ltr";"ltr"
|
||||
|
||||
"CREDITS_POLYGLOT";"";"Translated by the Polyglot Project.";"Traduit par le Polyglot Projet.";"Traducido por el proyecto Polyglot.";"Übersetzt von Polyglot Project.";"Tradotto dal Polyglot Project.";"Traduzido pelo projeto Polyglot.";"Traduzido pelo projeto Polyglot.";"Перевод от проекта Polygon";"Μεταφράστηκε από το Polyglot Project.";"Polyglot Projesi ile çevrilmiştir.";"Oversat af Polyglot Projektet.";"Oversatt av Polyglot Prosjektet.";"Översättning av Polyglot-projektet.";"Vertaald door het Polyglot project.";"Przetłumaczono za pomocą Polyglot Project.";"Käännökset: Polyglot Project.";"翻訳提供:Polyglotプロジェクト";"Polyglot 项目提供翻译";"翻譯由Polyglot Project 提供";"번역 제공: Polyglot Project.";"Překlad: Polyglot Projektu.";"Fordította a Polgylot Project.";"Tradus de către Polyglot Project.";"คำแปลโดย Polyglot Project";"Превод от проекта Polyglot.";"תורגם על-ידי פרויקט פוליגלוט.";"ほんやく ていきょう:Polyglotプロジェクト";"Þýddur af verkefnið Polyglot"
|
||||
|
||||
|
@@ -67,8 +67,15 @@ public class ActorWithBody implements Actor, Visible, Glowing {
|
||||
* meter to pixel : 24/FPS
|
||||
*/
|
||||
private final float METER = 24f;
|
||||
private final float SI_TO_GAME_ACC = METER / (Terrarum.TARGET_FPS * Terrarum.TARGET_FPS);
|
||||
/**
|
||||
* [m / s^2] * SI_TO_GAME_ACC -> [px / IFrame^2]
|
||||
*/
|
||||
private final float SI_TO_GAME_ACC = METER / FastMath.sqr(Terrarum.TARGET_FPS);
|
||||
/**
|
||||
* [m / s] * SI_TO_GAME_VEL -> [px / IFrame]
|
||||
*/
|
||||
private final float SI_TO_GAME_VEL = METER / Terrarum.TARGET_FPS;
|
||||
|
||||
private float gravitation;
|
||||
private final float DRAG_COEFF = 1f;
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ public class Player extends ActorWithBody implements Controllable, Pocketed, Fac
|
||||
|
||||
private final int TSIZE = MapDrawer.TILE_SIZE;
|
||||
|
||||
private char LUMINANCE_RGB = 1560;
|
||||
private char LUMINANCE_RGB = 31960;
|
||||
|
||||
private HashSet<Faction> factionSet = new HashSet<>();
|
||||
|
||||
|
||||
@@ -157,6 +157,14 @@ public class GameMap {
|
||||
else throw new IllegalArgumentException("illegal mode input: " + String.valueOf(mode));
|
||||
}
|
||||
|
||||
public void overwriteLayerWall(MapLayer layerData) {
|
||||
layerWall = layerData;
|
||||
}
|
||||
|
||||
public void overwriteLayerTerrain(MapLayer layerData) {
|
||||
layerTerrain = layerData;
|
||||
}
|
||||
|
||||
private int uint8ToInt32(byte x) {
|
||||
int ret;
|
||||
if ((x & 0b1000_0000) != 0) {
|
||||
|
||||
@@ -109,6 +109,10 @@ public class MapLayer implements Iterable<Byte> {
|
||||
return uint8ToInt32(data[y][x]);
|
||||
}
|
||||
|
||||
public void setTile(int x, int y, byte tile) {
|
||||
data[y][x] = tile;
|
||||
}
|
||||
|
||||
private int uint8ToInt32(byte x) {
|
||||
int ret;
|
||||
if ((x & 0b1000_0000) != 0) {
|
||||
|
||||
@@ -31,3 +31,9 @@ Crafted tool/weapon size is dependent on the baseRaceMass.
|
||||
* Gemstone tier
|
||||
|
||||
Topaz -> R·G·B -> Diamond·Amethyst
|
||||
|
||||
|
||||
* Colouring
|
||||
|
||||
Natural: Use 4096
|
||||
Magical/Surreal: Use 24 Bits
|
||||
@@ -114,9 +114,9 @@ public class LightmapRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
// Round 2
|
||||
for (int y = for_y_start; y < for_y_end; y++) {
|
||||
for (int x = for_x_end - 1; x >= for_x_start; x--) {
|
||||
// Round 4
|
||||
for (int y = for_y_end - 1; y > for_y_start; y--) {
|
||||
for (int x = for_x_start; x < for_x_end; x++) {
|
||||
staticLightMap[y][x] = calculate(x, y);
|
||||
}
|
||||
}
|
||||
@@ -128,12 +128,13 @@ public class LightmapRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
// Round 4
|
||||
for (int y = for_y_end - 1; y > for_y_start; y--) {
|
||||
for (int x = for_x_start; x < for_x_end; x++) {
|
||||
// Round 2
|
||||
for (int y = for_y_start; y < for_y_end; y++) {
|
||||
for (int x = for_x_end - 1; x >= for_x_start; x--) {
|
||||
staticLightMap[y][x] = calculate(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void draw(Graphics g) {
|
||||
@@ -178,23 +179,21 @@ public class LightmapRenderer {
|
||||
* d
|
||||
*/
|
||||
char a = (y == 0) ? thisLightLevel
|
||||
: (y == Terrarum.game.map.height - 1) ? thisLightLevel
|
||||
: max(staticLightMap[y][x]
|
||||
: (y == Terrarum.game.map.height - 1) ? thisLightLevel
|
||||
: maximiseRGB(staticLightMap[y][x]
|
||||
, staticLightMap[y - 1][x]);
|
||||
char d = (y == 0) ? thisLightLevel
|
||||
: (y == Terrarum.game.map.height - 1) ? thisLightLevel
|
||||
: max(staticLightMap[y][x]
|
||||
: (y == Terrarum.game.map.height - 1) ? thisLightLevel
|
||||
: maximiseRGB(staticLightMap[y][x]
|
||||
, staticLightMap[y + 1][x]);
|
||||
char b = (x == 0) ? thisLightLevel
|
||||
: (x == Terrarum.game.map.width - 1) ? thisLightLevel
|
||||
: max(staticLightMap[y][x]
|
||||
: (x == Terrarum.game.map.width - 1) ? thisLightLevel
|
||||
: maximiseRGB(staticLightMap[y][x]
|
||||
, staticLightMap[y][x - 1]);
|
||||
char c = (x == 0) ? thisLightLevel
|
||||
: (x == Terrarum.game.map.width - 1) ? thisLightLevel
|
||||
: max(staticLightMap[y][x]
|
||||
: (x == Terrarum.game.map.width - 1) ? thisLightLevel
|
||||
: maximiseRGB(staticLightMap[y][x]
|
||||
, staticLightMap[y][x + 1]);
|
||||
char t = staticLightMap[y][x];
|
||||
|
||||
char[] colourMapItoL = new char[4];
|
||||
colourMapItoL[0] = colourLinearMix(a, b);
|
||||
colourMapItoL[1] = colourLinearMix(a, c);
|
||||
@@ -252,15 +251,21 @@ public class LightmapRenderer {
|
||||
int thisTerrain = Terrarum.game.map.getTileFromTerrain(x, y);
|
||||
int thisWall = Terrarum.game.map.getTileFromWall(x, y);
|
||||
char thisTileLuminosity = TilePropCodex.getProp(thisTerrain).getLuminosity();
|
||||
char thisTileOpacity = TilePropCodex.getProp(thisTerrain).getOpacity();
|
||||
char sunLight = Terrarum.game.map.getGlobalLight();
|
||||
|
||||
// open air
|
||||
if (thisTerrain == AIR && thisWall == AIR) {
|
||||
lightLevelThis = screenBlend(lightLevelThis, Terrarum.game.map.getGlobalLight());
|
||||
lightLevelThis = sunLight;
|
||||
}
|
||||
|
||||
// mix luminous tile
|
||||
if (thisTileLuminosity > 0) {
|
||||
lightLevelThis = screenBlend(lightLevelThis, thisTileLuminosity);
|
||||
// luminous tile transparent (allows sunlight to pass)
|
||||
else if (thisWall == AIR && thisTileLuminosity < COLOUR_DOMAIN_SIZE) {
|
||||
char darkenSunlight = darkenColoured(sunLight, thisTileOpacity);
|
||||
lightLevelThis = screenBlend(darkenSunlight, thisTileLuminosity);
|
||||
}
|
||||
// luminous tile (opaque)
|
||||
else {
|
||||
lightLevelThis = thisTileLuminosity;
|
||||
}
|
||||
|
||||
// mix lantern
|
||||
@@ -282,7 +287,7 @@ public class LightmapRenderer {
|
||||
}
|
||||
|
||||
|
||||
// calculate and mix ambient
|
||||
// calculate ambient
|
||||
char ambient = 0; char nearby = 0;
|
||||
findNearbyBrightest:
|
||||
for (int yoff = -1; yoff <= 1; yoff++) {
|
||||
@@ -305,7 +310,7 @@ public class LightmapRenderer {
|
||||
else if (xoff != 0 && yoff != 0) { // 'a' tiles
|
||||
if (!outOfMapBounds(x + xoff, y + yoff)) {
|
||||
nearby = darkenUniformInt(staticLightMap[y + yoff][x + xoff]
|
||||
, 2);
|
||||
, 2); //2
|
||||
// mix some to have more 'spreading'
|
||||
// so that light spreads in a shape of an octagon instead of a diamond
|
||||
}
|
||||
@@ -314,14 +319,14 @@ public class LightmapRenderer {
|
||||
nearby = 0; // exclude 'me' tile
|
||||
}
|
||||
|
||||
ambient = additiveBlend(ambient, nearby); // keep base value as brightest nearby
|
||||
ambient = maximiseRGB(ambient, nearby); // keep base value as brightest nearby
|
||||
}
|
||||
}
|
||||
|
||||
char opacity = TilePropCodex.getProp(thisTerrain).getOpacity();
|
||||
ambient = darkenColoured(ambient, opacity); // get real ambient by appling opacity value
|
||||
ambient = darkenColoured(ambient, thisTileOpacity); // get real ambient by appling opacity value
|
||||
|
||||
return screenBlend(lightLevelThis, ambient);
|
||||
// mix and return lightlevel and ambient
|
||||
return maximiseRGB(lightLevelThis, ambient);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Out of bounds of lightMap");
|
||||
@@ -329,6 +334,9 @@ public class LightmapRenderer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract each channel's RGB value.
|
||||
* It works like:
|
||||
* f(data, darken) = RGB(data.r - darken.r, data.g - darken.g, data.b - darken.b)
|
||||
*
|
||||
* @param data Raw channel value [0-39] per channel
|
||||
* @param darken [0-39] per channel
|
||||
@@ -347,6 +355,8 @@ public class LightmapRenderer {
|
||||
|
||||
/**
|
||||
* Darken each channel by 'darken' argument
|
||||
* It works like:
|
||||
* f(data, darken) = RGB(data.r - darken, data.g - darken, data.b - darken)
|
||||
* @param data [0-39] per channel
|
||||
* @param darken [0-1]
|
||||
* @return
|
||||
@@ -364,6 +374,8 @@ public class LightmapRenderer {
|
||||
|
||||
/**
|
||||
* Darken each channel by 'darken' argument
|
||||
* It works like:
|
||||
* f(data, darken) = RGB(data.r - darken, data.g - darken, data.b - darken)
|
||||
* @param data [0-39] per channel
|
||||
* @param darken [0-39]
|
||||
* @return
|
||||
@@ -381,7 +393,9 @@ public class LightmapRenderer {
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Add each channel's RGB value.
|
||||
* It works like:
|
||||
* f(data, brighten) = RGB(data.r + darken.r, data.g + darken.g, data.b + darken.b)
|
||||
* @param data Raw channel value [0-39] per channel
|
||||
* @param brighten [0-39] per channel
|
||||
* @return brightened data [0-39] per channel
|
||||
@@ -397,13 +411,12 @@ public class LightmapRenderer {
|
||||
return constructRGBFromFloat(r, g, b);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
/** Get each channel from two RGB values, return new RGB that has max value of each channel
|
||||
* @param rgb
|
||||
* @param rgb2
|
||||
* @return
|
||||
*/
|
||||
private static char additiveBlend(char rgb, char rgb2) {
|
||||
private static char maximiseRGB(char rgb, char rgb2) {
|
||||
int r1 = getRawR(rgb); int r2 = getRawR(rgb2); int newR = (r1 > r2) ? r1 : r2;
|
||||
int g1 = getRawG(rgb); int g2 = getRawG(rgb2); int newG = (g1 > g2) ? g1 : g2;
|
||||
int b1 = getRawB(rgb); int b2 = getRawB(rgb2); int newB = (b1 > b2) ? b1 : b2;
|
||||
@@ -505,12 +518,12 @@ public class LightmapRenderer {
|
||||
return (x << 4);
|
||||
}
|
||||
|
||||
private static char max(char... i) {
|
||||
private static int max(int... i) {
|
||||
Arrays.sort(i);
|
||||
return i[i.length - 1];
|
||||
}
|
||||
|
||||
private static char min(char... i) {
|
||||
private static int min(int... i) {
|
||||
Arrays.sort(i);
|
||||
return i[0];
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.Torvald.Terrarum.MapGenerator;
|
||||
|
||||
import com.Torvald.Rand.HQRNG;
|
||||
import com.Torvald.Terrarum.GameMap.GameMap;
|
||||
import com.Torvald.Terrarum.GameMap.MapLayer;
|
||||
import com.Torvald.Terrarum.TileProperties.TileNameCode;
|
||||
import com.jme3.math.FastMath;
|
||||
import com.sun.istack.internal.NotNull;
|
||||
@@ -34,6 +35,10 @@ public class MapGenerator {
|
||||
private static int SHORE_WIDTH = 120;
|
||||
private static int MAX_OCEAN_DEPTH = 200;
|
||||
|
||||
private static final int TERRAIN_PERTURB_OFFSETMAX = 32; // [-val , val]
|
||||
private static final int TERRAIN_PERTURB_LARGESTFEATURE = 256;
|
||||
private static final float TERRAIN_PERTURB_RATE = 0.5f;
|
||||
|
||||
private static int GLACIER_MOUNTAIN_WIDTH = 900;
|
||||
private static final int GLACIER_MOUNTAIN_HEIGHT = 300;
|
||||
|
||||
@@ -89,8 +94,10 @@ public class MapGenerator {
|
||||
placeGlacierMount(heightMap);
|
||||
heightMapToObjectMap(heightMap);
|
||||
|
||||
perturbTerrain();
|
||||
|
||||
carveCave(
|
||||
caveGen(1, 1.2f)
|
||||
caveGen(1.4f, 1.7f)
|
||||
, TileNameCode.AIR
|
||||
, "Carving out cave..."
|
||||
);
|
||||
@@ -518,6 +525,70 @@ public class MapGenerator {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void perturbTerrain() {
|
||||
SimplexNoise perturbGen = new SimplexNoise(TERRAIN_PERTURB_LARGESTFEATURE
|
||||
, TERRAIN_PERTURB_RATE, seed ^ random.nextLong());
|
||||
|
||||
float[][] perturbMap = new float[height][width];
|
||||
|
||||
byte[][] layerWall = map.getWallArray();
|
||||
byte[][] layerTerrain = map.getTerrainArray();
|
||||
MapLayer newLayerWall = new MapLayer(width, height);
|
||||
MapLayer newLayerTerrain = new MapLayer(width, height);
|
||||
|
||||
float lowestNoiseVal = 10000f;
|
||||
float highestNoiseVal = -10000f;
|
||||
|
||||
for (int y = 0; y < map.height; y++) {
|
||||
for (int x = 0; x < map.width; x++) {
|
||||
float noise = perturbGen.getNoise(x, y); // [-1, 1]
|
||||
perturbMap[y][x] = noise;
|
||||
if (noise < lowestNoiseVal) lowestNoiseVal = noise;
|
||||
if (noise > highestNoiseVal) highestNoiseVal = noise;
|
||||
}
|
||||
}
|
||||
|
||||
// Auto-scale noise [-1, 1]
|
||||
/**
|
||||
* See ./work_files/Linear_autoscale.gcx
|
||||
*/
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
float noiseInit = perturbMap[y][x];
|
||||
float noiseFin = (noiseInit - ((highestNoiseVal + lowestNoiseVal) / 2f))
|
||||
* (2f / (highestNoiseVal - lowestNoiseVal));
|
||||
|
||||
perturbMap[y][x] = noiseFin;
|
||||
}
|
||||
}
|
||||
|
||||
// Perturb to x-axis, apply to newLayer
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
float offsetOrigin = perturbMap[y][x] * 0.5f + 0.5f; // [0 , 1]
|
||||
int offset = Math.round(offsetOrigin * TERRAIN_PERTURB_OFFSETMAX);
|
||||
|
||||
byte tileWall = layerWall[y][x];
|
||||
byte tileTerrain = layerTerrain[y][x];
|
||||
|
||||
try {
|
||||
//newLayerWall.setTile(x + offset, y, tileWall);
|
||||
//newLayerTerrain.setTile(x + offset, y, tileTerrain);
|
||||
//layerWall[y][x] = 0;
|
||||
//layerTerrain[y][x] = 0;
|
||||
layerWall[y - offset][x] = tileWall;
|
||||
layerTerrain[y - offset][x] = tileTerrain;
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set reference (pointer) of original map layer to new layers
|
||||
//map.overwriteLayerWall(newLayerWall);
|
||||
//map.overwriteLayerTerrain(newLayerTerrain);
|
||||
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
BIN
work_files/LInear_autoscale.gcx
Normal file
BIN
work_files/LInear_autoscale.gcx
Normal file
Binary file not shown.
30
work_files/Tools/b24_col_to_40step_col.py
Normal file
30
work_files/Tools/b24_col_to_40step_col.py
Normal file
@@ -0,0 +1,30 @@
|
||||
MUL = 40
|
||||
MUL_2 = MUL ** 2
|
||||
MAX_STEP = MUL - 1
|
||||
|
||||
def getch(eightbit):
|
||||
return int(round(eightbit / 255.0 * MAX_STEP))
|
||||
|
||||
|
||||
def getR(rgb24):
|
||||
return (rgb24 >> 16) & 0xFF
|
||||
def getG(rgb24):
|
||||
return (rgb24 >> 8) & 0xFF
|
||||
def getB(rgb24):
|
||||
return rgb24 & 0xFF
|
||||
|
||||
|
||||
def getR40(raw):
|
||||
return raw / MUL_2
|
||||
def getG40(raw):
|
||||
return (raw % MUL_2) / MUL
|
||||
def getB40(raw):
|
||||
return raw % MUL
|
||||
|
||||
|
||||
def intFromCol(r, g, b):
|
||||
return r * MUL_2 + g * MUL + b
|
||||
def colFromNum(raw):
|
||||
return getR40(raw), getG40(raw), getB40(raw)
|
||||
|
||||
print(intFromCol(19,39,0))
|
||||
21
work_files/Tools/img_12bit_raw.py
Normal file
21
work_files/Tools/img_12bit_raw.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# usage: pypy scriptname inputfile outputfile
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
def bandlimit(i):
|
||||
key = (i & 0xF0) >> 4
|
||||
return (key << 4) | key
|
||||
|
||||
|
||||
outcontents = []
|
||||
|
||||
infile = open(sys.argv[1], "rb").read()
|
||||
|
||||
for i in infile:
|
||||
#print(ord(i))
|
||||
outcontents.append(bandlimit(ord(i)))
|
||||
|
||||
outfile = open(sys.argv[2], "wb")
|
||||
outfile.write(bytearray(outcontents))
|
||||
outfile.close()
|
||||
Reference in New Issue
Block a user