Split code, extend GUI mode, improve error handling
This commit is contained in:
		
							
								
								
									
										60
									
								
								cart.odin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								cart.odin
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,60 @@
 | 
				
			|||||||
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import rl "vendor:raylib"
 | 
				
			||||||
 | 
					import "core:strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CART_WIDTH :: 160
 | 
				
			||||||
 | 
					CART_HEIGHT :: 205
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Cart :: struct {
 | 
				
			||||||
 | 
						image : rl.Image,
 | 
				
			||||||
 | 
						texture : rl.Texture,
 | 
				
			||||||
 | 
						loaded : bool,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CartLoadError :: enum {
 | 
				
			||||||
 | 
						None,
 | 
				
			||||||
 | 
						Wrong_Size,
 | 
				
			||||||
 | 
						Allocation_Error,
 | 
				
			||||||
 | 
						Wrong_Type
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					loadCart :: proc(target: ^Cart, filename: cstring) -> CartLoadError {
 | 
				
			||||||
 | 
						if !strings.has_suffix(string(filename), ".png") {
 | 
				
			||||||
 | 
							return .Wrong_Type
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						unloadCart(target)
 | 
				
			||||||
 | 
						target.image = rl.LoadImage(filename)
 | 
				
			||||||
 | 
						if target.image.width != CART_WIDTH || target.image.height != CART_HEIGHT {
 | 
				
			||||||
 | 
							return CartLoadError.Wrong_Size
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						target.texture = rl.LoadTextureFromImage(target.image)
 | 
				
			||||||
 | 
						target.loaded = true
 | 
				
			||||||
 | 
						return CartLoadError.None
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unloadCart :: proc(target: ^Cart) {
 | 
				
			||||||
 | 
						if target.loaded {
 | 
				
			||||||
 | 
							rl.UnloadTexture(target.texture)
 | 
				
			||||||
 | 
							rl.MemFree(target.image.data)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						target.loaded = false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					convertCart :: proc(cart: rl.Image, target: rl.Image) -> rl.Image {
 | 
				
			||||||
 | 
						newCartImage := rl.ImageCopy(target)
 | 
				
			||||||
 | 
						for x : i32 = 0; x < newCartImage.width; x += 1 {
 | 
				
			||||||
 | 
							for y : i32 = 0; y < newCartImage.height; y += 1{
 | 
				
			||||||
 | 
								targetCol := rl.GetImageColor(target, x, y)
 | 
				
			||||||
 | 
								sourceCol := rl.GetImageColor(cart, x, y)
 | 
				
			||||||
 | 
								newCol := rl.Color{
 | 
				
			||||||
 | 
									targetCol.r & 0b11111100 | sourceCol.r & 0b00000011,
 | 
				
			||||||
 | 
									targetCol.g & 0b11111100 | sourceCol.g & 0b00000011,
 | 
				
			||||||
 | 
									targetCol.b & 0b11111100 | sourceCol.b & 0b00000011,
 | 
				
			||||||
 | 
									targetCol.a & 0b11111100 | sourceCol.a & 0b00000011,
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								rl.ImageDrawPixel(&newCartImage, x, y, newCol)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return newCartImage
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										65
									
								
								cmdmode.odin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								cmdmode.odin
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,65 @@
 | 
				
			|||||||
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import rl "vendor:raylib"
 | 
				
			||||||
 | 
					import "core:fmt"
 | 
				
			||||||
 | 
					import "core:strings"
 | 
				
			||||||
 | 
					import "core:os"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CmdMode :: proc(args: []string) {
 | 
				
			||||||
 | 
						if len(args) < 2 || len(args) > 3 {
 | 
				
			||||||
 | 
							fmt.eprintln(
 | 
				
			||||||
 | 
								"  PicoRepico cmdline usage:",
 | 
				
			||||||
 | 
								"repico <input.p8.png> <shell.png> <output.p8.png>",
 | 
				
			||||||
 | 
								"Use only 160x205 png images with PICO-8 palette",
 | 
				
			||||||
 | 
								sep = "\n",
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
							return 
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						outToStd := false
 | 
				
			||||||
 | 
						if len(args) == 2 {
 | 
				
			||||||
 | 
							outToStd = true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						argnames := []string {
 | 
				
			||||||
 | 
							"Input file",
 | 
				
			||||||
 | 
							"Shell file",
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						images := [2]rl.Image{}
 | 
				
			||||||
 | 
						for i := 0; i < 2; i+=1 {
 | 
				
			||||||
 | 
							if !strings.has_suffix(args[i], ".png") {
 | 
				
			||||||
 | 
								fmt.eprintf("ERROR: %v is not a .png file\n", argnames[i])
 | 
				
			||||||
 | 
								os.exit(auto_cast os.EINVAL)	
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							images[i] = rl.LoadImage(strings.unsafe_string_to_cstring(args[i]))
 | 
				
			||||||
 | 
							if !rl.IsImageReady(images[i]) {
 | 
				
			||||||
 | 
								fmt.eprintf("ERROR: can't load %v\n", argnames[i])
 | 
				
			||||||
 | 
								os.exit(auto_cast os.EIO)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if images[i].width != CART_WIDTH || images[i].height != CART_HEIGHT {
 | 
				
			||||||
 | 
								fmt.eprintf("ERROR: %v has wrong dimensions. 160x205 is expected\n", argnames[i])
 | 
				
			||||||
 | 
								rl.UnloadImage(images[i])
 | 
				
			||||||
 | 
								os.exit(auto_cast os.EINVAL)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer {
 | 
				
			||||||
 | 
							for img in images {
 | 
				
			||||||
 | 
								rl.UnloadImage(img)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						newCart := convertCart(images[0], images[1])
 | 
				
			||||||
 | 
						defer rl.UnloadImage(newCart)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !outToStd {
 | 
				
			||||||
 | 
							rl.ExportImage(newCart, strings.unsafe_string_to_cstring(args[2]))
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							filesize : i32 = 0
 | 
				
			||||||
 | 
							ptr := rl.ExportImageToMemory(newCart, ".png", &filesize)
 | 
				
			||||||
 | 
							defer rl.MemFree(ptr)
 | 
				
			||||||
 | 
							os.write_ptr(os.stdout, ptr, auto_cast filesize)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						fmt.eprintln("done!")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										163
									
								
								guimode.odin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								guimode.odin
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,163 @@
 | 
				
			|||||||
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import rl "vendor:raylib"
 | 
				
			||||||
 | 
					import "core:fmt"
 | 
				
			||||||
 | 
					import "core:strings"
 | 
				
			||||||
 | 
					import "core:slice"
 | 
				
			||||||
 | 
					import "core:os"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					W :: 400
 | 
				
			||||||
 | 
					H :: 300
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					width : int = W
 | 
				
			||||||
 | 
					height : int = H
 | 
				
			||||||
 | 
					zoom : int = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WrongSizeErrorTimer : i32 = 0
 | 
				
			||||||
 | 
					IsConverted : bool = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FILENAME_MAX :: 255
 | 
				
			||||||
 | 
					fileNameBuffer : [FILENAME_MAX]byte
 | 
				
			||||||
 | 
					fileNameString := cstring(&fileNameBuffer[0])
 | 
				
			||||||
 | 
					editMode := false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					State :: enum {
 | 
				
			||||||
 | 
						CartsInput,
 | 
				
			||||||
 | 
						Export,
 | 
				
			||||||
 | 
						GotError,
 | 
				
			||||||
 | 
						Exported
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GraphicsMode :: proc() {
 | 
				
			||||||
 | 
						cart := Cart{}
 | 
				
			||||||
 | 
						target := Cart{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						errorMessages := map[CartLoadError]cstring {
 | 
				
			||||||
 | 
							.None = "",
 | 
				
			||||||
 | 
							.Wrong_Size = "The image has wrong dimensions!\n160x205 PNG file expected",
 | 
				
			||||||
 | 
							.Wrong_Type = "The image is not a PNG file!\n160x205 PNG file expected",
 | 
				
			||||||
 | 
							.Allocation_Error = "Allocation error!",
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer delete(errorMessages)
 | 
				
			||||||
 | 
						currentError := CartLoadError.None
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						rl.SetConfigFlags({rl.ConfigFlag.WINDOW_RESIZABLE})
 | 
				
			||||||
 | 
						rl.InitWindow(W, H, "PicoRepico")
 | 
				
			||||||
 | 
						rl.SetTargetFPS(60)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//fontData := #load("font.ttf")
 | 
				
			||||||
 | 
						//font := rl.LoadFontFromMemory(".ttf", raw_data(fontData), auto_cast len(fontData), 8, nil, 0)
 | 
				
			||||||
 | 
						font := rl.LoadFontEx("font.ttf", 32, nil, 0)
 | 
				
			||||||
 | 
						rl.GuiSetFont(font)
 | 
				
			||||||
 | 
						rl.GuiSetStyle(auto_cast rl.GuiControl.DEFAULT, auto_cast rl.GuiControlProperty.BORDER_COLOR_NORMAL, i32(rl.ColorToInt(rl.Color{211, 2, 255, 255})))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hw : f32 = auto_cast width / 2
 | 
				
			||||||
 | 
						hh : f32 = auto_cast height / 2
 | 
				
			||||||
 | 
						state := State.CartsInput
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for !rl.WindowShouldClose() {
 | 
				
			||||||
 | 
							if WrongSizeErrorTimer > 0 {
 | 
				
			||||||
 | 
								WrongSizeErrorTimer -= 1
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							width = auto_cast rl.GetScreenWidth()
 | 
				
			||||||
 | 
							height = auto_cast rl.GetScreenHeight()
 | 
				
			||||||
 | 
							hw = auto_cast width / 2
 | 
				
			||||||
 | 
							hh = auto_cast height / 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							#partial switch state {
 | 
				
			||||||
 | 
							case .CartsInput: {
 | 
				
			||||||
 | 
								mouse := rl.GetMousePosition()
 | 
				
			||||||
 | 
								if rl.IsFileDropped() {
 | 
				
			||||||
 | 
									droppedFiles := rl.LoadDroppedFiles()
 | 
				
			||||||
 | 
									defer rl.UnloadDroppedFiles(droppedFiles)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if droppedFiles.count == 1 {
 | 
				
			||||||
 | 
										f := droppedFiles.paths[0]
 | 
				
			||||||
 | 
										if mouse.x <= hw {
 | 
				
			||||||
 | 
											fmt.eprintln("Got cart file: ", f)
 | 
				
			||||||
 | 
											currentError = loadCart(&cart, f)
 | 
				
			||||||
 | 
											if currentError != .None {
 | 
				
			||||||
 | 
												state = .GotError
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										if mouse.x > hw {
 | 
				
			||||||
 | 
											fmt.eprintln("Got target file: ", f)
 | 
				
			||||||
 | 
											currentError = loadCart(&target, f) 
 | 
				
			||||||
 | 
											if currentError != .None {
 | 
				
			||||||
 | 
												state = .GotError
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								buttonCartRect := rl.Rectangle{
 | 
				
			||||||
 | 
									x = hw - CART_WIDTH - 20,
 | 
				
			||||||
 | 
									y = 8,
 | 
				
			||||||
 | 
									width = CART_WIDTH,
 | 
				
			||||||
 | 
									height = CART_HEIGHT,
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								buttonTargetRect := rl.Rectangle{
 | 
				
			||||||
 | 
									x = hw + 20,
 | 
				
			||||||
 | 
									y = 8,
 | 
				
			||||||
 | 
									width = CART_WIDTH,
 | 
				
			||||||
 | 
									height = CART_HEIGHT,
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								convertButtonRect := rl.Rectangle{
 | 
				
			||||||
 | 
									x = hw - 40,
 | 
				
			||||||
 | 
									y = auto_cast height - 38,
 | 
				
			||||||
 | 
									width = 80,
 | 
				
			||||||
 | 
									height = 30,
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								rl.BeginDrawing()
 | 
				
			||||||
 | 
								rl.GuiDummyRec(rl.Rectangle{0, 0, auto_cast width, auto_cast height}, "")
 | 
				
			||||||
 | 
								rl.GuiButton(buttonCartRect, "Place here cart")
 | 
				
			||||||
 | 
								rl.GuiButton(buttonTargetRect, "Place here target")
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								if cart.loaded {
 | 
				
			||||||
 | 
									rl.DrawTexture(cart.texture, auto_cast buttonCartRect.x, auto_cast buttonCartRect.y, rl.WHITE)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if target.loaded {
 | 
				
			||||||
 | 
									rl.DrawTexture(target.texture, auto_cast buttonTargetRect.x, auto_cast buttonTargetRect.y, rl.WHITE)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if !(cart.loaded && target.loaded) { rl.GuiDisable() }
 | 
				
			||||||
 | 
								if rl.GuiButton(convertButtonRect, "CONVERT!") {
 | 
				
			||||||
 | 
									state = .Export
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								rl.GuiEnable()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							case .Export: {
 | 
				
			||||||
 | 
								res := rl.GuiTextInputBox(rl.Rectangle{hw - 100, 60, 200, 100}, "Input filename for result", "", "ok;cancel", fileNameString, FILENAME_MAX, nil)
 | 
				
			||||||
 | 
								if res == 0 || res == 2 {
 | 
				
			||||||
 | 
									state = .CartsInput
 | 
				
			||||||
 | 
									slice.fill(fileNameBuffer[:], 0)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if res == 1 {
 | 
				
			||||||
 | 
									newCart := convertCart(cart.image, target.image)
 | 
				
			||||||
 | 
									rl.ExportImage(newCart, fileNameString)
 | 
				
			||||||
 | 
									state = .Exported
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							case .Exported: {
 | 
				
			||||||
 | 
								if rl.GuiMessageBox(rl.Rectangle{hw-110, 80, 220, 120}, "Success!", "Cart was exported successfully", "CLOSE") != -1 {
 | 
				
			||||||
 | 
									state = .CartsInput
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							case .GotError: {
 | 
				
			||||||
 | 
								if rl.GuiMessageBox(rl.Rectangle{hw-150, 30, 300, 200}, "ERROR", errorMessages[currentError], "CLOSE") != -1 {
 | 
				
			||||||
 | 
									state = .CartsInput
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							rl.EndDrawing()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						unloadCart(&cart)
 | 
				
			||||||
 | 
						unloadCart(&target)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										196
									
								
								main.odin
									
									
									
									
									
								
							
							
						
						
									
										196
									
								
								main.odin
									
									
									
									
									
								
							@ -1,30 +1,11 @@
 | 
				
			|||||||
package main
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "core:fmt"
 | 
					 | 
				
			||||||
import rl "vendor:raylib"
 | 
					import rl "vendor:raylib"
 | 
				
			||||||
 | 
					import "core:fmt"
 | 
				
			||||||
import "core:mem"
 | 
					import "core:mem"
 | 
				
			||||||
import "core:os"
 | 
					import "core:os"
 | 
				
			||||||
import "core:strings"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
W :: 400
 | 
					 | 
				
			||||||
H :: 300
 | 
					 | 
				
			||||||
CW :: 160
 | 
					 | 
				
			||||||
CH :: 205
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
width : int = W
 | 
					 | 
				
			||||||
height : int = H
 | 
					 | 
				
			||||||
zoom : int = 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Cart :: struct {
 | 
					 | 
				
			||||||
	image : rl.Image,
 | 
					 | 
				
			||||||
	texture : rl.Texture,
 | 
					 | 
				
			||||||
	loaded : bool,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
WrongSizeErrorTimer : i32 = 0
 | 
					 | 
				
			||||||
IsConverted : bool = false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
main :: proc() {
 | 
					main :: proc() {
 | 
				
			||||||
	rl.SetTraceLogLevel(.FATAL)
 | 
						rl.SetTraceLogLevel(.FATAL)
 | 
				
			||||||
	when ODIN_DEBUG {
 | 
						when ODIN_DEBUG {
 | 
				
			||||||
@ -53,180 +34,5 @@ main :: proc() {
 | 
				
			|||||||
		GraphicsMode()
 | 
							GraphicsMode()
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(args) != 3 {
 | 
					 | 
				
			||||||
		fmt.eprintln(
 | 
					 | 
				
			||||||
			"  PicoRepico cmdline usage:",
 | 
					 | 
				
			||||||
			"repico <input.p8.png> <shell.png> <output.p8.png>",
 | 
					 | 
				
			||||||
			"Use only 160x205 png images with PICO-8 palette",
 | 
					 | 
				
			||||||
			sep = "\n",
 | 
					 | 
				
			||||||
		)
 | 
					 | 
				
			||||||
		return 
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	CmdMode(args)
 | 
						CmdMode(args)
 | 
				
			||||||
} 
 | 
					} 
 | 
				
			||||||
 | 
					 | 
				
			||||||
CartLoadError :: enum {
 | 
					 | 
				
			||||||
	None,
 | 
					 | 
				
			||||||
	Wrong_Size,
 | 
					 | 
				
			||||||
	Allocation_Error,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
loadCart :: proc(target: ^Cart, filename: cstring) -> CartLoadError {
 | 
					 | 
				
			||||||
	unloadCart(target)
 | 
					 | 
				
			||||||
	target.image = rl.LoadImage(filename)
 | 
					 | 
				
			||||||
	if target.image.width != CW || target.image.height != CH {
 | 
					 | 
				
			||||||
		return CartLoadError.Wrong_Size
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	target.texture = rl.LoadTextureFromImage(target.image)
 | 
					 | 
				
			||||||
	target.loaded = true
 | 
					 | 
				
			||||||
	return CartLoadError.None
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
unloadCart :: proc(target: ^Cart) {
 | 
					 | 
				
			||||||
	if target.loaded {
 | 
					 | 
				
			||||||
		rl.UnloadTexture(target.texture)
 | 
					 | 
				
			||||||
		rl.MemFree(target.image.data)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	target.loaded = false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
convertCart :: proc(cart: rl.Image, target: rl.Image) -> rl.Image {
 | 
					 | 
				
			||||||
	newCartImage := rl.ImageCopy(target)
 | 
					 | 
				
			||||||
	for x : i32 = 0; x < newCartImage.width; x += 1 {
 | 
					 | 
				
			||||||
		for y : i32 = 0; y < newCartImage.height; y += 1{
 | 
					 | 
				
			||||||
			targetCol := rl.GetImageColor(target, x, y)
 | 
					 | 
				
			||||||
			sourceCol := rl.GetImageColor(cart, x, y)
 | 
					 | 
				
			||||||
			newCol := rl.Color{
 | 
					 | 
				
			||||||
				targetCol.r & 0b11111100 | sourceCol.r & 0b00000011,
 | 
					 | 
				
			||||||
				targetCol.g & 0b11111100 | sourceCol.g & 0b00000011,
 | 
					 | 
				
			||||||
				targetCol.b & 0b11111100 | sourceCol.b & 0b00000011,
 | 
					 | 
				
			||||||
				targetCol.a & 0b11111100 | sourceCol.a & 0b00000011,
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			rl.ImageDrawPixel(&newCartImage, x, y, newCol)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return newCartImage
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GraphicsMode :: proc() {
 | 
					 | 
				
			||||||
	cart := Cart{}
 | 
					 | 
				
			||||||
	target := Cart{}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	rl.InitWindow(W, H, "PicoRepico")
 | 
					 | 
				
			||||||
	rl.SetTargetFPS(60)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	hw : f32 = auto_cast width / 2
 | 
					 | 
				
			||||||
	hh : f32 = auto_cast height / 2
 | 
					 | 
				
			||||||
	buttonCartRect := rl.Rectangle{
 | 
					 | 
				
			||||||
		x = hw - CW - 20,
 | 
					 | 
				
			||||||
		y = 8,
 | 
					 | 
				
			||||||
		width = CW,
 | 
					 | 
				
			||||||
		height = CH,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	buttonTargetRect := rl.Rectangle{
 | 
					 | 
				
			||||||
		x = hw + 20,
 | 
					 | 
				
			||||||
		y = 8,
 | 
					 | 
				
			||||||
		width = CW,
 | 
					 | 
				
			||||||
		height = CH,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	convertButtonRect := rl.Rectangle{
 | 
					 | 
				
			||||||
		x = hw - 40,
 | 
					 | 
				
			||||||
		y = auto_cast height - 38,
 | 
					 | 
				
			||||||
		width = 80,
 | 
					 | 
				
			||||||
		height = 30,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for !rl.WindowShouldClose() {
 | 
					 | 
				
			||||||
		if WrongSizeErrorTimer > 0 {
 | 
					 | 
				
			||||||
			WrongSizeErrorTimer -= 1
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		mouse := rl.GetMousePosition()
 | 
					 | 
				
			||||||
		if rl.IsFileDropped() {
 | 
					 | 
				
			||||||
			droppedFiles := rl.LoadDroppedFiles()
 | 
					 | 
				
			||||||
			defer rl.UnloadDroppedFiles(droppedFiles)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if droppedFiles.count == 1 {
 | 
					 | 
				
			||||||
				f := droppedFiles.paths[0]
 | 
					 | 
				
			||||||
				if mouse.x <= hw {
 | 
					 | 
				
			||||||
					fmt.eprintln("Got cart file: ", f)
 | 
					 | 
				
			||||||
					if loadCart(&cart, f) == .Wrong_Size {
 | 
					 | 
				
			||||||
						WrongSizeErrorTimer = 180
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				if mouse.x > hw {
 | 
					 | 
				
			||||||
					fmt.eprintln("Got target file: ", f)
 | 
					 | 
				
			||||||
					if loadCart(&target, f) == .Wrong_Size {
 | 
					 | 
				
			||||||
						WrongSizeErrorTimer = 180
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		rl.BeginDrawing()
 | 
					 | 
				
			||||||
		rl.GuiDummyRec(rl.Rectangle{0, 0, auto_cast width, auto_cast height}, "")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		rl.GuiButton(buttonCartRect, "Place here cart")
 | 
					 | 
				
			||||||
		rl.GuiButton(buttonTargetRect, "Place here target")
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		if WrongSizeErrorTimer > 0 {
 | 
					 | 
				
			||||||
			rl.GuiLabel(rl.Rectangle{8, auto_cast height - 38, 100, 30}, "WRONG IMAGE SIZE")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if cart.loaded {
 | 
					 | 
				
			||||||
			rl.DrawTexture(cart.texture, auto_cast buttonCartRect.x, auto_cast buttonCartRect.y, rl.WHITE)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if target.loaded {
 | 
					 | 
				
			||||||
			rl.DrawTexture(target.texture, auto_cast buttonTargetRect.x, auto_cast buttonTargetRect.y, rl.WHITE)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if rl.GuiButton(convertButtonRect, "CONVERT!") {
 | 
					 | 
				
			||||||
			newCart := convertCart(cart.image, target.image)
 | 
					 | 
				
			||||||
			rl.ExportImage(newCart, "output.p8.png")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		rl.EndDrawing()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	unloadCart(&cart)
 | 
					 | 
				
			||||||
	unloadCart(&target)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CmdMode :: proc(args: []string) {
 | 
					 | 
				
			||||||
	argnames := []string {
 | 
					 | 
				
			||||||
		"input file",
 | 
					 | 
				
			||||||
		"shell file",
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	images := [2]rl.Image{}
 | 
					 | 
				
			||||||
	for i := 0; i < 2; i+=1 {
 | 
					 | 
				
			||||||
		if !strings.has_suffix(args[i], ".png") {
 | 
					 | 
				
			||||||
			fmt.eprintf("%v is not a .png file", argnames[i])
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		images[i] = rl.LoadImage(strings.unsafe_string_to_cstring(args[i]))
 | 
					 | 
				
			||||||
		if !rl.IsImageReady(images[i]) {
 | 
					 | 
				
			||||||
			fmt.eprintf("can't load %v", argnames[i])
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer {
 | 
					 | 
				
			||||||
		for img in images {
 | 
					 | 
				
			||||||
			rl.UnloadImage(img)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	newCart := convertCart(images[0], images[1])
 | 
					 | 
				
			||||||
	defer rl.UnloadImage(newCart)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if args[2] != "--" {
 | 
					 | 
				
			||||||
		rl.ExportImage(newCart, strings.unsafe_string_to_cstring(args[2]))
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		filesize : i32 = 0
 | 
					 | 
				
			||||||
		ptr := rl.ExportImageToMemory(newCart, ".png", &filesize)
 | 
					 | 
				
			||||||
		defer rl.MemFree(ptr)
 | 
					 | 
				
			||||||
		os.write_ptr(os.stdout, ptr, auto_cast filesize)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	fmt.eprintln("done!")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user