mirror of
https://github.com/Dadido3/noita-mapcap.git
synced 2024-11-18 17:17:31 +00:00
Several changes
- Don't change effects, as it's not needed anymore - Add capture library to be loaded by lua (go and PureBasic) - Modify pixel size, to nicely fit into FullHD - Move camera instead of player - Add capturing routine - Round position to fit into grid, and also render the world pixel perfect - Add util/helper functions
This commit is contained in:
parent
be48a75c25
commit
99ad91e67c
34
.gitignore
vendored
34
.gitignore
vendored
@ -1,7 +1,28 @@
|
|||||||
# File created using '.gitignore Generator' for Visual Studio Code: https://bit.ly/vscode-gig
|
# File created using '.gitignore Generator' for Visual Studio Code: https://bit.ly/vscode-gig
|
||||||
|
|
||||||
# Created by https://www.gitignore.io/api/visualstudiocode,windows,lua
|
# Created by https://www.gitignore.io/api/lua,visualstudiocode,windows,go
|
||||||
# Edit at https://www.gitignore.io/?templates=visualstudiocode,windows,lua
|
# Edit at https://www.gitignore.io/?templates=lua,visualstudiocode,windows,go
|
||||||
|
|
||||||
|
### Go ###
|
||||||
|
# Binaries for programs and plugins
|
||||||
|
*.exe
|
||||||
|
*.exe~
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Test binary, built with `go test -c`
|
||||||
|
*.test
|
||||||
|
|
||||||
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
|
*.out
|
||||||
|
|
||||||
|
# Dependency directories (remove the comment below to include it)
|
||||||
|
# vendor/
|
||||||
|
|
||||||
|
### Go Patch ###
|
||||||
|
/vendor/
|
||||||
|
/Godeps/
|
||||||
|
|
||||||
### Lua ###
|
### Lua ###
|
||||||
# Compiled Lua sources
|
# Compiled Lua sources
|
||||||
@ -32,14 +53,9 @@ luac.out
|
|||||||
*.exp
|
*.exp
|
||||||
|
|
||||||
# Shared objects (inc. Windows DLLs)
|
# Shared objects (inc. Windows DLLs)
|
||||||
*.dll
|
|
||||||
*.so
|
|
||||||
*.so.*
|
*.so.*
|
||||||
*.dylib
|
|
||||||
|
|
||||||
# Executables
|
# Executables
|
||||||
*.exe
|
|
||||||
*.out
|
|
||||||
*.app
|
*.app
|
||||||
*.i*86
|
*.i*86
|
||||||
*.x86_64
|
*.x86_64
|
||||||
@ -83,7 +99,9 @@ $RECYCLE.BIN/
|
|||||||
# Windows shortcuts
|
# Windows shortcuts
|
||||||
*.lnk
|
*.lnk
|
||||||
|
|
||||||
# End of https://www.gitignore.io/api/visualstudiocode,windows,lua
|
# End of https://www.gitignore.io/api/lua,visualstudiocode,windows,go
|
||||||
|
|
||||||
# Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option)
|
# Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option)
|
||||||
|
|
||||||
|
/libs/
|
||||||
|
output/
|
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@ -1,5 +1,7 @@
|
|||||||
{
|
{
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
"Vogel"
|
"Vogel",
|
||||||
|
"kbinani",
|
||||||
|
"noita"
|
||||||
]
|
]
|
||||||
}
|
}
|
95
bin/capture-b/Capture.pb
Normal file
95
bin/capture-b/Capture.pb
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
UsePNGImageEncoder()
|
||||||
|
|
||||||
|
Declare Worker(*Dummy)
|
||||||
|
|
||||||
|
Structure QueueElement
|
||||||
|
img.i
|
||||||
|
x.i
|
||||||
|
y.i
|
||||||
|
EndStructure
|
||||||
|
|
||||||
|
ProcedureDLL AttachProcess(Instance)
|
||||||
|
Global Semaphore = CreateSemaphore()
|
||||||
|
Global Mutex = CreateMutex()
|
||||||
|
Global NewList Queue.QueueElement()
|
||||||
|
|
||||||
|
For i = 1 To 4
|
||||||
|
CreateThread(@Worker(), #Null)
|
||||||
|
Next
|
||||||
|
EndProcedure
|
||||||
|
|
||||||
|
Procedure Worker(*Dummy)
|
||||||
|
Protected img, x, y
|
||||||
|
|
||||||
|
Repeat
|
||||||
|
WaitSemaphore(Semaphore)
|
||||||
|
|
||||||
|
LockMutex(Mutex)
|
||||||
|
FirstElement(Queue())
|
||||||
|
img = Queue()\img
|
||||||
|
x = Queue()\x
|
||||||
|
y = Queue()\y
|
||||||
|
DeleteElement(Queue())
|
||||||
|
UnlockMutex(Mutex)
|
||||||
|
|
||||||
|
SaveImage(img, "mods/noita-mapcap/output/" + x + "," + y + ".png", #PB_ImagePlugin_PNG)
|
||||||
|
FreeImage(img)
|
||||||
|
ForEver
|
||||||
|
EndProcedure
|
||||||
|
|
||||||
|
ProcedureDLL Capture(px.i, py.i)
|
||||||
|
; Get dimensions of main screen
|
||||||
|
|
||||||
|
ExamineDesktops()
|
||||||
|
|
||||||
|
x = DesktopX(0)
|
||||||
|
y = DesktopY(0)
|
||||||
|
w = DesktopWidth(0)
|
||||||
|
h = DesktopHeight(0)
|
||||||
|
|
||||||
|
imageID = CreateImage(#PB_Any, w, h)
|
||||||
|
If Not imageID
|
||||||
|
ProcedureReturn
|
||||||
|
EndIf
|
||||||
|
|
||||||
|
; Get DC of whole screen
|
||||||
|
screenDC = GetDC_(#Null)
|
||||||
|
|
||||||
|
hDC = StartDrawing(ImageOutput(imageID))
|
||||||
|
If Not hDC
|
||||||
|
ReleaseDC_(#Null, screenDC)
|
||||||
|
FreeImage(imageID)
|
||||||
|
ProcedureReturn
|
||||||
|
EndIf
|
||||||
|
BitBlt_(hDC, 0, 0, w, h, screenDC, x, y, #SRCCOPY)
|
||||||
|
StopDrawing()
|
||||||
|
|
||||||
|
ReleaseDC_(#Null, screenDC)
|
||||||
|
|
||||||
|
LockMutex(Mutex)
|
||||||
|
; Check if the queue has too many elements, if so, wait. (Simulate go's channels)
|
||||||
|
While ListSize(Queue()) > 0
|
||||||
|
UnlockMutex(Mutex)
|
||||||
|
Delay(10)
|
||||||
|
LockMutex(Mutex)
|
||||||
|
Wend
|
||||||
|
LastElement(Queue())
|
||||||
|
AddElement(Queue())
|
||||||
|
Queue()\img = imageID
|
||||||
|
Queue()\x = px
|
||||||
|
Queue()\y = py
|
||||||
|
UnlockMutex(Mutex)
|
||||||
|
|
||||||
|
SignalSemaphore(Semaphore)
|
||||||
|
|
||||||
|
EndProcedure
|
||||||
|
|
||||||
|
; IDE Options = PureBasic 5.71 LTS (Windows - x64)
|
||||||
|
; ExecutableFormat = Shared dll
|
||||||
|
; CursorPosition = 15
|
||||||
|
; Folding = -
|
||||||
|
; EnableThread
|
||||||
|
; EnableXP
|
||||||
|
; Executable = capture.dll
|
||||||
|
; DisableDebugger
|
||||||
|
; Compiler = PureBasic 5.71 LTS (Windows - x86)
|
7
bin/capture-b/README.md
Normal file
7
bin/capture-b/README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Capture
|
||||||
|
|
||||||
|
A dynamically linked library, that supplies a single function to take a screenshot and store it as PNG file.
|
||||||
|
|
||||||
|
## State
|
||||||
|
|
||||||
|
Works, not as fast as the go version, but ok.
|
7
bin/capture/README.md
Normal file
7
bin/capture/README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Capture
|
||||||
|
|
||||||
|
A dynamically linked library, that supplies a single function to take a screenshot and store it as PNG file.
|
||||||
|
|
||||||
|
## State
|
||||||
|
|
||||||
|
Works, but it seems the go runtime interferes with other stuff inside noita. Therefore it's unusable, because it causes crashes.
|
9
bin/capture/build.bat
Normal file
9
bin/capture/build.bat
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
rem Copyright (c) 2019 David Vogel
|
||||||
|
rem
|
||||||
|
rem This software is released under the MIT License.
|
||||||
|
rem https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
set GOARCH=386
|
||||||
|
set CGO_ENABLED=1
|
||||||
|
|
||||||
|
go build -o capture.dll -buildmode=c-shared
|
@ -4,3 +4,83 @@
|
|||||||
// https://opensource.org/licenses/MIT
|
// https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"image"
|
||||||
|
"image/png"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/kbinani/screenshot"
|
||||||
|
)
|
||||||
|
|
||||||
|
type encodeElement struct {
|
||||||
|
x, y int
|
||||||
|
img *image.RGBA
|
||||||
|
}
|
||||||
|
|
||||||
|
var encodeQueue = make(chan encodeElement)
|
||||||
|
|
||||||
|
var bounds = screenshot.GetDisplayBounds(0) // Only care about the main screen
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// Start encode workers
|
||||||
|
startWorkers()
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
/*flagX := flag.Int("x", 0, "x coordinate")
|
||||||
|
flagY := flag.Int("y", 0, "y coordinate")
|
||||||
|
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
Capture(*flagX, *flagY)
|
||||||
|
|
||||||
|
//startServer()*/
|
||||||
|
|
||||||
|
/*for i := 0; i < 5000; i++ {
|
||||||
|
Capture(i, 0)
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
func startWorkers() {
|
||||||
|
for i := 0; i < 8; i++ {
|
||||||
|
go func() {
|
||||||
|
encoder := png.Encoder{CompressionLevel: png.BestSpeed}
|
||||||
|
|
||||||
|
for elem := range encodeQueue {
|
||||||
|
fileName := fmt.Sprintf("mods/noita-mapcap/output/%d,%d.png", elem.x, elem.y)
|
||||||
|
//fileName := fmt.Sprintf("%d,%d.png", x, y)
|
||||||
|
file, err := os.Create(fileName)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
encoder.Encode(file, elem.img)
|
||||||
|
|
||||||
|
file.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Capture creates a snapshot of the whole main screen, and stores it inside the mod's output folder.
|
||||||
|
//export Capture
|
||||||
|
func Capture(x, y int) {
|
||||||
|
|
||||||
|
img, err := screenshot.CaptureRect(bounds)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
//return
|
||||||
|
}
|
||||||
|
|
||||||
|
//img := image.NewRGBA(image.Rect(0, 0, 1920, 1080))
|
||||||
|
|
||||||
|
encodeQueue <- encodeElement{
|
||||||
|
img: img,
|
||||||
|
x: x,
|
||||||
|
y: y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
78
bin/capture/capture.h
Normal file
78
bin/capture/capture.h
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/* Code generated by cmd/cgo; DO NOT EDIT. */
|
||||||
|
|
||||||
|
/* package github.com/Dadido3/noita-mapcap/bin/capture */
|
||||||
|
|
||||||
|
|
||||||
|
#line 1 "cgo-builtin-export-prolog"
|
||||||
|
|
||||||
|
#include <stddef.h> /* for ptrdiff_t below */
|
||||||
|
|
||||||
|
#ifndef GO_CGO_EXPORT_PROLOGUE_H
|
||||||
|
#define GO_CGO_EXPORT_PROLOGUE_H
|
||||||
|
|
||||||
|
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
||||||
|
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Start of preamble from import "C" comments. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* End of preamble from import "C" comments. */
|
||||||
|
|
||||||
|
|
||||||
|
/* Start of boilerplate cgo prologue. */
|
||||||
|
#line 1 "cgo-gcc-export-header-prolog"
|
||||||
|
|
||||||
|
#ifndef GO_CGO_PROLOGUE_H
|
||||||
|
#define GO_CGO_PROLOGUE_H
|
||||||
|
|
||||||
|
typedef signed char GoInt8;
|
||||||
|
typedef unsigned char GoUint8;
|
||||||
|
typedef short GoInt16;
|
||||||
|
typedef unsigned short GoUint16;
|
||||||
|
typedef int GoInt32;
|
||||||
|
typedef unsigned int GoUint32;
|
||||||
|
typedef long long GoInt64;
|
||||||
|
typedef unsigned long long GoUint64;
|
||||||
|
typedef GoInt32 GoInt;
|
||||||
|
typedef GoUint32 GoUint;
|
||||||
|
typedef __SIZE_TYPE__ GoUintptr;
|
||||||
|
typedef float GoFloat32;
|
||||||
|
typedef double GoFloat64;
|
||||||
|
typedef float _Complex GoComplex64;
|
||||||
|
typedef double _Complex GoComplex128;
|
||||||
|
|
||||||
|
/*
|
||||||
|
static assertion to make sure the file is being used on architecture
|
||||||
|
at least with matching size of GoInt.
|
||||||
|
*/
|
||||||
|
typedef char _check_for_32_bit_pointer_matching_GoInt[sizeof(void*)==32/8 ? 1:-1];
|
||||||
|
|
||||||
|
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
||||||
|
typedef _GoString_ GoString;
|
||||||
|
#endif
|
||||||
|
typedef void *GoMap;
|
||||||
|
typedef void *GoChan;
|
||||||
|
typedef struct { void *t; void *v; } GoInterface;
|
||||||
|
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* End of boilerplate cgo prologue. */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//Capture creates a snapshot of the whole main screen, and stores it inside the mod's output folder.
|
||||||
|
|
||||||
|
extern void Capture(GoInt p0, GoInt p1);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
81
bin/capture/server.go.disabled
Normal file
81
bin/capture/server.go.disabled
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
// Copyright (c) 2019 David Vogel
|
||||||
|
//
|
||||||
|
// This software is released under the MIT License.
|
||||||
|
// https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func startServer() {
|
||||||
|
log.Printf("Launching server...\n")
|
||||||
|
|
||||||
|
// listen on all interfaces
|
||||||
|
ln, err := net.Listen("tcp", ":46789")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Couldn't open TCP server at port 46789: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// accept connections
|
||||||
|
for {
|
||||||
|
conn, err := ln.Accept()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Couldn't accept TCP connection: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle incoming data
|
||||||
|
go func(conn net.Conn) {
|
||||||
|
defer conn.Close()
|
||||||
|
var x, y int
|
||||||
|
|
||||||
|
for {
|
||||||
|
message, err := bufio.NewReader(conn).ReadString('\n')
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Couldn't read from connection: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for end condition
|
||||||
|
if message == "\n" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
colonPos := strings.IndexByte(message, ':') // Expect UTF-8
|
||||||
|
if colonPos < 0 {
|
||||||
|
log.Printf("Missing colon in message: %v", message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
key, value := message[:colonPos], message[colonPos+1:]
|
||||||
|
log.Printf("Bla %v blub %v", key, value)
|
||||||
|
switch key { // Expect UTF-8
|
||||||
|
case "x":
|
||||||
|
if res, err := strconv.ParseInt(value, 10, 0); err == nil {
|
||||||
|
x = int(res)
|
||||||
|
} else {
|
||||||
|
log.Printf("Can't parse string %v to integer: %v", value, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
case "y":
|
||||||
|
if res, err := strconv.ParseInt(value, 10, 0); err == nil {
|
||||||
|
y = int(res)
|
||||||
|
} else {
|
||||||
|
log.Printf("Can't parse string %v to integer: %v", value, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.Write([]byte("\n"))
|
||||||
|
|
||||||
|
log.Printf("capture bla at %v, %v", x, y)
|
||||||
|
|
||||||
|
}(conn)
|
||||||
|
}
|
||||||
|
}
|
17
data/entities/misc/fogofwar_radius.xml.disabled
Normal file
17
data/entities/misc/fogofwar_radius.xml.disabled
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<Entity >
|
||||||
|
|
||||||
|
<FogOfWarRadiusComponent _enabled="0"
|
||||||
|
radius="200">
|
||||||
|
</FogOfWarRadiusComponent>
|
||||||
|
|
||||||
|
<SpriteComponent _enabled="0"
|
||||||
|
alpha="0.8"
|
||||||
|
image_file="data/particles/torch_fog_of_war_hole.xml"
|
||||||
|
smooth_filtering="1"
|
||||||
|
fog_of_war_hole="1"
|
||||||
|
has_special_scale="1"
|
||||||
|
special_scale_x="4"
|
||||||
|
special_scale_y="4">
|
||||||
|
</SpriteComponent>
|
||||||
|
|
||||||
|
</Entity>
|
@ -3,12 +3,19 @@
|
|||||||
-- This software is released under the MIT License.
|
-- This software is released under the MIT License.
|
||||||
-- https://opensource.org/licenses/MIT
|
-- https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
dofile("data/scripts/lib/coroutines.lua")
|
dofile("mods/noita-mapcap/files/util.lua")
|
||||||
|
dofile("mods/noita-mapcap/files/external.lua")
|
||||||
|
dofile("mods/noita-mapcap/files/ws.lua")
|
||||||
|
|
||||||
--dofile("data/scripts/lib/utilities.lua")
|
--dofile("data/scripts/lib/utilities.lua")
|
||||||
dofile("data/scripts/perks/perk_list.lua")
|
dofile("data/scripts/perks/perk_list.lua")
|
||||||
|
|
||||||
local CAPTURE_GRID_SIZE = 64 -- in ingame pixels
|
if not async then -- Check if lib is already loaded
|
||||||
local CAPTURE_DELAY = 30 -- in frames
|
dofile("data/scripts/lib/coroutines.lua")
|
||||||
|
end
|
||||||
|
|
||||||
|
local CAPTURE_GRID_SIZE = 128 -- in ingame pixels
|
||||||
|
local CAPTURE_DELAY = 15 -- in frames
|
||||||
local CAPTURE_FORCE_HP = 40 -- * 25HP
|
local CAPTURE_FORCE_HP = 40 -- * 25HP
|
||||||
|
|
||||||
local function getPlayer()
|
local function getPlayer()
|
||||||
@ -87,20 +94,14 @@ local function resetPlayer()
|
|||||||
setPlayerHP(CAPTURE_FORCE_HP)
|
setPlayerHP(CAPTURE_FORCE_HP)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function doCapture()
|
local function startCapturing()
|
||||||
local ox, oy = getPlayerPos()
|
local ox, oy = getPlayerPos()
|
||||||
|
ox, oy = math.floor(ox / CAPTURE_GRID_SIZE) * CAPTURE_GRID_SIZE, math.floor(oy / CAPTURE_GRID_SIZE) * CAPTURE_GRID_SIZE
|
||||||
local x, y = ox, oy
|
local x, y = ox, oy
|
||||||
|
|
||||||
preparePlayer()
|
preparePlayer()
|
||||||
|
|
||||||
-- Coroutine to force player to x, y coordinate
|
GameSetCameraFree(true)
|
||||||
async_loop(
|
|
||||||
function()
|
|
||||||
teleportPlayer(x, y)
|
|
||||||
resetPlayer()
|
|
||||||
wait(0)
|
|
||||||
end
|
|
||||||
)
|
|
||||||
|
|
||||||
-- Coroutine to calculate next coordinate, and trigger screenshots
|
-- Coroutine to calculate next coordinate, and trigger screenshots
|
||||||
local i = 1
|
local i = 1
|
||||||
@ -108,23 +109,31 @@ local function doCapture()
|
|||||||
function()
|
function()
|
||||||
-- +x
|
-- +x
|
||||||
for i = 1, i, 1 do
|
for i = 1, i, 1 do
|
||||||
|
TriggerCapture(x, y)
|
||||||
x, y = x + CAPTURE_GRID_SIZE, y
|
x, y = x + CAPTURE_GRID_SIZE, y
|
||||||
|
GameSetCameraPos(x, y)
|
||||||
wait(CAPTURE_DELAY)
|
wait(CAPTURE_DELAY)
|
||||||
end
|
end
|
||||||
-- +y
|
-- +y
|
||||||
for i = 1, i, 1 do
|
for i = 1, i, 1 do
|
||||||
|
TriggerCapture(x, y)
|
||||||
x, y = x, y + CAPTURE_GRID_SIZE
|
x, y = x, y + CAPTURE_GRID_SIZE
|
||||||
|
GameSetCameraPos(x, y)
|
||||||
wait(CAPTURE_DELAY)
|
wait(CAPTURE_DELAY)
|
||||||
end
|
end
|
||||||
i = i + 1
|
i = i + 1
|
||||||
-- -x
|
-- -x
|
||||||
for i = 1, i, 1 do
|
for i = 1, i, 1 do
|
||||||
|
TriggerCapture(x, y)
|
||||||
x, y = x - CAPTURE_GRID_SIZE, y
|
x, y = x - CAPTURE_GRID_SIZE, y
|
||||||
|
GameSetCameraPos(x, y)
|
||||||
wait(CAPTURE_DELAY)
|
wait(CAPTURE_DELAY)
|
||||||
end
|
end
|
||||||
-- -y
|
-- -y
|
||||||
for i = 1, i, 1 do
|
for i = 1, i, 1 do
|
||||||
|
TriggerCapture(x, y)
|
||||||
x, y = x, y - CAPTURE_GRID_SIZE
|
x, y = x, y - CAPTURE_GRID_SIZE
|
||||||
|
GameSetCameraPos(x, y)
|
||||||
wait(CAPTURE_DELAY)
|
wait(CAPTURE_DELAY)
|
||||||
end
|
end
|
||||||
i = i + 1
|
i = i + 1
|
||||||
@ -143,12 +152,19 @@ async_loop(
|
|||||||
|
|
||||||
GuiLayoutBeginVertical(gui, 50, 20)
|
GuiLayoutBeginVertical(gui, 50, 20)
|
||||||
if GuiButton(gui, 0, 0, "Start capturing map", 1) then
|
if GuiButton(gui, 0, 0, "Start capturing map", 1) then
|
||||||
doCapture()
|
startCapturing()
|
||||||
GuiDestroy(gui)
|
GuiDestroy(gui)
|
||||||
gui = nil
|
gui = nil
|
||||||
end
|
end
|
||||||
GuiTextCentered(gui, 0, 0, "Don't do anything while the capturing process is running!")
|
GuiTextCentered(gui, 0, 0, "Don't do anything while the capturing process is running!")
|
||||||
GuiTextCentered(gui, 0, 0, "Use ESC and close the game to stop the process.")
|
GuiTextCentered(gui, 0, 0, "Use ESC and close the game to stop the process.")
|
||||||
|
--[[if GuiButton(gui, 0, 0, "DEBUG globals", 1) then
|
||||||
|
local file = io.open("mods/noita-mapcap/output/globals.txt", "w")
|
||||||
|
for i, v in pairs(_G) do
|
||||||
|
file:write(i .. "\n")
|
||||||
|
end
|
||||||
|
file:close()
|
||||||
|
end]]
|
||||||
GuiLayoutEnd(gui)
|
GuiLayoutEnd(gui)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
67
files/external.lua
Normal file
67
files/external.lua
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
-- Copyright (c) 2019 David Vogel
|
||||||
|
--
|
||||||
|
-- This software is released under the MIT License.
|
||||||
|
-- https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
--local host, port = "127.0.0.1", "46789"
|
||||||
|
--local socket = require("socket")
|
||||||
|
--local tcp = assert(socket.tcp())
|
||||||
|
|
||||||
|
--package.path = package.path .. ";" .. "mods/noita-mapcap/libs/lua/" .. "?.lua"
|
||||||
|
--package.cpath = package.cpath .. ";" .. "mods/noita-mapcap/libs/" .. "?.dll" -- TODO: Make it OS aware
|
||||||
|
|
||||||
|
local ffi = ffi or _G.ffi or require("ffi")
|
||||||
|
|
||||||
|
-- Don't let lua garbage collect and unload the lib, it will cause crashes later on!
|
||||||
|
-- Blah, this causes random crashes anyways. Probably the go runtime that interferes with something else in noita.
|
||||||
|
local status, caplib = pcall(ffi.load, "mods/noita-mapcap/bin/capture-b/capture")
|
||||||
|
if not status then
|
||||||
|
print("Error loading capture lib: " .. cap)
|
||||||
|
end
|
||||||
|
ffi.cdef [[
|
||||||
|
void Capture(int x, int y);
|
||||||
|
]]
|
||||||
|
|
||||||
|
function TriggerCapture(x, y)
|
||||||
|
--IngamePrint(os.execute(string.format("mods/noita-mapcap/bin/capture/capture.exe -x %i -y %i", x, y)))
|
||||||
|
--IngamePrint("a", os.execute("capture.exe"))
|
||||||
|
--os.execute("screenshots")
|
||||||
|
--IngamePrint("b", os.execute("../bin/capture/capture.exe"))
|
||||||
|
--local handle = io.popen("mods/noita-mapcap/bin/capture/capture.exe")
|
||||||
|
--local result = handle:read("*a")
|
||||||
|
--IngamePrint(result)
|
||||||
|
--handle:close()
|
||||||
|
--IngamePrint(os.execute("echo test"))
|
||||||
|
|
||||||
|
--print("trace", "A")
|
||||||
|
|
||||||
|
caplib.Capture(x, y)
|
||||||
|
|
||||||
|
--print("trace", "B")
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[function TriggerCapture(x, y)
|
||||||
|
local status, lib = pcall(require, "socket")
|
||||||
|
if not status then
|
||||||
|
IngamePrint("Error loading socket lib: " .. lib)
|
||||||
|
end
|
||||||
|
|
||||||
|
IngamePrint("DEBUG - Capture")
|
||||||
|
tcp:connect(host, port)
|
||||||
|
IngamePrint("DEBUG - Connected")
|
||||||
|
|
||||||
|
tcp:send(string.format("x: %i\n", x))
|
||||||
|
tcp:send(string.format("y: %i\n", y))
|
||||||
|
tcp:send(string.format("\n", y))
|
||||||
|
|
||||||
|
IngamePrint("DEBUG - Sent")
|
||||||
|
|
||||||
|
local result, error = tcp:receive("*l")
|
||||||
|
-- Ignore error or result for now, the function blocks until a newline character is received.
|
||||||
|
|
||||||
|
IngamePrint("DEBUG - Received")
|
||||||
|
|
||||||
|
tcp:close()
|
||||||
|
|
||||||
|
IngamePrint("DEBUG - Closed")
|
||||||
|
end]]
|
@ -1,5 +1,5 @@
|
|||||||
<MagicNumbers VIRTUAL_RESOLUTION_X="427"
|
<MagicNumbers VIRTUAL_RESOLUTION_X="960"
|
||||||
VIRTUAL_RESOLUTION_Y="242"
|
VIRTUAL_RESOLUTION_Y="540"
|
||||||
CAMERA_NO_MOVE_BUFFER_NEAR_VIEWPORT_EDGE="0.0"
|
CAMERA_NO_MOVE_BUFFER_NEAR_VIEWPORT_EDGE="0.0"
|
||||||
CAMERA_MOUSE_INTERPOLATION_SPEED="0.0"
|
CAMERA_MOUSE_INTERPOLATION_SPEED="0.0"
|
||||||
CAMERA_POSITION_INTERPOLATION_SPEED="50.0"
|
CAMERA_POSITION_INTERPOLATION_SPEED="50.0"
|
||||||
|
44
files/util.lua
Normal file
44
files/util.lua
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
-- Copyright (c) 2019 David Vogel
|
||||||
|
--
|
||||||
|
-- This software is released under the MIT License.
|
||||||
|
-- https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
function splitStringByLength(string, length)
|
||||||
|
local chunks = {}
|
||||||
|
for i = 1, #string, length do
|
||||||
|
table.insert(chunks, string:sub(i, i + length - 1))
|
||||||
|
end
|
||||||
|
return chunks
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Improved version of GamePrint, that behaves more like print.
|
||||||
|
function IngamePrint(...)
|
||||||
|
local arg = {...}
|
||||||
|
|
||||||
|
local result = ""
|
||||||
|
|
||||||
|
for i, v in ipairs(arg) do
|
||||||
|
result = result .. tostring(v) .. " "
|
||||||
|
end
|
||||||
|
|
||||||
|
for line in result:gmatch("[^\r\n]+") do
|
||||||
|
for i, v in ipairs(splitStringByLength(line, 100)) do
|
||||||
|
GamePrint(v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Globally overwrite print function and write output into a logfile
|
||||||
|
local logFile = io.open("lualog.txt", "w")
|
||||||
|
function print(...)
|
||||||
|
local arg = {...}
|
||||||
|
|
||||||
|
local result = ""
|
||||||
|
for i, v in ipairs(arg) do
|
||||||
|
result = result .. tostring(v) .. "\t"
|
||||||
|
end
|
||||||
|
result = result .. "\n"
|
||||||
|
|
||||||
|
logFile:write(result)
|
||||||
|
logFile:flush()
|
||||||
|
end
|
10
go.mod
Normal file
10
go.mod
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
module github.com/Dadido3/noita-mapcap
|
||||||
|
|
||||||
|
go 1.13
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 // indirect
|
||||||
|
github.com/gen2brain/shm v0.0.0-20180314170312-6c18ff7f8b90 // indirect
|
||||||
|
github.com/kbinani/screenshot v0.0.0-20190719135742-f06580e30cdc
|
||||||
|
github.com/lxn/win v0.0.0-20190919090605-24c5960b03d8 // indirect
|
||||||
|
)
|
10
go.sum
Normal file
10
go.sum
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc=
|
||||||
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
|
github.com/gen2brain/shm v0.0.0-20180314170312-6c18ff7f8b90 h1:QagTG5rauLt6pVVEhnVSrlIX4ifhVIZOwmw6x6D8TUw=
|
||||||
|
github.com/gen2brain/shm v0.0.0-20180314170312-6c18ff7f8b90/go.mod h1:uF6rMu/1nvu+5DpiRLwusA6xB8zlkNoGzKn8lmYONUo=
|
||||||
|
github.com/kbinani/screenshot v0.0.0-20190719135742-f06580e30cdc h1:kGFotla6Dyr6a2ILeExAHlttPgJtnoP/GIw2uVN/4h4=
|
||||||
|
github.com/kbinani/screenshot v0.0.0-20190719135742-f06580e30cdc/go.mod h1:f8GY5V3lRzakvEyr49P7hHRYoHtPr8zvj/7JodCoRzw=
|
||||||
|
github.com/lxn/win v0.0.0-20190919090605-24c5960b03d8 h1:RVMGIuuNgrpGB7I79f6xfhGCkpN47IaEGh8VTM0p7Xc=
|
||||||
|
github.com/lxn/win v0.0.0-20190919090605-24c5960b03d8/go.mod h1:ouWl4wViUNh8tPSIwxTVMuS014WakR1hqvBc2I0bMoA=
|
||||||
|
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd h1:DBH9mDw0zluJT/R+nGuV3jWFWLFaHyYZWD4tOT+cjn0=
|
||||||
|
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
Loading…
Reference in New Issue
Block a user