mirror of
https://gitlab.com/octospacc/MultiSpaccSDK
synced 2025-03-01 10:17:53 +01:00
Update scripts and NES compatibility, add PNG to NES CHR convert
This commit is contained in:
parent
9be90d7629
commit
fa7bc447fc
@ -51,12 +51,8 @@ else ifeq ($(MultiSpacc_Target), NES)
|
||||
endif
|
||||
|
||||
CC = $(ToolsPrefix)gcc $(CFlags) $(Defines)
|
||||
Shell = $(shell echo $$SHELL)
|
||||
AppObjects = $(AppSources:.c=.o)
|
||||
SpaccObjects = $(SpaccSources:.c=.o)
|
||||
BuildObjects = $(AppObjects) $(SpaccObjects)
|
||||
#BuildSources = $(AppSources) $(SpaccSources)
|
||||
#Objects = $(BuildSources:.c=.o)
|
||||
BuildSources = $(AppSources) $(SpaccSources)
|
||||
BuildObjects = $(BuildSources:.c=.o)
|
||||
|
||||
All all: $(BuildProcess)
|
||||
|
||||
@ -73,9 +69,9 @@ __NDS__:
|
||||
cp $(SpaccSources) $(SpaccHeaders) $(VirtualBuildDir)/source/.tmp/
|
||||
cd $(VirtualBuildDir)/source/.tmp; for i in *; do mv ./$$i ../LibMultiSpacc_$$i; done
|
||||
cp $(AppSources) $(AppHeaders) $(VirtualBuildDir)/source/
|
||||
for i in $(VirtualBuildDir)/source/*; do sed -i 's|#include[ \t]"../../LibMultiSpacc/|#include "LibMultiSpacc_|g' $$i; done
|
||||
for i in $(VirtualBuildDir)/source/*; do sed -i 's|#include[ \t]"../MultiSpacc|#include "LibMultiSpacc_MultiSpacc|g' $$i; done
|
||||
for i in $(VirtualBuildDir)/source/*; do sed -i 's|#include[ \t]"./|#include "./LibMultiSpacc_|g' $$i; done
|
||||
for i in $(VirtualBuildDir)/source/*.c $(VirtualBuildDir)/source/*.h; do sed -i 's|#include[ \t]"../../LibMultiSpacc/|#include "LibMultiSpacc_|g' $$i; done
|
||||
for i in $(VirtualBuildDir)/source/*.c $(VirtualBuildDir)/source/*.h; do sed -i 's|#include[ \t]"../MultiSpacc|#include "LibMultiSpacc_MultiSpacc|g' $$i; done
|
||||
for i in $(VirtualBuildDir)/source/*.c $(VirtualBuildDir)/source/*.h; do sed -i 's|#include[ \t]"./|#include "LibMultiSpacc_|g' $$i; done
|
||||
cd $(VirtualBuildDir); make
|
||||
|
||||
__NES__:
|
||||
@ -85,13 +81,14 @@ __NES__:
|
||||
cp $(SpaccSources) $(SpaccHeaders) $(VirtualBuildDir)/.tmp/
|
||||
cd $(VirtualBuildDir)/.tmp; for i in *; do mv ./$$i ../LibMultiSpacc_$$i; done
|
||||
cp $(AppSources) $(AppHeaders) $(VirtualBuildDir)/
|
||||
for i in $(VirtualBuildDir)/*; do sed -i 's|#include[ \t]"../../LibMultiSpacc/|#include "LibMultiSpacc_|g' $$i; done
|
||||
for i in $(VirtualBuildDir)/*; do sed -i 's|#include[ \t]"../MultiSpacc|#include "LibMultiSpacc_MultiSpacc|g' $$i; done
|
||||
for i in $(VirtualBuildDir)/*; do sed -i 's|#include[ \t]"./|#include "./LibMultiSpacc_|g' $$i; done
|
||||
cp ../../neslib/*.cfg ../../neslib/crt0.o ../../neslib/chr_generic.o ../../neslib/*.lib ../../neslib/*.h $(VirtualBuildDir)/
|
||||
echo "AppName='$(AppName)'; Defines='$(Defines)'; AppSources='$(AppSources)'; SpaccSources='$(SpaccSources)'; AppObjects='$(AppObjects)'; BuildObjects='$(BuildObjects)';" > $(VirtualBuildDir)/Make.sh
|
||||
for i in $(VirtualBuildDir)/*.c $(VirtualBuildDir)/*.h; do sed -i 's|#include[ \t]"../../LibMultiSpacc/|#include "LibMultiSpacc_|g' $$i; done
|
||||
for i in $(VirtualBuildDir)/*.c $(VirtualBuildDir)/*.h; do sed -i 's|#include[ \t]"../MultiSpacc|#include "LibMultiSpacc_MultiSpacc|g' $$i; done
|
||||
for i in $(VirtualBuildDir)/*.c $(VirtualBuildDir)/*.h; do sed -i 's|#include[ \t]"./|#include "LibMultiSpacc_|g' $$i; done
|
||||
cp ../../neslib/*.cfg ../../neslib/crt0.o ../../neslib/*.lib ../../neslib/*.h $(VirtualBuildDir)/
|
||||
printf ".segment \"CHARS\"\n\t.incbin \"CHARS.chr\"" > $(VirtualBuildDir)/CHARS.s
|
||||
echo "AppName='$(AppName)'; Defines='$(Defines)'; ProjectRoot=../..;" > $(VirtualBuildDir)/Make.sh
|
||||
cat ../NES.mk.sh >> $(VirtualBuildDir)/Make.sh
|
||||
cd $(VirtualBuildDir); $(Shell) ./Make.sh
|
||||
cd $(VirtualBuildDir); sh ./Make.sh
|
||||
|
||||
Run run: All
|
||||
./$(AppName)$(ExeSuffix)
|
||||
|
BIN
LibMultiSpacc/Examples/HelloWorld/CHARS.png
Normal file
BIN
LibMultiSpacc/Examples/HelloWorld/CHARS.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 773 B |
@ -27,7 +27,7 @@ int main( int argc, char *argv[] )
|
||||
MultiSpacc_Surface *Screen;
|
||||
MultiSpacc_Surface *TilesImg;
|
||||
|
||||
WindowConfig.Width = 256;
|
||||
WindowConfig.Width = 320;
|
||||
WindowConfig.Height = 240;
|
||||
WindowConfig.Bits = 16;
|
||||
memcpy( WindowConfig.Palette, PALETTE, 32 );
|
||||
@ -45,13 +45,13 @@ int main( int argc, char *argv[] )
|
||||
|
||||
// Bitmap font borrowed from: <https://github.com/nesdoug/01_Hello/blob/master/Alpha.chr>
|
||||
// Copyright (c) 2018 Doug Fraker www.nesdoug.com (MIT)
|
||||
//TilesImg = MultiSpacc_LoadImage( "Tiles.png", Screen, NULL );
|
||||
TilesImg = MultiSpacc_LoadImage( "CHARS.png", Screen, NULL );
|
||||
MultiSpacc_PrintText( "Hello, World!", Screen, &WindowConfig, 2, 2, TilesImg );
|
||||
MultiSpacc_PrintDebug("[I] Ready!\n");
|
||||
|
||||
while(true)
|
||||
{
|
||||
MultiSpacc_Sprite( 0, spriteX, spriteY, 20/*128*/, TilesImg, Screen );
|
||||
MultiSpacc_Sprite( 0, spriteX, spriteY, 1, TilesImg, Screen );
|
||||
//scroll(spriteX,0);
|
||||
|
||||
spriteX += accelX;
|
||||
@ -74,7 +74,7 @@ int main( int argc, char *argv[] )
|
||||
};
|
||||
|
||||
// TODO: Implement cross-platform vblank-wait
|
||||
//MultiSpacc_Sleep(16);
|
||||
MultiSpacc_Sleep(16);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1 +1 @@
|
||||
include ../Common.mk
|
||||
include ../Common.mk
|
Binary file not shown.
Before Width: | Height: | Size: 664 B |
@ -1,7 +1,8 @@
|
||||
#!/dev/null
|
||||
set -e
|
||||
SdkRoot="${ProjectRoot}/../../.."
|
||||
|
||||
# ${SpaccSources} ${AppSources} ${SpaccObjects} ${AppObjects} chr_generic.s chr_generic.o crt0.o
|
||||
sh "${SdkRoot}/Tools/python3.sh" "${SdkRoot}/Tools/pilbmp2nes.py" -i "${ProjectRoot}/CHARS.png" -o ./CHARS.chr
|
||||
|
||||
for File in *.c
|
||||
do cc65 -Oirs --target nes ${File} ${Defines}
|
||||
|
@ -98,4 +98,11 @@ void MultiSpacc_Sprite( int id, int x, int y, int sprite, MultiSpacc_Surface *Ti
|
||||
ppu_wait_frame();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MultiSpacc_Sleep( int milliseconds ){}
|
||||
|
||||
MultiSpacc_Surface *MultiSpacc_LoadImage( char FilePath[], MultiSpacc_Surface *Screen, Uint32 *ColorKey )
|
||||
{
|
||||
return NULL;
|
||||
};
|
||||
#endif
|
||||
|
@ -64,6 +64,7 @@
|
||||
#define MultiSpacc_Surface int
|
||||
#define MultiSpacc_Event int
|
||||
int MultiSpacc_UpdateWindowSurface( MultiSpacc_Window *Window );
|
||||
void MultiSpacc_Sleep( int milliseconds );
|
||||
#endif
|
||||
|
||||
typedef struct MultiSpacc_SurfaceConfig {
|
||||
|
@ -22,6 +22,8 @@ MultiSpacc_Window *MultiSpacc_SetWindow( MultiSpacc_SurfaceConfig *WindowConfig
|
||||
#endif
|
||||
|
||||
#ifdef MultiSpacc_Target_NES
|
||||
WindowConfig->Width = 256;
|
||||
WindowConfig->Height = 240;
|
||||
oam_clear();
|
||||
pal_all(WindowConfig->Palette);
|
||||
ppu_on_all();
|
||||
|
5
LibMultiSpacc/neslib/.gitignore
vendored
5
LibMultiSpacc/neslib/.gitignore
vendored
@ -1,5 +0,0 @@
|
||||
*.o
|
||||
*.lst
|
||||
*~
|
||||
crt0.lst
|
||||
neslib2.lib
|
@ -300,8 +300,12 @@ void __fastcall__ nmi_set_callback(void (*callback)(void));
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#define NT_UPD_HORZ 0x40
|
||||
#define NT_UPD_VERT 0x80
|
||||
|
130
Tools/WindowsRefreshEnv.cmd
Normal file
130
Tools/WindowsRefreshEnv.cmd
Normal file
@ -0,0 +1,130 @@
|
||||
:: Code generously provided by @beatcracker: https://github.com/beatcracker/detect-batch-subshell
|
||||
@echo off
|
||||
|
||||
setlocal EnableDelayedExpansion
|
||||
|
||||
:: Dequote path to command processor and this script path
|
||||
set ScriptPath=%~0
|
||||
set CmdPath=%COMSPEC:"=%
|
||||
|
||||
:: Get command processor filename and filename with extension
|
||||
for %%c in (!CmdPath!) do (
|
||||
set CmdExeName=%%~nxc
|
||||
set CmdName=%%~nc
|
||||
)
|
||||
|
||||
:: Get this process' PID
|
||||
:: Adapted from: http://www.dostips.com/forum/viewtopic.php?p=22675#p22675
|
||||
set "uid="
|
||||
for /l %%i in (1 1 128) do (
|
||||
set /a "bit=!random!&1"
|
||||
set "uid=!uid!!bit!"
|
||||
)
|
||||
|
||||
for /f "tokens=2 delims==" %%i in (
|
||||
'wmic Process WHERE "Name='!CmdExeName!' AND CommandLine LIKE '%%!uid!%%'" GET ParentProcessID /value'
|
||||
) do (
|
||||
rem Get commandline of parent
|
||||
for /f "tokens=1,2,*" %%j in (
|
||||
'wmic Process WHERE "Handle='%%i'" GET CommandLine /value'
|
||||
) do (
|
||||
|
||||
rem Strip extra CR's from wmic output
|
||||
rem http://www.dostips.com/forum/viewtopic.php?t=4266
|
||||
for /f "delims=" %%x in ("%%l") do (
|
||||
rem Dequote path to batch file, if any (3rd argument)
|
||||
set ParentScriptPath=%%x
|
||||
set ParentScriptPath=!ParentScriptPath:"=!
|
||||
)
|
||||
|
||||
rem Get parent process path
|
||||
for /f "tokens=2 delims==" %%y in ("%%j") do (
|
||||
rem Dequote parent path
|
||||
set ParentPath=%%y
|
||||
set ParentPath=!ParentPath:"=!
|
||||
|
||||
rem Handle different invocations: C:\Windows\system32\cmd.exe , cmd.exe , cmd
|
||||
for %%p in (!CmdPath! !CmdExeName! !CmdName!) do (
|
||||
if !ParentPath!==%%p set IsCmdParent=1
|
||||
)
|
||||
|
||||
rem Check if we're running in cmd.exe with /c switch and this script path as argument
|
||||
if !IsCmdParent!==1 if %%k==/c if "!ParentScriptPath!"=="%ScriptPath%" set IsExternal=1
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
if !IsExternal!==1 (
|
||||
echo %~nx0 does not work when run from this process. If you're in PowerShell, please 'Import-Module $env:ChocolateyInstall\helpers\chocolateyProfile.psm1' and try again.
|
||||
exit 1
|
||||
)
|
||||
|
||||
endlocal
|
||||
:: End code from @beatcracker
|
||||
@echo off
|
||||
::
|
||||
:: RefreshEnv.cmd
|
||||
::
|
||||
:: Batch file to read environment variables from registry and
|
||||
:: set session variables to these values.
|
||||
::
|
||||
:: With this batch file, there should be no need to reload command
|
||||
:: environment every time you want environment changes to propagate
|
||||
|
||||
::echo "RefreshEnv.cmd only works from cmd.exe, please install the Chocolatey Profile to take advantage of refreshenv from PowerShell"
|
||||
echo | set /p dummy="Refreshing environment variables from registry for cmd.exe. Please wait..."
|
||||
|
||||
goto main
|
||||
|
||||
:: Set one environment variable from registry key
|
||||
:SetFromReg
|
||||
"%WinDir%\System32\Reg" QUERY "%~1" /v "%~2" > "%TEMP%\_envset.tmp" 2>NUL
|
||||
for /f "usebackq skip=2 tokens=2,*" %%A IN ("%TEMP%\_envset.tmp") do (
|
||||
echo/set "%~3=%%B"
|
||||
)
|
||||
goto :EOF
|
||||
|
||||
:: Get a list of environment variables from registry
|
||||
:GetRegEnv
|
||||
"%WinDir%\System32\Reg" QUERY "%~1" > "%TEMP%\_envget.tmp"
|
||||
for /f "usebackq skip=2" %%A IN ("%TEMP%\_envget.tmp") do (
|
||||
if /I not "%%~A"=="Path" (
|
||||
call :SetFromReg "%~1" "%%~A" "%%~A"
|
||||
)
|
||||
)
|
||||
goto :EOF
|
||||
|
||||
:main
|
||||
echo/@echo off >"%TEMP%\_env.cmd"
|
||||
|
||||
:: Slowly generating final file
|
||||
call :GetRegEnv "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" >> "%TEMP%\_env.cmd"
|
||||
call :GetRegEnv "HKCU\Environment">>"%TEMP%\_env.cmd" >> "%TEMP%\_env.cmd"
|
||||
|
||||
:: Special handling for PATH - mix both User and System
|
||||
call :SetFromReg "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" Path Path_HKLM >> "%TEMP%\_env.cmd"
|
||||
call :SetFromReg "HKCU\Environment" Path Path_HKCU >> "%TEMP%\_env.cmd"
|
||||
|
||||
:: Caution: do not insert space-chars before >> redirection sign
|
||||
echo/set "Path=%%Path_HKLM%%;%%Path_HKCU%%" >> "%TEMP%\_env.cmd"
|
||||
|
||||
:: Cleanup
|
||||
del /f /q "%TEMP%\_envset.tmp" 2>nul
|
||||
del /f /q "%TEMP%\_envget.tmp" 2>nul
|
||||
|
||||
:: capture user / architecture
|
||||
SET "OriginalUserName=%USERNAME%"
|
||||
SET "OriginalArchitecture=%PROCESSOR_ARCHITECTURE%"
|
||||
|
||||
:: Set these variables
|
||||
call "%TEMP%\_env.cmd"
|
||||
|
||||
:: Cleanup
|
||||
del /f /q "%TEMP%\_env.cmd" 2>nul
|
||||
|
||||
:: reset user / architecture
|
||||
SET "USERNAME=%OriginalUserName%"
|
||||
SET "PROCESSOR_ARCHITECTURE=%OriginalArchitecture%"
|
||||
|
||||
echo | set /p dummy="Finished."
|
||||
echo .
|
209
Tools/pilbmp2nes.py
Normal file
209
Tools/pilbmp2nes.py
Normal file
@ -0,0 +1,209 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Bitmap to multi-console CHR converter using Pillow, the
|
||||
# Python Imaging Library
|
||||
#
|
||||
# Copyright 2014-2015 Damian Yerrick
|
||||
# Copying and distribution of this file, with or without
|
||||
# modification, are permitted in any medium without royalty
|
||||
# provided the copyright notice and this notice are preserved.
|
||||
# This file is offered as-is, without any warranty.
|
||||
#
|
||||
from __future__ import with_statement, print_function, unicode_literals
|
||||
from PIL import Image
|
||||
from time import sleep
|
||||
|
||||
def formatTilePlanar(tile, planemap, hflip=False, little=False):
|
||||
"""Turn a tile into bitplanes.
|
||||
|
||||
Planemap opcodes:
|
||||
10 -- bit 1 then bit 0 of each tile
|
||||
0,1 -- planar interleaved by rows
|
||||
0;1 -- planar interlaved by planes
|
||||
0,1;2,3 -- SNES/PCE format
|
||||
|
||||
"""
|
||||
hflip = 7 if hflip else 0
|
||||
if (tile.size != (8, 8)):
|
||||
return None
|
||||
pixels = list(tile.getdata())
|
||||
pixelrows = [pixels[i:i + 8] for i in range(0, 64, 8)]
|
||||
if hflip:
|
||||
for row in pixelrows:
|
||||
row.reverse()
|
||||
out = bytearray()
|
||||
|
||||
planemap = [[[int(c) for c in row]
|
||||
for row in plane.split(',')]
|
||||
for plane in planemap.split(';')]
|
||||
# format: [tile-plane number][plane-within-row number][bit number]
|
||||
|
||||
# we have five (!) nested loops
|
||||
# outermost: separate planes
|
||||
# within separate planes: pixel rows
|
||||
# within pixel rows: row planes
|
||||
# within row planes: pixels
|
||||
# within pixels: bits
|
||||
for plane in planemap:
|
||||
for pxrow in pixelrows:
|
||||
for rowplane in plane:
|
||||
rowbits = 1
|
||||
thisrow = bytearray()
|
||||
for px in pxrow:
|
||||
for bitnum in rowplane:
|
||||
rowbits = (rowbits << 1) | ((px >> bitnum) & 1)
|
||||
if rowbits >= 0x100:
|
||||
thisrow.append(rowbits & 0xFF)
|
||||
rowbits = 1
|
||||
out.extend(thisrow[::-1] if little else thisrow)
|
||||
return bytes(out)
|
||||
|
||||
def pilbmp2chr(im, tileWidth=8, tileHeight=8,
|
||||
formatTile=lambda im: formatTilePlanar(im, "0;1")):
|
||||
"""Convert a bitmap image into a list of byte strings representing tiles."""
|
||||
im.load()
|
||||
(w, h) = im.size
|
||||
outdata = []
|
||||
for mt_y in range(0, h, tileHeight):
|
||||
for mt_x in range(0, w, tileWidth):
|
||||
metatile = im.crop((mt_x, mt_y,
|
||||
mt_x + tileWidth, mt_y + tileHeight))
|
||||
for tile_y in range(0, tileHeight, 8):
|
||||
for tile_x in range(0, tileWidth, 8):
|
||||
tile = metatile.crop((tile_x, tile_y,
|
||||
tile_x + 8, tile_y + 8))
|
||||
data = formatTile(tile)
|
||||
outdata.append(data)
|
||||
return outdata
|
||||
|
||||
def parse_argv(argv):
|
||||
from optparse import OptionParser
|
||||
parser = OptionParser(usage="usage: %prog [options] [-i] INFILE [-o] OUTFILE")
|
||||
parser.add_option("-i", "--image", dest="infilename",
|
||||
help="read image from INFILE", metavar="INFILE")
|
||||
parser.add_option("-o", "--output", dest="outfilename",
|
||||
help="write CHR data to OUTFILE", metavar="OUTFILE")
|
||||
parser.add_option("-W", "--tile-width", dest="tileWidth",
|
||||
help="set width of metatiles", metavar="HEIGHT",
|
||||
type="int", default=8)
|
||||
parser.add_option("--packbits", dest="packbits",
|
||||
help="use PackBits RLE compression",
|
||||
action="store_true", default=False)
|
||||
parser.add_option("-H", "--tile-height", dest="tileHeight",
|
||||
help="set height of metatiles", metavar="HEIGHT",
|
||||
type="int", default=8)
|
||||
parser.add_option("-1", dest="planes",
|
||||
help="set 1bpp mode (default: 2bpp NES)",
|
||||
action="store_const", const="0", default="0;1")
|
||||
parser.add_option("--planes", dest="planes",
|
||||
help="set the plane map (1bpp: 0) (NES: 0;1) (GB: 0,1) (SMS:0,1,2,3) (TG16/SNES: 0,1;2,3) (MD: 3210)")
|
||||
parser.add_option("--hflip", dest="hflip",
|
||||
help="horizontally flip all tiles (most significant pixel on right)",
|
||||
action="store_true", default=False)
|
||||
parser.add_option("--little", dest="little",
|
||||
help="reverse the bytes within each row-plane (needed for GBA and a few others)",
|
||||
action="store_true", default=False)
|
||||
parser.add_option("--add", dest="addamt",
|
||||
help="value to add to each pixel",
|
||||
type="int", default=0)
|
||||
parser.add_option("--add0", dest="addamt0",
|
||||
help="value to add to pixels of color 0 (if different)",
|
||||
type="int", default=None)
|
||||
(options, args) = parser.parse_args(argv[1:])
|
||||
|
||||
tileWidth = int(options.tileWidth)
|
||||
if tileWidth <= 0:
|
||||
raise ValueError("tile width '%d' must be positive" % tileWidth)
|
||||
|
||||
tileHeight = int(options.tileHeight)
|
||||
if tileHeight <= 0:
|
||||
raise ValueError("tile height '%d' must be positive" % tileHeight)
|
||||
|
||||
# Fill unfilled roles with positional arguments
|
||||
argsreader = iter(args)
|
||||
try:
|
||||
infilename = options.infilename
|
||||
if infilename is None:
|
||||
infilename = next(argsreader)
|
||||
except StopIteration:
|
||||
raise ValueError("not enough filenames")
|
||||
|
||||
outfilename = options.outfilename
|
||||
if outfilename is None:
|
||||
try:
|
||||
outfilename = next(argsreader)
|
||||
except StopIteration:
|
||||
outfilename = '-'
|
||||
if outfilename == '-':
|
||||
import sys
|
||||
if sys.stdout.isatty():
|
||||
raise ValueError("cannot write CHR to terminal")
|
||||
|
||||
addamt, addamt0 = options.addamt, options.addamt0
|
||||
if addamt0 is None: addamt0 = addamt
|
||||
|
||||
return (infilename, outfilename, tileWidth, tileHeight,
|
||||
options.packbits, options.planes, options.hflip, options.little,
|
||||
addamt, addamt0)
|
||||
|
||||
argvTestingMode = True
|
||||
|
||||
def make_stdout_binary():
|
||||
"""Ensure that sys.stdout is in binary mode, with no newline translation."""
|
||||
|
||||
# Recipe from
|
||||
# http://code.activestate.com/recipes/65443-sending-binary-data-to-stdout-under-windows/
|
||||
# via http://stackoverflow.com/a/2374507/2738262
|
||||
if sys.platform == "win32":
|
||||
import os, msvcrt
|
||||
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
|
||||
|
||||
def main(argv=None):
|
||||
import sys
|
||||
if argv is None:
|
||||
argv = sys.argv
|
||||
if (argvTestingMode and len(argv) < 2
|
||||
and sys.stdin.isatty() and sys.stdout.isatty()):
|
||||
argv.extend(input('args:').split())
|
||||
try:
|
||||
(infilename, outfilename, tileWidth, tileHeight,
|
||||
usePackBits, planes, hflip, little,
|
||||
addamt, addamt0) = parse_argv(argv)
|
||||
except Exception as e:
|
||||
sys.stderr.write("%s: %s\n" % (argv[0], str(e)))
|
||||
sys.exit(1)
|
||||
|
||||
im = Image.open(infilename)
|
||||
|
||||
# Subpalette shift
|
||||
if addamt or addamt0:
|
||||
px = bytearray(im.getdata())
|
||||
for i in range(len(px)):
|
||||
thispixel = px[i]
|
||||
px[i] = thispixel + (addamt if thispixel else addamt0)
|
||||
im.putdata(px)
|
||||
|
||||
outdata = pilbmp2chr(im, tileWidth, tileHeight,
|
||||
lambda im: formatTilePlanar(im, planes, hflip, little))
|
||||
outdata = b''.join(outdata)
|
||||
if usePackBits:
|
||||
from packbits import PackBits
|
||||
sz = len(outdata) % 0x10000
|
||||
outdata = PackBits(outdata).flush().tostring()
|
||||
outdata = b''.join([chr(sz >> 8), chr(sz & 0xFF), outdata])
|
||||
|
||||
# Write output file
|
||||
outfp = None
|
||||
try:
|
||||
if outfilename != '-':
|
||||
outfp = open(outfilename, 'wb')
|
||||
else:
|
||||
outfp = sys.stdout
|
||||
make_stdout_binary()
|
||||
outfp.write(outdata)
|
||||
finally:
|
||||
if outfp and outfilename != '-':
|
||||
outfp.close()
|
||||
|
||||
if __name__=='__main__':
|
||||
main()
|
5
Tools/python3.sh
Normal file
5
Tools/python3.sh
Normal file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
[ "$(shell uname --operating-system)" = "Msys" ] \
|
||||
&& cmd //c "$(cygpath --windows "$(dirname "$(realpath "$0")")/WindowsRefreshEnv.cmd") && python3 $@" \
|
||||
|| python3 $@ \
|
||||
;
|
Loading…
x
Reference in New Issue
Block a user