Лисья Нора

§ Программный код

undertale.gif
Программа может загружать INES файл и редактировать его, но сохраняет в BIN-формат.
Команды управления редактором:
При активном окне выбора тайла нажатие на 0-3 выбирает цвет в текущей палитре, надо ввести номер цвета от 0 до 255. При активном окне редактора тайлов выбирает цвет, которым будет происходить рисование и тут же рисует этим цветом. Нажимая на пробел, рисуется последним использованным цветом.
SCREEN 13
 
DIM SHARED T AS STRING * 4096
DIM SHARED PLT(0 TO 15) AS INTEGER
DIM SHARED cpal AS INTEGER
DIM SHARED cp AS INTEGER
DIM SHARED mv AS INTEGER
DIM SHARED EMode AS INTEGER
DIM SHARED LFile AS STRING
 
FOR i = 0 TO 15
IF i AND 3 THEN PLT(i) = i
NEXT
 
TitleName
Controls
 
cp = 0: mv = 0
xs = 0: ys = 0
xp = 0: yp = 0
 
DO
 
SelectBox xs, ys, xp, yp
 
DO: i$ = INKEY$: LOOP WHILE i$ = ""
 
' Clear OLD
id = xs + ys * 16
DrawSP id, 0
 
' Controls
IF EMode THEN
 
IF i$ = CHR$(0) + "H" THEN yp = yp - 1
IF i$ = CHR$(0) + "P" THEN yp = yp + 1
IF i$ = CHR$(0) + "K" THEN xp = xp - 1
IF i$ = CHR$(0) + "M" THEN xp = xp + 1
IF xp < 0 THEN xp = 7
IF yp < 0 THEN yp = 7
IF xp > 7 THEN xp = 0
IF yp > 7 THEN yp = 0
 
IF i$ >= "0" AND i$ <= "3" THEN lcl = VAL(i$): SetPix xs, ys, xp, yp, lcl
IF i$ = " " THEN SetPix xs, ys, xp, yp, lcl
 
ELSE
 
IF i$ = CHR$(0) + "H" THEN ys = ys - 1
IF i$ = CHR$(0) + "P" THEN ys = ys + 1
IF i$ = CHR$(0) + "K" THEN xs = xs - 1
IF i$ = CHR$(0) + "M" THEN xs = xs + 1
IF xs < 0 THEN xs = 15
IF ys < 0 THEN ys = 15
IF xs > 15 THEN xs = 0
IF ys > 15 THEN ys = 0
IF i$ >= "0" AND i$ <= "3" THEN COLOR 15: PLT(cpal * 4 + VAL(i$)) = VAL(Inp$("ColorID")): Refresh
 
END IF
 
IF i$ = CHR$(0) + "<" THEN LoadData: EMode = 0: Refresh
IF i$ = CHR$(0) + "=" THEN SaveData
IF i$ = CHR$(0) + ">" THEN cpal = (cpal + 1) AND 3: Refresh
IF i$ = CHR$(9) THEN EMode = 1 - EMode: Controls
 
' COPY
IF i$ = CHR$(0) + "?" THEN
cp = 1 - cp: IF cp THEN cpsrc = id ELSE DoCopy cpsrc, id
Controls
END IF
 
' SWAP
IF i$ = CHR$(0) + "@" THEN
mv = 1 - mv: IF mv THEN cpsrc = id ELSE DoMove cpsrc, id
Controls
END IF
 
' LOCATE 1, 1: PRINT i$
 
LOOP WHILE i$ <> CHR$(27)
 
' Show controls button
SUB Controls
 
LOCATE 25, 1
 
mc = 15: IF EMode THEN mc = 12
COLOR 11: PRINT "F1"; : COLOR mc: PRINT "ED ";
COLOR 11: PRINT "F2"; : COLOR 15: PRINT "LD ";
COLOR 11: PRINT "F3"; : COLOR 15: PRINT "SV ";
COLOR 11: PRINT "F4"; : COLOR 15: PRINT "PL ";
mc = 15: IF cp THEN mc = 12
COLOR 11: PRINT "F5"; : COLOR mc: PRINT "CP ";
mc = 15: IF mv THEN mc = 12
COLOR 11: PRINT "F6"; : COLOR mc: PRINT "MV ";
COLOR 11: PRINT "03"; : COLOR 15: PRINT "CL ";
 
FOR i = 0 TO 15
 
x1 = i * 16
y1 = 140
x2 = x1 + 14
y2 = y1 + 14
 
LINE (x1, y1)-(x2, y2), 15, B
LINE (x1 + 1, y1 + 1)-(x2 - 1, y2 - 1), PLT(i), BF
 
NEXT
 
FOR i = 0 TO 3
 
x1 = i * 64
LINE (x1, 160)-(x1 + 62, 160), 7
LINE (x1, 160)-(x1, 156), 8
LINE (x1 + 62, 160)-(x1 + 62, 156), 8
 
IF cpal = i THEN COLOR 15 ELSE COLOR 8
LOCATE 21, 4 + i * 8
PRINT i;
 
NEXT
 
' Tiles Box
LINE (0, 8)-(129, 137), 7, B
LINE (131, 8)-(197, 74), 7, B
 
END SUB
 
' Copy tile from src to dst ID
SUB DoCopy (src, dst)
 
k$ = MID$(T, 1 + src * 16, 16)
T = MID$(T, 1, dst * 16) + k$ + MID$(T, dst * 16 + 17, 4095 - dst * 16)
 
END SUB
 
' Swap tiles
SUB DoMove (src, dst)
 
a$ = MID$(T, 1 + src * 16, 16)
B$ = MID$(T, 1 + dst * 16, 16)
 
T = MID$(T, 1, dst * 16) + a$ + MID$(T, dst * 16 + 17, 4096)
T = MID$(T, 1, src * 16) + B$ + MID$(T, src * 16 + 17, 4096)
 
DrawSP src, 0
 
END SUB
 
' Drawing ID sprite, if sel > 0 then also draw right box
SUB DrawSP (id, sel)
 
x = id AND 15
y = id \ 16
s = x + y * 16
 
FOR i = 0 TO 7
 
m0 = 1 + id * 16 + i
b0 = ASC(MID$(T, m0, 1))
b1 = ASC(MID$(T, m0 + 8, 1))
 
' Clear right lines
IF EMode THEN
 
LINE (132, 9 + i * 8)-(196, 9 + i * 8), 0
LINE (132 + 8 * i, 9)-(132 + 8 * i, 73), 0
 
END IF
 
' Down and right line clear
LINE (132, 9 + 64)-(196, 9 + 64), 0
LINE (132 + 64, 9)-(132 + 64, 9 + 64), 0
 
FOR j = 0 TO 7
 
c = (b0 AND 1) + 2 * (b1 AND 1) + cpal * 4
PSET (8 + x * 8 - j, 9 + y * 8 + i), PLT(c)
 
b0 = b0 \ 2
b1 = b1 \ 2
 
IF sel > 0 THEN
 
xa = 132 + (7 - j) * 8
ya = 9 + i * 8
LINE (xa + 1, ya + 1)-(xa + 7, ya + 7), PLT(c), BF
 
END IF
 
NEXT
 
NEXT
 
END SUB
 
' Input data from keyboard
FUNCTION Inp$ (msg$)
 
LOCATE 23, 2: PRINT msg$; : INPUT ix$
LOCATE 23, 2: PRINT " ";
Inp$ = ix$
 
END FUNCTION
 
' Load sprites (nes/bin)
SUB LoadData
 
DIM DT AS STRING * 16
 
COLOR 14
File$ = Inp$("Load File")
IF File$ <> "" THEN
 
Ext$ = MID$(File$, LEN(File$) - 2, 3)
OPEN File$ FOR BINARY AS #1
 
IF Ext$ = "nes" THEN
 
PGE = VAL(Inp$("Page"))
GET #1, 5, DT
prg = ASC(MID$(DT, 1, 1))
ofs = 16 + prg * 16384
IF prg THEN GET #1, ofs + 1 + PGE * 4096, T
 
ELSE
 
GET #1, 1, T
GET #1, 4096, DT
FOR i = 0 TO 15
x = ASC(MID$(DT, 1 + i, 1))
PLT(i) = x
NEXT
 
LFile = File$
 
END IF
 
CLOSE #1
 
END IF
 
END SUB
 
' Update all
SUB Refresh
 
Controls
FOR i = 0 TO 255: DrawSP i, 0: NEXT
 
END SUB
 
' Save to bin file
SUB SaveData
 
COLOR 14
IF LFile <> "" THEN File$ = LFile ELSE File$ = Inp$("Save File")
OPEN File$ FOR BINARY AS #1
PUT #1, 1, T
FOR i = 0 TO 15
M$ = CHR$(PLT(i))
PUT #1, 4096 + i, M$
NEXT
CLOSE #1
LFile = File$
 
END SUB
 
' Show current sprite
SUB SelectBox (x, y, xp, yp)
 
xs = 1 + x * 8
ys = 9 + y * 8
 
DrawSP x + y * 16, 1
 
IF EMode = 0 THEN
 
FOR j = 0 TO 7 STEP 2
 
PSET (xs + j, ys), 7
PSET (xs + j + 1, ys + 7), 7
PSET (xs, ys + j), 7
PSET (xs + 7, ys + j + 1), 7
 
NEXT
 
ELSE
 
xs = 132 + xp * 8
ys = 9 + yp * 8
LINE (xs, ys)-(xs + 8, ys + 8), 15, B
 
END IF
 
hx$ = "0123456789ABCDEF"
LOCATE 12, 18: COLOR 14: PRINT "ID:"; MID$(hx$, y + 1, 1); MID$(hx$, x + 1, 1);
 
END SUB
 
' Update files in tile
SUB SetPix (xs, ys, xp, yp, cl)
 
m1 = 2 ^ (7 - xp)
m0 = 1 + yp + ys * 256 + xs * 16
 
b0 = ASC(MID$(T, m0, 1))
b1 = ASC(MID$(T, m0 + 8, 1))
 
k1 = cl AND 1
k2 = (cl \ 2) AND 1
 
b0 = b0 AND (255 - m1)
b1 = b1 AND (255 - m1)
 
IF k1 THEN b0 = b0 + m1
IF k2 THEN b1 = b1 + m1
 
T = MID$(T, 1, m0 - 1) + CHR$(b0) + MID$(T, m0 + 1, 4096 - m0)
T = MID$(T, 1, m0 + 7) + CHR$(b1) + MID$(T, m0 + 9, 4096 - m0 - 8)
 
END SUB
 
' Show tite
SUB TitleName
 
LOCATE 1, 22
COLOR 16
PRINT "TILES EDITOR 1"
 
FOR y = 0 TO 7
FOR x = 0 TO 129
 
c = POINT(x + 160, y - 1)
IF c > 0 THEN c = 0 ELSE c = 31 - y
PSET (x, y), c
 
NEXT
NEXT
 
FOR y = 0 TO 7: LINE (130, y)-(320, y), 31 - y: NEXT
 
END SUB