Remove old map editor
Removes the old map editor and files that only it depended on.
17
.gitattributes
vendored
@@ -15,7 +15,6 @@ CorsixTH/Bitmap/flag_travel_east.bmp -text
|
||||
CorsixTH/Bitmap/flag_travel_north.bmp -text
|
||||
CorsixTH/Bitmap/flag_travel_south.bmp -text
|
||||
CorsixTH/Bitmap/flag_travel_west.bmp -text
|
||||
CorsixTH/Bitmap/flags32.png -text
|
||||
CorsixTH/Bitmap/fullscreen_border_bottom.bmp -text
|
||||
CorsixTH/Bitmap/fullscreen_border_bottomleft.bmp -text
|
||||
CorsixTH/Bitmap/fullscreen_border_bottomright.bmp -text
|
||||
@@ -32,13 +31,6 @@ CorsixTH/Bitmap/map_cell_outline_east.bmp -text
|
||||
CorsixTH/Bitmap/map_cell_outline_north.bmp -text
|
||||
CorsixTH/Bitmap/map_cell_outline_south.bmp -text
|
||||
CorsixTH/Bitmap/map_cell_outline_west.bmp -text
|
||||
CorsixTH/Bitmap/new32.png -text svneol=unset#image/png
|
||||
CorsixTH/Bitmap/open32.png -text svneol=unset#image/png
|
||||
CorsixTH/Bitmap/parcels32.png -text
|
||||
CorsixTH/Bitmap/positions32.png -text
|
||||
CorsixTH/Bitmap/redo32.png -text
|
||||
CorsixTH/Bitmap/save32.png -text svneol=unset#image/png
|
||||
CorsixTH/Bitmap/transparent_walls32.png -text
|
||||
CorsixTH/Bitmap/tree_collapsed.bmp -text
|
||||
CorsixTH/Bitmap/tree_ctrl.dat -text
|
||||
CorsixTH/Bitmap/tree_ctrl.pal -text
|
||||
@@ -46,7 +38,6 @@ CorsixTH/Bitmap/tree_ctrl.tab -text
|
||||
CorsixTH/Bitmap/tree_expanded.bmp -text
|
||||
CorsixTH/Bitmap/tree_leaf.bmp -text
|
||||
CorsixTH/Bitmap/tree_level.bmp -text
|
||||
CorsixTH/Bitmap/undo32.png -text
|
||||
CorsixTH/CorsixTH.ico -text
|
||||
CorsixTH/Icon.icns -text
|
||||
CorsixTH/Levels/Example.map -text
|
||||
@@ -54,11 +45,6 @@ CorsixTH/Levels/avatar.map -text
|
||||
CorsixTH/Levels/confined_v5.map -text
|
||||
CorsixTH/Levels/finisham.map -text
|
||||
CorsixTH/Levels/original08.level -text
|
||||
CorsixTH/Lua/command.lua -text
|
||||
CorsixTH/Lua/command_stack.lua -text
|
||||
CorsixTH/Lua/commands/compound.lua -text
|
||||
CorsixTH/Lua/commands/set_map_cell.lua -text
|
||||
CorsixTH/Lua/commands/set_map_cell_flags.lua -text
|
||||
CorsixTH/Lua/dialogs/resizables/customise.lua -text
|
||||
CorsixTH/Lua/dialogs/resizables/folder_settings.lua -text
|
||||
CorsixTH/Lua/dialogs/resizables/update.lua -text
|
||||
@@ -104,7 +90,4 @@ LevelEdit/src/icon256.png -text
|
||||
LevelEdit/src/icon32.png -text
|
||||
LevelEdit/src/icon48.png -text
|
||||
LevelEdit/src/icon64.png -text
|
||||
MapEdit/Icon.icns -text
|
||||
MapEdit/MapEdit.ico -text
|
||||
MapEdit/RequiredResources.txt -text
|
||||
WindowsInstaller/welcome.bmp -text
|
||||
|
@@ -7,7 +7,6 @@
|
||||
# - WITH_FREETYPE2
|
||||
# - WITH_MOVIES : Activate movies (requires Sound)
|
||||
# - BUILD_ANIMVIEWER
|
||||
# - BUILD_MAPEDITOR
|
||||
# - WITH_LUAJIT : Whether to use LuaJIT 2 instead of Lua51 (default is LuaJIT 2)
|
||||
# - WITH_LIBAV : Whether to use LibAV (as opposed to FFMEPG) when building movies
|
||||
# - WITH_VLD : Build with Visual Leak Detector (requires Visual Studio)
|
||||
@@ -37,7 +36,6 @@ OPTION(WITH_FREETYPE2 "Enhanced Font Support" ON)
|
||||
OPTION(WITH_LUAJIT "Use LuaJIT instead of Lua" OFF)
|
||||
OPTION(WITH_LIBAV "Use LibAV instead of FFmpeg" OFF)
|
||||
OPTION(BUILD_ANIMVIEWER "Build the animation viewer as part of the build process" OFF)
|
||||
OPTION(BUILD_MAPEDITOR "Build the map editor as part of the build process" OFF)
|
||||
IF(MSVC)
|
||||
OPTION(WITH_VLD "Build with Visual Leak Detector for Visual Studio" OFF)
|
||||
ENDIF(MSVC)
|
||||
@@ -107,15 +105,6 @@ IF(BUILD_ANIMVIEWER)
|
||||
add_subdirectory(AnimView)
|
||||
ENDIF(BUILD_ANIMVIEWER)
|
||||
|
||||
IF(BUILD_MAPEDITOR)
|
||||
IF(WITH_OPENGL)
|
||||
message("Building MapEdit")
|
||||
add_subdirectory(MapEdit)
|
||||
ELSE(WITH_OPENGL)
|
||||
message(FATAL_ERROR "The map editor can only be built when using OpenGL as renderer")
|
||||
ENDIF(WITH_OPENGL)
|
||||
ENDIF(BUILD_MAPEDITOR)
|
||||
|
||||
# Documentation generation, construct 'doc' target (or a message it is disabled).
|
||||
|
||||
# Try to find 'lua'
|
||||
@@ -172,14 +161,6 @@ IF (DOXYGEN_FOUND)
|
||||
add_dependencies(doc doc_leveledit)
|
||||
|
||||
|
||||
add_custom_target(doc_mapedit
|
||||
${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/DoxyGen/mapedit.doxygen
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc
|
||||
COMMENT "Generating API documentation for MapEdit" VERBATIM
|
||||
)
|
||||
add_dependencies(doc doc_mapedit)
|
||||
|
||||
|
||||
add_custom_target(doc_corsixth_engine
|
||||
${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/DoxyGen/corsixth_engine.doxygen
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc
|
||||
@@ -223,7 +204,6 @@ IF (DOXYGEN_FOUND)
|
||||
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/doc/index.html "<ul>\n")
|
||||
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/doc/index.html " <li><a href=\"animview/html/index.html\">Animation viewer documentation</a>\n")
|
||||
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/doc/index.html " <li><a href=\"leveledit/html/index.html\">Level editor documentation</a>\n")
|
||||
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/doc/index.html " <li><a href=\"mapedit/html/index.html\">Map editor documentation</a>\n")
|
||||
ENDIF (DOXYGEN_FOUND)
|
||||
|
||||
IF (DOXYGEN_FOUND OR LUA_PROGRAM_FOUND)
|
||||
|
Before Width: | Height: | Size: 342 B |
Before Width: | Height: | Size: 1008 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 413 B |
Before Width: | Height: | Size: 358 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 890 B |
Before Width: | Height: | Size: 353 B |
Before Width: | Height: | Size: 1.6 KiB |
@@ -1,29 +0,0 @@
|
||||
--[[ Copyright (c) 2013 Alan Woolley
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE. --]]
|
||||
|
||||
class "Command"
|
||||
|
||||
---@type Command
|
||||
local Command = _G["Command"]
|
||||
|
||||
function Command:Command(can_undo)
|
||||
self.can_undo = can_undo
|
||||
end
|
||||
|
@@ -1,61 +0,0 @@
|
||||
--[[ Copyright (c) 2013 Alan Woolley
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE. --]]
|
||||
|
||||
class "CommandStack"
|
||||
|
||||
---@type CommandStack
|
||||
local CommandStack = _G["CommandStack"]
|
||||
|
||||
function CommandStack:CommandStack()
|
||||
self.undo_stack = {}
|
||||
self.redo_stack = {}
|
||||
end
|
||||
|
||||
function CommandStack:redo()
|
||||
if (#self.redo_stack == 0) then
|
||||
print "Nothing left to redo!"
|
||||
return
|
||||
end
|
||||
local cmd = self.redo_stack[#self.redo_stack]
|
||||
table.remove(self.redo_stack, #self.redo_stack)
|
||||
table.insert(self.undo_stack, #self.undo_stack + 1, cmd)
|
||||
cmd:perform()
|
||||
return #self.redo_stack == 0
|
||||
end
|
||||
|
||||
function CommandStack:undo()
|
||||
if (#self.undo_stack == 0) then
|
||||
print "Nothing left to undo!"
|
||||
return
|
||||
end
|
||||
local cmd = self.undo_stack[#self.undo_stack]
|
||||
table.remove(self.undo_stack, #self.undo_stack)
|
||||
table.insert(self.redo_stack, #self.redo_stack + 1, cmd)
|
||||
cmd:undo()
|
||||
return #self.undo_stack == 0
|
||||
end
|
||||
|
||||
function CommandStack:add(cmd)
|
||||
if not cmd.can_undo then
|
||||
self.undo_stack = {}
|
||||
end
|
||||
self.redo_stack = {}
|
||||
table.insert(self.undo_stack, #self.undo_stack + 1, cmd)
|
||||
end
|
@@ -1,48 +0,0 @@
|
||||
--[[ Copyright (c) 2013 Alan Woolley
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE. --]]
|
||||
|
||||
class "CompoundCommand" (Command)
|
||||
|
||||
---@type CompoundCommand
|
||||
local CompoundCommand = _G["CompoundCommand"]
|
||||
|
||||
function CompoundCommand:CompoundCommand()
|
||||
self:Command(true)
|
||||
self.command_list = {}
|
||||
end
|
||||
|
||||
function CompoundCommand:addCommand(cmd)
|
||||
table.insert(self.command_list, #self.command_list + 1, cmd)
|
||||
end
|
||||
|
||||
function CompoundCommand:perform()
|
||||
for i = 1 , #self.command_list do
|
||||
local cmd = self.command_list[i]
|
||||
cmd:perform()
|
||||
end
|
||||
end
|
||||
|
||||
function CompoundCommand:undo()
|
||||
for i = #self.command_list, 1, -1 do
|
||||
local cmd = self.command_list[i]
|
||||
cmd:undo()
|
||||
end
|
||||
end
|
||||
|
@@ -1,50 +0,0 @@
|
||||
--[[ Copyright (c) 2013 Alan Woolley
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE. --]]
|
||||
|
||||
class "SetMapCellCommand" (Command)
|
||||
|
||||
---@type SetMapCellCommand
|
||||
local SetMapCellCommand = _G["SetMapCellCommand"]
|
||||
|
||||
function SetMapCellCommand:SetMapCellCommand(map)
|
||||
self:Command(true)
|
||||
self.map = map
|
||||
self.paint_list = {}
|
||||
end
|
||||
|
||||
function SetMapCellCommand:addTile(x_tile, y_tile, ...)
|
||||
local old = {self.map:getCell(x_tile, y_tile)}
|
||||
table.insert(self.paint_list, #self.paint_list + 1, {x = x_tile, y = y_tile, new_flags = {...}, old_flags = old})
|
||||
end
|
||||
|
||||
function SetMapCellCommand:perform()
|
||||
for i = 1 , #self.paint_list do
|
||||
local cell_table = self.paint_list[i]
|
||||
self.map:setCell(cell_table.x, cell_table.y, unpack(cell_table.new_flags))
|
||||
end
|
||||
end
|
||||
|
||||
function SetMapCellCommand:undo()
|
||||
for i = #self.paint_list, 1, -1 do
|
||||
local cell_table = self.paint_list[i]
|
||||
self.map:setCell(cell_table.x, cell_table.y, unpack(cell_table.old_flags))
|
||||
end
|
||||
end
|
||||
|
@@ -1,49 +0,0 @@
|
||||
--[[ Copyright (c) 2013 Alan Woolley
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE. --]]
|
||||
|
||||
class "SetMapCellFlagsCommand" (Command)
|
||||
|
||||
---@type SetMapCellFlagsCommand
|
||||
local SetMapCellFlagsCommand = _G["SetMapCellFlagsCommand"]
|
||||
|
||||
function SetMapCellFlagsCommand:SetMapCellFlagsCommand(map)
|
||||
self:Command(true)
|
||||
self.map = map
|
||||
self.paint_list = {}
|
||||
end
|
||||
|
||||
function SetMapCellFlagsCommand:addTile(x_tile, y_tile, ...)
|
||||
local old = {self.map:getCellFlags(x_tile, y_tile)}
|
||||
table.insert(self.paint_list, #self.paint_list + 1, {x = x_tile, y = y_tile, new_flags = {...}, old_flags = old})
|
||||
end
|
||||
|
||||
function SetMapCellFlagsCommand:perform()
|
||||
for i = 1 , #self.paint_list do
|
||||
local cell_table = self.paint_list[i]
|
||||
self.map:setCellFlags(cell_table.x, cell_table.y, unpack(cell_table.new_flags))
|
||||
end
|
||||
end
|
||||
|
||||
function SetMapCellFlagsCommand:undo()
|
||||
for i = #self.paint_list, 1, -1 do
|
||||
local cell_table = self.paint_list[i]
|
||||
self.map:setCellFlags(cell_table.x, cell_table.y, unpack(cell_table.old_flags))
|
||||
end
|
||||
end
|
@@ -146,9 +146,6 @@ int CorsixTH_lua_main_no_eval(lua_State *L)
|
||||
#if defined(IS_CORSIXTH_APP)
|
||||
"code = loadfile(\"CorsixTH.app/Contents/Resources/\"..name)\n"
|
||||
"if code then return code end\n"
|
||||
#elif defined(IS_MAPEDIT_APP)
|
||||
"code = loadfile(\"MapEdit.app/Contents/Resources/\"..name)\n"
|
||||
"if code then return code end\n"
|
||||
#endif
|
||||
#endif
|
||||
"for num_dotdot = 0, 3 do\n"
|
||||
|
@@ -1,200 +0,0 @@
|
||||
# Project Declaration
|
||||
PROJECT(MapEdit)
|
||||
# 2.8.3 is required for the wxWidgets finder to know about ribbon
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.3)
|
||||
|
||||
# Generate source files list
|
||||
# Note: Done after generating config.h
|
||||
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/CorsixTH/Src/)
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/CorsixTH/Src/)
|
||||
FILE(GLOB_RECURSE mapedit_source_files
|
||||
${CMAKE_SOURCE_DIR}/MapEdit/Src/*.cpp
|
||||
${CMAKE_SOURCE_DIR}/MapEdit/Src/*.c
|
||||
${CMAKE_SOURCE_DIR}/MapEdit/Src/*.h
|
||||
${CMAKE_SOURCE_DIR}/MapEdit/MapEdit.rc
|
||||
${CMAKE_SOURCE_DIR}/CorsixTH/Src/*.h
|
||||
${CMAKE_SOURCE_DIR}/CorsixTH/Src/*.c
|
||||
${CMAKE_SOURCE_DIR}/CorsixTH/Src/*.cpp
|
||||
${CMAKE_SOURCE_DIR}/LFS/*.c
|
||||
${CMAKE_SOURCE_DIR}/LPEG/*.c
|
||||
)
|
||||
|
||||
# Declaration of the executable
|
||||
IF(APPLE)
|
||||
add_definitions(-DIS_MAPEDIT_APP)
|
||||
|
||||
set(corsixth_icon_file ${CMAKE_SOURCE_DIR}/MapEdit/Icon.icns)
|
||||
set_source_files_properties(
|
||||
${corsixth_icon_file}
|
||||
PROPERTIES
|
||||
MACOSX_PACKAGE_LOCATION Resources
|
||||
)
|
||||
set(MACOSX_BUNDLE_ICON_FILE Icon.icns)
|
||||
|
||||
add_executable(MapEdit
|
||||
MACOSX_BUNDLE
|
||||
${mapedit_source_files}
|
||||
${corsixth_icon_file}
|
||||
)
|
||||
|
||||
set_target_properties(MapEdit PROPERTIES LINK_FLAGS_MINSIZEREL "-dead_strip")
|
||||
set_target_properties(MapEdit PROPERTIES XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../Frameworks")
|
||||
|
||||
#Add an extra step at the end of the build process to copy the resources into the bundle.
|
||||
add_custom_command(TARGET MapEdit
|
||||
POST_BUILD
|
||||
COMMAND rsync -rv --include-from ${CMAKE_SOURCE_DIR}/MapEdit/RequiredResources.txt ${CMAKE_SOURCE_DIR}/CorsixTH/ \${TARGET_BUILD_DIR}/\${FULL_PRODUCT_NAME}/Contents/Resources)
|
||||
|
||||
ELSE()
|
||||
add_executable(MapEdit
|
||||
WIN32
|
||||
${mapedit_source_files}
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
# Basic platform dependant stuff
|
||||
IF(UNIX)
|
||||
IF(APPLE)
|
||||
# fruit goes here
|
||||
ELSE(APPLE)
|
||||
# regular unix/linux
|
||||
ENDIF(APPLE)
|
||||
ELSE(UNIX)
|
||||
IF(WIN32)
|
||||
# Win32 specific
|
||||
IF(MSVC)
|
||||
# We want to bind against the very latest versions of the MSVC runtimes
|
||||
add_definitions(/D "_BIND_TO_CURRENT_VCLIBS_VERSION=1")
|
||||
ELSE(MSVC)
|
||||
IF(MSYS)
|
||||
# MSYS stuff
|
||||
ELSE(MSYS)
|
||||
# What's left? MINGW? CYGWIN? BORLAND?
|
||||
ENDIF(MSYS)
|
||||
ENDIF(MSVC)
|
||||
ELSE(WIN32)
|
||||
# other OS (not UNIX, not 32/64 bit Windows)
|
||||
ENDIF(WIN32)
|
||||
ENDIF(UNIX)
|
||||
|
||||
# Finding libraries
|
||||
|
||||
# Find WxWidgets
|
||||
SET(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${PROJECT_SOURCE_DIR}")
|
||||
MESSAGE("Module path: ${CMAKE_MODULE_PATH}")
|
||||
SET(wxWidgets_USE_LIBS gl ribbon core base) # optionally: more than wx std libs
|
||||
FIND_PACKAGE(wxWidgets REQUIRED)
|
||||
IF(wxWidgets_FOUND)
|
||||
LINK_LIBRARIES(${wxWidgets_LIBRARIES})
|
||||
INCLUDE_DIRECTORIES(${wxWidgets_INCLUDE_DIRS})
|
||||
INCLUDE(${wxWidgets_USE_FILE})
|
||||
TARGET_LINK_LIBRARIES(MapEdit ${wxWidgets_LIBRARIES})
|
||||
message(" wxWidgets found")
|
||||
ELSE(wxWidgets_FOUND)
|
||||
message( FATAL_ERROR "error: wxWdigets library (or one of it's components) not found, it is required to build")
|
||||
message( "Make sure the path is correctly defined or set the envirnomental variable WXWIN to the correct location" )
|
||||
ENDIF(wxWidgets_FOUND)
|
||||
|
||||
# Find SDL
|
||||
FIND_PACKAGE(SDL2 REQUIRED)
|
||||
IF(SDL_FOUND)
|
||||
INCLUDE_DIRECTORIES(${SDL_INCLUDE_DIR})
|
||||
TARGET_LINK_LIBRARIES(MapEdit ${SDL_LIBRARY})
|
||||
message( " SDL found" )
|
||||
ELSE(SDL_FOUND)
|
||||
message( FATAL_ERROR "error: SDL library not found, it is required to build")
|
||||
message( "Make sure the path is correctly defined or set the envirnomental variable SDLDIR to the correct location" )
|
||||
ENDIF(SDL_FOUND)
|
||||
|
||||
# Find SDL_mixer
|
||||
IF(CORSIX_TH_USE_SDL_MIXER)
|
||||
FIND_PACKAGE(SDL2_mixer REQUIRED)
|
||||
IF(SDLMIXER_FOUND)
|
||||
TARGET_LINK_LIBRARIES(MapEdit ${SDLMIXER_LIBRARY})
|
||||
INCLUDE_DIRECTORIES(${SDLMIXER_INCLUDE_DIR})
|
||||
message( " SDL_mixer found" )
|
||||
ELSE(SDLMIXER_FOUND)
|
||||
message( "error: SDL_mixer library not found, it was selected to be included")
|
||||
ENDIF(SDLMIXER_FOUND)
|
||||
ENDIF(CORSIX_TH_USE_SDL_MIXER)
|
||||
|
||||
# Find FFMPEG
|
||||
IF(CORSIX_TH_USE_FFMPEG)
|
||||
FIND_PACKAGE(FFmpeg COMPONENTS AVFORMAT AVCODEC AVUTIL SWSCALE SWRESAMPLE REQUIRED)
|
||||
IF(FFMPEG_FOUND)
|
||||
TARGET_LINK_LIBRARIES(MapEdit ${FFMPEG_LIBRARIES})
|
||||
INCLUDE_DIRECTORIES(${FFMPEG_INCLUDE_DIRS})
|
||||
IF(APPLE)
|
||||
TARGET_LINK_LIBRARIES(MapEdit libz.dylib)
|
||||
ENDIF()
|
||||
message(" FFmpeg found")
|
||||
ELSE(FFMPEG_FOUND)
|
||||
message("Error: FFmpeg library not found, even though it was selected to be included")
|
||||
ENDIF(FFMPEG_FOUND)
|
||||
ENDIF(CORSIX_TH_USE_FFMPEG)
|
||||
|
||||
# Find Freetype2
|
||||
IF(CORSIX_TH_USE_FREETYPE2)
|
||||
FIND_PACKAGE(Freetype REQUIRED)
|
||||
IF(FREETYPE_FOUND)
|
||||
TARGET_LINK_LIBRARIES(MapEdit ${FREETYPE_LIBRARIES})
|
||||
INCLUDE_DIRECTORIES(${FREETYPE_INCLUDE_DIRS})
|
||||
IF(APPLE)
|
||||
TARGET_LINK_LIBRARIES(MapEdit libz.dylib)
|
||||
TARGET_LINK_LIBRARIES(MapEdit libbz2.dylib)
|
||||
ENDIF()
|
||||
message(" FreeType2 found")
|
||||
ELSE(FREETYPE_FOUND)
|
||||
message("Error: FreeType2 library not found, even though it was selected to be used")
|
||||
ENDIF(FREETYPE_FOUND)
|
||||
ENDIF(CORSIX_TH_USE_FREETYPE2)
|
||||
|
||||
# Find OpenGL
|
||||
IF(CORSIX_TH_USE_OGL_RENDERER)
|
||||
FIND_PACKAGE(OpenGL REQUIRED)
|
||||
IF(OPENGL_FOUND)
|
||||
TARGET_LINK_LIBRARIES( MapEdit ${OPENGL_gl_LIBRARY})
|
||||
INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR})
|
||||
message( " OpenGL found" )
|
||||
ELSE(OPENGL_FOUND)
|
||||
message( FATAL_ERROR "error: OpenGL library not found, it is required to build")
|
||||
ENDIF(OPENGL_FOUND)
|
||||
ENDIF(CORSIX_TH_USE_OGL_RENDERER)
|
||||
|
||||
# Find Lua
|
||||
FIND_PACKAGE(Lua REQUIRED)
|
||||
IF(Lua_FOUND)
|
||||
TARGET_LINK_LIBRARIES(MapEdit ${LUA_LIBRARY})
|
||||
INCLUDE_DIRECTORIES(${LUA_INCLUDE_DIR})
|
||||
# Special link flags needed on OSX/64bit, according to: http://luajit.org/install.html
|
||||
# If these are not specified, luaL_newstate() returns NULL and we get this:
|
||||
# Fatal error starting CorsixTH: Cannot open Lua state.
|
||||
IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND LUA_INTERPRETER_TYPE STREQUAL "LuaJIT" AND CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
TARGET_LINK_LIBRARIES(MapEdit "-pagezero_size 10000" "-image_base 100000000")
|
||||
ENDIF()
|
||||
message(" ${LUA_INTERPRETER_TYPE} found")
|
||||
ELSE(Lua_FOUND)
|
||||
message(FATAL_ERROR "Error: Lua library not found, it is required to build")
|
||||
ENDIF(Lua_FOUND)
|
||||
|
||||
# Find msinttypes for MSVC
|
||||
IF(MSVC AND NOT CORSIX_TH_HAS_INTTYPES_H)
|
||||
FIND_PATH(MSINTTYPES_INCLUDE_DIRS "inttypes.h" NO_DEFAULT_PATH)
|
||||
MESSAGE(STATUS "Adding include directory: ${MSINTTYPES_INCLUDE_DIRS}")
|
||||
INCLUDE_DIRECTORIES(${MSINTTYPES_INCLUDE_DIRS})
|
||||
SET(CORSIX_TH_HAS_INTTYPES_H 1)
|
||||
ENDIF(MSVC AND NOT CORSIX_TH_HAS_INTTYPES_H)
|
||||
|
||||
IF(APPLE)
|
||||
#Just use the prefix as it's sufficient to just set the prefix to /Applications on Mac.
|
||||
install(TARGETS MapEdit BUNDLE DESTINATION .)
|
||||
|
||||
# Fix the OS X bundle to include required libraries (create a redistributable app)
|
||||
install(CODE "
|
||||
INCLUDE(BundleUtilities)
|
||||
SET(BU_CHMOD_BUNDLE_ITEMS ON)
|
||||
FIXUP_BUNDLE(${CMAKE_INSTALL_PREFIX}/MapEdit.app \"\" \"\")
|
||||
")
|
||||
ELSE()
|
||||
install(TARGETS MapEdit RUNTIME DESTINATION CorsixTH)
|
||||
ENDIF()
|
Before Width: | Height: | Size: 134 KiB |
@@ -1,34 +0,0 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.K.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_MAPEDIT ICON "MapEdit.ico"
|
||||
#endif // English (U.K.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
@@ -1,14 +0,0 @@
|
||||
# rsync compatible filter file which is used post-build
|
||||
# to help with copying the required resources into the
|
||||
# bundles for the Mac build.
|
||||
|
||||
- .svn
|
||||
- .DS_Store
|
||||
- CVS
|
||||
+ CorsixTH.lua
|
||||
+ Lua/
|
||||
+ Lua/**
|
||||
+ Bitmap/
|
||||
+ Bitmap/*.png
|
||||
+ Bitmap/aux_ui.*
|
||||
- *
|
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2009 Peter "Corsix" Cawley
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "app.h"
|
||||
//Darrell: This macro has to be called before the frmMain.h include otherwise
|
||||
//a subsequent SDL include causes main() to be replaced with SDLmain().
|
||||
IMPLEMENT_APP(ThemeHospitalMapEditApp)
|
||||
#include "frmMain.h"
|
||||
|
||||
bool ThemeHospitalMapEditApp::OnInit()
|
||||
{
|
||||
wxImage::AddHandler(new wxPNGHandler);
|
||||
wxTopLevelWindow *pForm = new frmMain;
|
||||
|
||||
pForm->Show(true);
|
||||
SetTopWindow(pForm);
|
||||
|
||||
return true;
|
||||
}
|
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2009 Peter "Corsix" Cawley
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
// For compilers that support precompilation, includes "wx/wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
// for all others, include the necessary headers (this file is usually all you
|
||||
// need because it includes almost all "standard" wxWidgets headers)
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif
|
||||
// ----------------------------
|
||||
#include <wx/glcanvas.h>
|
||||
#ifndef wxUSE_GLCANVAS
|
||||
#error To compile the map editor, wxWidgets must be compiled with OpenGL
|
||||
#endif
|
||||
|
||||
class ThemeHospitalMapEditApp : public wxGLApp
|
||||
{
|
||||
virtual bool OnInit();
|
||||
};
|
||||
|
||||
DECLARE_APP(ThemeHospitalMapEditApp)
|
@@ -1,286 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2009 Peter "Corsix" Cawley
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "block_gallery.h"
|
||||
#include <map>
|
||||
|
||||
BEGIN_EVENT_TABLE(RibbonBlockGallery, wxRibbonGallery)
|
||||
EVT_BUTTON(wxID_ANY, RibbonBlockGallery::OnExtButton)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
RibbonBlockGallery::RibbonBlockGallery(wxWindow* parent, wxWindowID id)
|
||||
: wxRibbonGallery(parent, id)
|
||||
{
|
||||
}
|
||||
|
||||
RibbonBlockGallery::~RibbonBlockGallery()
|
||||
{
|
||||
_clearCategories();
|
||||
}
|
||||
|
||||
#define FOREACH(container_t, itr_name, container_name) \
|
||||
for(container_t::iterator itr_name = container_name.begin(), \
|
||||
itr_name##_end = container_name.end(); itr_name != itr_name##_end; \
|
||||
++itr_name)
|
||||
|
||||
void RibbonBlockGallery::_clearCategories()
|
||||
{
|
||||
FOREACH(categorylist_t, itr, m_vCategories)
|
||||
{
|
||||
Unbind(wxEVT_COMMAND_MENU_SELECTED,
|
||||
&RibbonBlockGallery::OnToggleCategory, this, (**itr).iID);
|
||||
delete *itr;
|
||||
}
|
||||
m_vCategories.clear();
|
||||
}
|
||||
|
||||
void RibbonBlockGallery::Populate(THSpriteSheet *pBlocks,
|
||||
const char* sCategory,
|
||||
const char* sSubCategory,
|
||||
lua_State* L,
|
||||
int iInfoIndex)
|
||||
{
|
||||
m_vBlocks.clear();
|
||||
_clearCategories();
|
||||
typedef std::map<wxString, category_t*> category_map_t;
|
||||
category_map_t mapCategories;
|
||||
|
||||
// Extract relevant block information from Lua
|
||||
if(LUA_REGISTRYINDEX < iInfoIndex && iInfoIndex < 0)
|
||||
iInfoIndex = lua_gettop(L) + 1 + iInfoIndex;
|
||||
lua_pushstring(L, sCategory);
|
||||
int iCategoryIndex = lua_gettop(L);
|
||||
lua_pushstring(L, sSubCategory);
|
||||
lua_pushnil(L);
|
||||
int iBaseIndex = lua_gettop(L);
|
||||
while(lua_next(L, iInfoIndex) != 0)
|
||||
{
|
||||
lua_rawgeti(L, -1, 1);
|
||||
if(lua_equal(L, -1, iCategoryIndex))
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
lua_rawgeti(L, -1, 2);
|
||||
if(lua_equal(L, -1, iCategoryIndex + 1))
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
block_t oBlock;
|
||||
oBlock.iBlock = lua_tointeger(L, -2);
|
||||
oBlock.iBaseBlock = 0;
|
||||
wxString sCategory(L"Miscellaneous");
|
||||
lua_rawgeti(L, -1, 3);
|
||||
if(lua_type(L, -1) == LUA_TSTRING)
|
||||
sCategory = lua_tostring(L, -1);
|
||||
oBlock.pCategory = mapCategories[sCategory];
|
||||
if(oBlock.pCategory == NULL)
|
||||
{
|
||||
oBlock.pCategory = new category_t;
|
||||
oBlock.pCategory->bEnabled = true;
|
||||
oBlock.pCategory->sName = sCategory;
|
||||
oBlock.pCategory->iID = wxID_HIGHEST + 1 +
|
||||
mapCategories.size();
|
||||
Bind(wxEVT_COMMAND_MENU_SELECTED,
|
||||
&RibbonBlockGallery::OnToggleCategory, this,
|
||||
oBlock.pCategory->iID);
|
||||
mapCategories[sCategory] = oBlock.pCategory;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
lua_getfield(L, -1, "base");
|
||||
if(lua_type(L, -1) == LUA_TNUMBER)
|
||||
oBlock.iBaseBlock = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
m_vBlocks.push_back(oBlock);
|
||||
}
|
||||
}
|
||||
lua_settop(L, iBaseIndex);
|
||||
}
|
||||
lua_pop(L, 2);
|
||||
|
||||
FOREACH(category_map_t, itr, mapCategories)
|
||||
{
|
||||
m_vCategories.push_back(itr->second);
|
||||
}
|
||||
|
||||
// Load block bitmaps
|
||||
wxSize szLargestBitmap(0, 0);
|
||||
FOREACH(blocklist_t, itr, m_vBlocks)
|
||||
{
|
||||
unsigned int iWidth, iHeight;
|
||||
if(!pBlocks->getSpriteSize(itr->iBlock, &iWidth, &iHeight))
|
||||
continue;
|
||||
|
||||
wxImage imgBlock(iWidth, iHeight);
|
||||
if(!imgBlock.HasAlpha())
|
||||
imgBlock.InitAlpha();
|
||||
|
||||
pBlocks->wxDrawSprite(itr->iBlock, imgBlock.GetData(), imgBlock.GetAlpha());
|
||||
_trimImage(imgBlock);
|
||||
if(imgBlock.GetWidth() > szLargestBitmap.GetWidth())
|
||||
szLargestBitmap.SetWidth(imgBlock.GetWidth());
|
||||
if(imgBlock.GetHeight() > szLargestBitmap.GetHeight())
|
||||
szLargestBitmap.SetHeight(imgBlock.GetHeight());
|
||||
itr->bmpTrimmed = wxBitmap(imgBlock);
|
||||
}
|
||||
|
||||
// Make block bitmaps equally sized
|
||||
FOREACH(blocklist_t, itr, m_vBlocks)
|
||||
{
|
||||
if(itr->bmpTrimmed.IsOk() && itr->bmpTrimmed.GetSize() != szLargestBitmap)
|
||||
{
|
||||
wxImage imgBlock = itr->bmpTrimmed.ConvertToImage();
|
||||
_expandImage(imgBlock, szLargestBitmap);
|
||||
itr->bmpTrimmed = wxBitmap(imgBlock);
|
||||
}
|
||||
}
|
||||
|
||||
// Add blocks to gallery
|
||||
_repopulate();
|
||||
}
|
||||
|
||||
void RibbonBlockGallery::_repopulate()
|
||||
{
|
||||
Clear();
|
||||
FOREACH(blocklist_t, itr, m_vBlocks)
|
||||
{
|
||||
if(itr->pCategory->bEnabled && itr->bmpTrimmed.IsOk())
|
||||
{
|
||||
Append(itr->bmpTrimmed, itr->iBlock, (void*)&*itr);
|
||||
}
|
||||
}
|
||||
Realise();
|
||||
}
|
||||
|
||||
void RibbonBlockGallery::OnToggleCategory(wxCommandEvent& evt)
|
||||
{
|
||||
FOREACH(categorylist_t, itr, m_vCategories)
|
||||
{
|
||||
if((**itr).iID == evt.GetId())
|
||||
{
|
||||
(**itr).bEnabled = !(**itr).bEnabled;
|
||||
_repopulate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool RibbonBlockGallery::SelectAndMakeVisible(int iBlock)
|
||||
{
|
||||
unsigned int iCount = GetCount();
|
||||
for(unsigned int i = 0; i < iCount; ++i)
|
||||
{
|
||||
wxRibbonGalleryItem *pItem = GetItem(i);
|
||||
block_t *pBlock = reinterpret_cast<block_t*>(GetItemClientData(pItem));
|
||||
if(pBlock->iBlock == iBlock)
|
||||
{
|
||||
SetSelection(pItem);
|
||||
EnsureVisible(pItem);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
FOREACH(blocklist_t, itr, m_vBlocks)
|
||||
{
|
||||
if(itr->iBlock == iBlock && !itr->pCategory->bEnabled)
|
||||
{
|
||||
itr->pCategory->bEnabled = true;
|
||||
_repopulate();
|
||||
return SelectAndMakeVisible(iBlock);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int RibbonBlockGallery::GetBlock(wxRibbonGalleryItem* pItem, int* pBaseBlock)
|
||||
{
|
||||
block_t *pBlock = reinterpret_cast<block_t*>(GetItemClientData(pItem));
|
||||
if(pBaseBlock)
|
||||
*pBaseBlock = pBlock->iBaseBlock;
|
||||
return pBlock->iBlock;
|
||||
}
|
||||
|
||||
void RibbonBlockGallery::_trimImage(wxImage& image)
|
||||
{
|
||||
int iOpaqueTop = 0;
|
||||
int iOpaqueBottom = image.GetHeight() - 1;
|
||||
int iOpaqueLeft = 0;
|
||||
int iOpaqueRight = image.GetWidth() - 1;
|
||||
|
||||
for(; iOpaqueTop <= iOpaqueBottom; ++iOpaqueTop)
|
||||
{
|
||||
for(int iX = iOpaqueLeft; iX <= iOpaqueRight; ++iX)
|
||||
{
|
||||
if(!image.IsTransparent(iX, iOpaqueTop))
|
||||
goto break1;
|
||||
}
|
||||
}
|
||||
break1:;
|
||||
|
||||
for(; iOpaqueBottom >= iOpaqueTop; --iOpaqueBottom)
|
||||
{
|
||||
for(int iX = iOpaqueLeft; iX <= iOpaqueRight; ++iX)
|
||||
{
|
||||
if(!image.IsTransparent(iX, iOpaqueBottom))
|
||||
goto break2;
|
||||
}
|
||||
}
|
||||
break2:;
|
||||
|
||||
for(; iOpaqueLeft <= iOpaqueRight; ++iOpaqueLeft)
|
||||
{
|
||||
for(int iY = iOpaqueTop; iY <= iOpaqueBottom; ++iY)
|
||||
{
|
||||
if(!image.IsTransparent(iOpaqueLeft, iY))
|
||||
goto break3;
|
||||
}
|
||||
}
|
||||
break3:;
|
||||
|
||||
for(; iOpaqueRight >= iOpaqueLeft; --iOpaqueRight)
|
||||
{
|
||||
for(int iY = iOpaqueTop; iY <= iOpaqueBottom; ++iY)
|
||||
{
|
||||
if(!image.IsTransparent(iOpaqueRight, iY))
|
||||
goto break4;
|
||||
}
|
||||
}
|
||||
break4:;
|
||||
|
||||
image = image.Size(wxSize(iOpaqueRight - iOpaqueLeft + 1, iOpaqueBottom - iOpaqueTop + 1),
|
||||
wxPoint(-iOpaqueLeft, -iOpaqueTop));
|
||||
}
|
||||
|
||||
void RibbonBlockGallery::_expandImage(wxImage& image, wxSize size)
|
||||
{
|
||||
image = image.Size(size, wxPoint(
|
||||
(size.GetWidth() - image.GetWidth()) / 2,
|
||||
size.GetHeight() - image.GetHeight()
|
||||
));
|
||||
}
|
||||
|
||||
void RibbonBlockGallery::OnExtButton(wxCommandEvent& evt)
|
||||
{
|
||||
wxMenu mnCategories;
|
||||
FOREACH(categorylist_t, itr, m_vCategories)
|
||||
{
|
||||
mnCategories.AppendCheckItem((**itr).iID, (**itr).sName)
|
||||
->Check((**itr).bEnabled);
|
||||
}
|
||||
PopupMenu(&mnCategories);
|
||||
}
|
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2009 Peter "Corsix" Cawley
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
// For compilers that support precompilation, includes "wx/wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
// for all others, include the necessary headers (this file is usually all you
|
||||
// need because it includes almost all "standard" wxWidgets headers)
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif
|
||||
// ----------------------------
|
||||
#include <wx/ribbon/gallery.h>
|
||||
#include <vector>
|
||||
#include "game.h"
|
||||
|
||||
class RibbonBlockGallery : public wxRibbonGallery
|
||||
{
|
||||
public:
|
||||
RibbonBlockGallery(wxWindow* parent, wxWindowID id = wxID_ANY);
|
||||
~RibbonBlockGallery();
|
||||
|
||||
void Populate(THSpriteSheet *pBlocks, const char* sCategory,
|
||||
const char* sSubCategory, lua_State* L, int iInfoIndex);
|
||||
|
||||
bool SelectAndMakeVisible(int iBlock);
|
||||
|
||||
int GetBlock(wxRibbonGalleryItem* pItem, int* pBaseBlock);
|
||||
|
||||
void OnExtButton(wxCommandEvent& evt);
|
||||
void OnToggleCategory(wxCommandEvent& evt);
|
||||
|
||||
protected:
|
||||
struct category_t
|
||||
{
|
||||
wxString sName;
|
||||
bool bEnabled;
|
||||
int iID;
|
||||
};
|
||||
struct block_t
|
||||
{
|
||||
wxBitmap bmpTrimmed;
|
||||
category_t* pCategory;
|
||||
int iBlock;
|
||||
int iBaseBlock;
|
||||
};
|
||||
|
||||
// wxWidgets encourages use of wxArray over std::vector, but this isn't in
|
||||
// wxWidgets core (and never will be), so it doesn't matter ^_^
|
||||
typedef std::vector<block_t> blocklist_t;
|
||||
typedef std::vector<category_t*> categorylist_t;
|
||||
|
||||
blocklist_t m_vBlocks;
|
||||
categorylist_t m_vCategories;
|
||||
|
||||
void _trimImage(wxImage& image);
|
||||
void _expandImage(wxImage& image, wxSize size);
|
||||
void _clearCategories();
|
||||
void _repopulate();
|
||||
|
||||
DECLARE_EVENT_TABLE();
|
||||
};
|
@@ -1,448 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2009 Peter "Corsix" Cawley
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "frmMain.h"
|
||||
#include "../../CorsixTH/Src/main.h"
|
||||
|
||||
BEGIN_EVENT_TABLE(EmbeddedGamePanel, wxGLCanvas)
|
||||
EVT_MOTION(EmbeddedGamePanel::_onMouseMove)
|
||||
EVT_PAINT(EmbeddedGamePanel::_onPaint)
|
||||
EVT_LEFT_UP(EmbeddedGamePanel::_onLeftUp)
|
||||
EVT_LEFT_DOWN(EmbeddedGamePanel::_onLeftDown)
|
||||
EVT_MIDDLE_UP(EmbeddedGamePanel::_onMiddleUp)
|
||||
EVT_MIDDLE_DOWN(EmbeddedGamePanel::_onMiddleDown)
|
||||
EVT_RIGHT_UP(EmbeddedGamePanel::_onRightUp)
|
||||
EVT_RIGHT_DOWN(EmbeddedGamePanel::_onRightDown)
|
||||
EVT_LEFT_DCLICK(EmbeddedGamePanel::_onLeftDoubleClick)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
IEmbeddedGamePanel::~IEmbeddedGamePanel()
|
||||
{
|
||||
}
|
||||
|
||||
EmbeddedGamePanel::EmbeddedGamePanel(wxWindow *pParent)
|
||||
: wxGLCanvas(pParent, wxID_ANY, NULL, wxDefaultPosition,
|
||||
wxDefaultSize, 0, wxGLCanvasName, wxNullPalette)
|
||||
, m_pGLCanvas(NULL)
|
||||
, m_pGLContext(NULL)
|
||||
, m_pPrintTarget(NULL)
|
||||
, m_L(NULL)
|
||||
, m_Lthread(NULL)
|
||||
, m_fnExtraLuaInit(NULL)
|
||||
, m_pExtraLuaInitArg(NULL)
|
||||
{
|
||||
m_pGLCanvas = this;
|
||||
m_pGLContext = new wxGLContext(m_pGLCanvas);
|
||||
}
|
||||
|
||||
EmbeddedGamePanel::~EmbeddedGamePanel()
|
||||
{
|
||||
if(m_L)
|
||||
lua_close(m_L);
|
||||
delete m_pGLContext;
|
||||
}
|
||||
|
||||
void EmbeddedGamePanel::setExtraLuaInitFunction(lua_CFunction fn, void* arg)
|
||||
{
|
||||
m_fnExtraLuaInit = fn;
|
||||
m_pExtraLuaInitArg = arg;
|
||||
}
|
||||
|
||||
void EmbeddedGamePanel::setLogWindow(frmLog *pLogWindow)
|
||||
{
|
||||
m_pPrintTarget = pLogWindow->getTextControl();
|
||||
}
|
||||
|
||||
THMap* EmbeddedGamePanel::getMap()
|
||||
{
|
||||
THMap *pMap = NULL;
|
||||
int iTop = lua_gettop(m_L);
|
||||
lua_checkstack(m_L, 5);
|
||||
lua_getglobal(m_L, "TheApp");
|
||||
if(!lua_isnil(m_L, -1))
|
||||
{
|
||||
lua_getfield(m_L, -1, "map");
|
||||
if(!lua_isnil(m_L, -1))
|
||||
{
|
||||
lua_getfield(m_L, -1, "th");
|
||||
pMap = reinterpret_cast<THMap*>(lua_touserdata(m_L, -1));
|
||||
}
|
||||
}
|
||||
lua_settop(m_L, iTop);
|
||||
return pMap;
|
||||
}
|
||||
|
||||
bool EmbeddedGamePanel::loadLua()
|
||||
{
|
||||
// Create state
|
||||
m_L = luaL_newstate();
|
||||
lua_atpanic(m_L, _l_panic);
|
||||
|
||||
// Save a pointer to ourselves in the registry
|
||||
lua_pushliteral(m_L, "wxWindow");
|
||||
lua_pushlightuserdata(m_L, reinterpret_cast<wxWindow*>(this));
|
||||
lua_settable(m_L, LUA_REGISTRYINDEX);
|
||||
|
||||
// Open default libraries, and override appropriate bits
|
||||
luaL_openlibs(m_L);
|
||||
luaT_execute(m_L, "print = ...", _l_print);
|
||||
|
||||
// Set _MAP_EDITOR to true, to allow scripts to notice that they are
|
||||
// running inside this component, rather than standalone.
|
||||
luaT_execute(m_L, "_MAP_EDITOR = true");
|
||||
|
||||
// Load CorsixTH.lua and perform other initialisation needed by it
|
||||
lua_settop(m_L, 0);
|
||||
lua_pushcfunction(m_L, CorsixTH_lua_stacktrace);
|
||||
lua_pushcfunction(m_L, CorsixTH_lua_main_no_eval);
|
||||
lua_checkstack(m_L, wxTheApp->argc);
|
||||
for(int i = 0; i < wxTheApp->argc; ++ i)
|
||||
lua_pushstring(m_L, wxTheApp->argv[i]);
|
||||
if(lua_pcall(m_L, wxTheApp->argc, 1, 1))
|
||||
{
|
||||
if(m_pPrintTarget)
|
||||
{
|
||||
m_pPrintTarget->AppendText(L"Error initialising Lua: ");
|
||||
m_pPrintTarget->AppendText(lua_tostring(m_L, -1));
|
||||
m_pPrintTarget->AppendText(L"\n");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// NB: CorsixTH_lua_main_no_eval will have loaded CorsixTH.lua and left it
|
||||
// as the top value on the stack, but will not have executed it.
|
||||
// The stack will hence have two things on it: the stacktrace function,
|
||||
// and the loaded CorsixTH.lua
|
||||
|
||||
// Overwrite what CorsixTH_lua_main_no_eval registered for require("sdl")
|
||||
// with our own function that uses wxWidgets to do what SDL would have.
|
||||
luaT_execute(m_L, "package.preload.sdl = ...", _l_open_sdl);
|
||||
|
||||
// Replace the Surface:endFrame() function with our own
|
||||
lua_getglobal(m_L, "require");
|
||||
lua_pushliteral(m_L, "TH");
|
||||
lua_call(m_L, 1, 1);
|
||||
lua_getfield(m_L, -1, "surface");
|
||||
lua_getfield(m_L, -1, "endFrame");
|
||||
lua_pushcclosure(m_L, _l_end_frame, 1);
|
||||
lua_setfield(m_L, -2, "endFrame");
|
||||
lua_pop(m_L, 2);
|
||||
|
||||
// Perform extra initialisation
|
||||
if(m_fnExtraLuaInit)
|
||||
{
|
||||
if(lua_cpcall(m_L, m_fnExtraLuaInit, m_pExtraLuaInitArg) != 0)
|
||||
lua_pop(m_L, 1);
|
||||
}
|
||||
|
||||
// Execute CorsixTH.lua in a coroutine
|
||||
lua_getglobal(m_L, "coroutine");
|
||||
lua_getfield(m_L, -1, "create");
|
||||
lua_replace(m_L, -2);
|
||||
lua_insert(m_L, -2);
|
||||
lua_call(m_L, 1, 1);
|
||||
lua_State *L = lua_tothread(m_L, -1);
|
||||
if(lua_resume(L, 0) != LUA_YIELD)
|
||||
{
|
||||
if(m_pPrintTarget)
|
||||
{
|
||||
// Push debug.traceback onto m_L
|
||||
lua_getglobal(m_L, "debug");
|
||||
lua_getfield(m_L, -1, "traceback");
|
||||
lua_replace(m_L, -2);
|
||||
// Push the thread onto m_L
|
||||
lua_pushvalue(m_L, -2);
|
||||
// Push tostring(errmsg) onto m_L
|
||||
lua_getglobal(m_L, "tostring");
|
||||
lua_xmove(L, m_L, 1);
|
||||
lua_call(m_L, 1, 1);
|
||||
// Push constant 1 onto m_L
|
||||
lua_pushinteger(m_L, 1);
|
||||
// Call debug.traceback(thread, tostring(err), 1)
|
||||
lua_call(m_L, 3, 1);
|
||||
// Display resulting string and pop it
|
||||
m_pPrintTarget->AppendText(L"Error initialising Lua: ");
|
||||
m_pPrintTarget->AppendText(lua_tostring(m_L, -1));
|
||||
m_pPrintTarget->AppendText(L"\n");
|
||||
lua_pop(m_L, 1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
lua_settop(L, 1);
|
||||
m_Lthread = L;
|
||||
|
||||
// The stack of the Lua states is now as follows:
|
||||
// m_L: stacktrace function, m_Lthread <top
|
||||
// m_Lthread: event dispatch coroutine <top
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EmbeddedGamePanel::_resume(lua_State *L, int iNArgs, int iNRes)
|
||||
{
|
||||
// L will be an event handling coroutine.
|
||||
// Start by sending the event to the coroutine by resuming it with the
|
||||
// event arguments.
|
||||
bool bGood = true;
|
||||
if(lua_resume(L, iNArgs) != LUA_YIELD)
|
||||
{
|
||||
// Error occurred during event processing.
|
||||
bGood = false;
|
||||
// Transfer the error details to m_Lthread
|
||||
int iNTransfer = lua_gettop(L);
|
||||
if(lua_status(L) >= LUA_ERRRUN)
|
||||
iNTransfer = 1;
|
||||
lua_checkstack(m_Lthread, iNTransfer);
|
||||
lua_xmove(L, m_Lthread, iNTransfer);
|
||||
lua_settop(L, 0);
|
||||
// Allow m_Lthread to respond to the error in an appropriate way
|
||||
lua_resume(m_Lthread, iNTransfer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Event processed without errors, and will have returned true if
|
||||
// a redraw needs to occur.
|
||||
if(lua_toboolean(L, -1) != 0)
|
||||
{
|
||||
Refresh(false);
|
||||
}
|
||||
}
|
||||
// Leave L with the desired number of return values.
|
||||
lua_settop(L, iNRes);
|
||||
return bGood;
|
||||
}
|
||||
|
||||
void EmbeddedGamePanel::_onMouseMove(wxMouseEvent& evt)
|
||||
{
|
||||
// Keep track of relative mouse movements as well as absolute
|
||||
wxPoint ptNew = evt.GetPosition();
|
||||
wxPoint ptDelta = ptNew - m_ptMouse;
|
||||
m_ptMouse = ptNew;
|
||||
|
||||
_dispatchEvent("motion", ptNew.x, ptNew.y, ptDelta.x, ptDelta.y);
|
||||
}
|
||||
|
||||
void EmbeddedGamePanel::_onLeftUp(wxMouseEvent& evt)
|
||||
{
|
||||
_dispatchEvent("buttonup", SDL_BUTTON_LEFT, evt.GetX(), evt.GetY());
|
||||
}
|
||||
|
||||
void EmbeddedGamePanel::_onLeftDown(wxMouseEvent& evt)
|
||||
{
|
||||
_dispatchEvent("buttondown", SDL_BUTTON_LEFT, evt.GetX(), evt.GetY());
|
||||
}
|
||||
|
||||
void EmbeddedGamePanel::_onLeftDoubleClick(wxMouseEvent& evt)
|
||||
{
|
||||
_dispatchEvent("buttondown", "left_double", evt.GetX(), evt.GetY());
|
||||
}
|
||||
|
||||
void EmbeddedGamePanel::_onRightUp(wxMouseEvent& evt)
|
||||
{
|
||||
_dispatchEvent("buttonup", SDL_BUTTON_RIGHT, evt.GetX(), evt.GetY());
|
||||
}
|
||||
|
||||
void EmbeddedGamePanel::_onRightDown(wxMouseEvent& evt)
|
||||
{
|
||||
_dispatchEvent("buttondown", SDL_BUTTON_RIGHT, evt.GetX(), evt.GetY());
|
||||
}
|
||||
|
||||
void EmbeddedGamePanel::_onMiddleUp(wxMouseEvent& evt)
|
||||
{
|
||||
_dispatchEvent("buttonup", SDL_BUTTON_MIDDLE, evt.GetX(), evt.GetY());
|
||||
}
|
||||
|
||||
void EmbeddedGamePanel::_onMiddleDown(wxMouseEvent& evt)
|
||||
{
|
||||
_dispatchEvent("buttondown", SDL_BUTTON_MIDDLE, evt.GetX(), evt.GetY());
|
||||
}
|
||||
|
||||
void EmbeddedGamePanel::_onPaint(wxPaintEvent& evt)
|
||||
{
|
||||
wxPaintDC dc(this);
|
||||
m_pGLContext->SetCurrent(*m_pGLCanvas);
|
||||
|
||||
if(m_L == NULL)
|
||||
{
|
||||
// Its rather hacky to be loading the Lua side of things from within
|
||||
// the paint handler, but Lua needs an OpenGL context to be active, and
|
||||
// we cannot give it one during the EmbeddedGamePanel constructor.
|
||||
loadLua();
|
||||
}
|
||||
|
||||
// Update the OpenGL projection matrix and Lua window size settings to keep
|
||||
// a 1:1 mapping between world space and screen space
|
||||
const wxSize szClient = GetClientSize();
|
||||
glViewport(0, 0, szClient.x, szClient.y);
|
||||
GLdouble fWidth = (GLdouble)szClient.x;
|
||||
GLdouble fHeight = (GLdouble)szClient.y;
|
||||
THRenderTarget::setGLProjection(fWidth, fHeight);
|
||||
if(m_L)
|
||||
{
|
||||
lua_getglobal(m_L, "TheApp");
|
||||
if(lua_isnil(m_L, -1))
|
||||
lua_pop(m_L, 1);
|
||||
else
|
||||
{
|
||||
lua_getfield(m_L, -1, "config");
|
||||
lua_pushinteger(m_L, szClient.x);
|
||||
lua_setfield(m_L, -2, "width");
|
||||
lua_pushinteger(m_L, szClient.y);
|
||||
lua_setfield(m_L, -2, "height");
|
||||
lua_pop(m_L, 2);
|
||||
}
|
||||
}
|
||||
|
||||
// Do the actual painting
|
||||
if(m_Lthread)
|
||||
{
|
||||
lua_State *L = lua_tothread(m_Lthread, 1);
|
||||
if(L == NULL)
|
||||
{
|
||||
for(int i = 1; i <= lua_gettop(m_L); ++i)
|
||||
{
|
||||
wxPrintf("m_L stack %i: %s\n", i, lua_typename(m_L, lua_type(m_L, i)));
|
||||
}
|
||||
for(int i = 1; i <= lua_gettop(m_Lthread); ++i)
|
||||
{
|
||||
wxPrintf("m_Lthread stack %i: %s\n", i, lua_typename(m_Lthread, lua_type(m_Lthread, i)));
|
||||
}
|
||||
}
|
||||
lua_pushliteral(L, "frame");
|
||||
_resume(L, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
EmbeddedGamePanel* EmbeddedGamePanel::_getThis(lua_State *L)
|
||||
{
|
||||
lua_pushliteral(L, "wxWindow");
|
||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||
EmbeddedGamePanel *pThis = reinterpret_cast<EmbeddedGamePanel*>(
|
||||
reinterpret_cast<wxWindow*>(lua_touserdata(L, -1)));
|
||||
lua_pop(L, 1);
|
||||
return pThis;
|
||||
}
|
||||
|
||||
int EmbeddedGamePanel::_l_print(lua_State *L)
|
||||
{
|
||||
EmbeddedGamePanel *pThis = _getThis(L);
|
||||
if(pThis->m_pPrintTarget)
|
||||
{
|
||||
int iCount = lua_gettop(L);
|
||||
lua_getglobal(L, "tostring");
|
||||
for(int iArg = 1; iArg <= iCount; ++iArg)
|
||||
{
|
||||
lua_pushvalue(L, -1);
|
||||
lua_pushvalue(L, iArg);
|
||||
lua_call(L, 1, 1);
|
||||
pThis->m_pPrintTarget->AppendText(lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
if(iArg != iCount)
|
||||
pThis->m_pPrintTarget->AppendText(L"\t");
|
||||
}
|
||||
pThis->m_pPrintTarget->AppendText(L"\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EmbeddedGamePanel::_l_panic(lua_State *L)
|
||||
{
|
||||
const char *sMessage = lua_tostring(L, -1);
|
||||
::wxMessageBox(wxString(L"Lua Panic!\n") + wxString(sMessage ? sMessage : ""),
|
||||
wxString(L"Lua Panic"), wxOK | wxICON_ERROR | wxCENTRE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EmbeddedGamePanel::_l_end_frame(lua_State *L)
|
||||
{
|
||||
// Call the original Surface:endFrame() function
|
||||
lua_pushvalue(L, lua_upvalueindex(1));
|
||||
lua_insert(L, 1);
|
||||
lua_call(L, lua_gettop(L) - 1, LUA_MULTRET);
|
||||
|
||||
// Update the display
|
||||
EmbeddedGamePanel *pThis = _getThis(L);
|
||||
pThis->m_pGLCanvas->SwapBuffers();
|
||||
|
||||
// Return whatever the original returned
|
||||
return lua_gettop(L);
|
||||
}
|
||||
|
||||
static int l_init(lua_State *L)
|
||||
{
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_get_fps(lua_State *L)
|
||||
{
|
||||
lua_pushnumber(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_nop(lua_State *L)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_get_ticks(lua_State *L)
|
||||
{
|
||||
// Not the same as the game's sdl.getTicks(), but it is sufficient for the
|
||||
// purpose (initialising the random number generator).
|
||||
lua_pushnumber(L, ::wxGetLocalTime());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct luaL_reg sdllib[] = {
|
||||
{"init", l_init},
|
||||
//{"mainloop", coroutine.yield},
|
||||
{"getFPS", l_get_fps},
|
||||
{"trackFPS", l_nop},
|
||||
{"limitFPS", l_nop},
|
||||
{"modifyKeyboardRepeat", l_nop},
|
||||
{"getTicks", l_get_ticks},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
static const struct luaL_reg sdl_wmlib[] = {
|
||||
{"setIconWin32", l_nop},
|
||||
{"setCaption", l_nop},
|
||||
{"showCursor", l_nop},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
int EmbeddedGamePanel::_l_open_sdl(lua_State *L)
|
||||
{
|
||||
luaL_register(L, "sdl", sdllib);
|
||||
lua_getglobal(L, "coroutine");
|
||||
lua_getfield(L, -1, "yield");
|
||||
lua_setfield(L, -3, "mainloop");
|
||||
lua_pop(L, 1);
|
||||
lua_newtable(L);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, -3, "wm");
|
||||
luaL_register(L, NULL, sdl_wmlib);
|
||||
lua_pop(L, 1);
|
||||
lua_newtable(L);
|
||||
lua_pushboolean(L, 0);
|
||||
lua_setfield(L, -2, "loaded");
|
||||
lua_setfield(L, -2, "audio");
|
||||
return 1;
|
||||
}
|
@@ -1,146 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2009 Peter "Corsix" Cawley
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
// For compilers that support precompilation, includes "wx/wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
// for all others, include the necessary headers (this file is usually all you
|
||||
// need because it includes almost all "standard" wxWidgets headers)
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif
|
||||
// ----------------------------
|
||||
#include <wx/glcanvas.h>
|
||||
#include "game.h"
|
||||
#include "frmLog.h"
|
||||
|
||||
class IEmbeddedGamePanel
|
||||
{
|
||||
public:
|
||||
virtual ~IEmbeddedGamePanel();
|
||||
|
||||
virtual void setExtraLuaInitFunction(lua_CFunction fn, void* arg) = 0;
|
||||
virtual void setLogWindow(frmLog *pLogWindow) = 0;
|
||||
virtual bool loadLua() = 0;
|
||||
|
||||
virtual lua_State* getLua() = 0;
|
||||
virtual THMap* getMap() = 0;
|
||||
};
|
||||
|
||||
//! GUI component which acts as an instance of CorsixTH
|
||||
/*!
|
||||
The component contains a Lua instance which executes the normal CorsixTH
|
||||
Lua scripts. Mouse and keyboard events to the component are forwarded to
|
||||
said Lua instance in the same way as they are for a standalone CorsixTH
|
||||
instance, and the visual representation of the component is what would
|
||||
normally get displayed in a standalone CorsixTH window.
|
||||
|
||||
Lua scripts can tell if they are being executed from within this, as the
|
||||
global variable _MAP_EDITOR will be set to true.
|
||||
*/
|
||||
class EmbeddedGamePanel : public wxGLCanvas, public IEmbeddedGamePanel
|
||||
{
|
||||
public:
|
||||
EmbeddedGamePanel(wxWindow *pParent);
|
||||
~EmbeddedGamePanel();
|
||||
|
||||
void setExtraLuaInitFunction(lua_CFunction fn, void* arg);
|
||||
void setLogWindow(frmLog *pLogWindow);
|
||||
bool loadLua();
|
||||
|
||||
lua_State* getLua() {return m_L;}
|
||||
THMap* getMap();
|
||||
|
||||
protected:
|
||||
// OpenGL rendering stuff
|
||||
wxGLCanvas* m_pGLCanvas;
|
||||
wxGLContext* m_pGLContext;
|
||||
|
||||
//! A text control which is used for the output of print() calls
|
||||
wxTextCtrl* m_pPrintTarget;
|
||||
//! The top-level Lua instance
|
||||
lua_State* m_L;
|
||||
//! A substate of m_L which is used for executing the CorsixTH instance,
|
||||
// as this allows the execution to yield and resume "asynchronously".
|
||||
lua_State* m_Lthread;
|
||||
//! A user-supplied function to be called during Lua initialisation.
|
||||
lua_CFunction m_fnExtraLuaInit;
|
||||
//! An argument to m_fnExtraLuaInit, delivered as a light userdata.
|
||||
void* m_pExtraLuaInitArg;
|
||||
//! The last recorded position of the mouse cursor - used to calculate
|
||||
// the difference in position each time the mouse is moved.
|
||||
wxPoint m_ptMouse;
|
||||
|
||||
static int _l_print(lua_State *L);
|
||||
static int _l_panic(lua_State *L);
|
||||
static int _l_open_sdl(lua_State *L);
|
||||
static int _l_end_frame(lua_State *L);
|
||||
static EmbeddedGamePanel* _getThis(lua_State *L);
|
||||
|
||||
void _onPaint(wxPaintEvent& evt);
|
||||
void _onMouseMove(wxMouseEvent& evt);
|
||||
void _onLeftUp(wxMouseEvent& evt);
|
||||
void _onLeftDown(wxMouseEvent& evt);
|
||||
void _onLeftDoubleClick(wxMouseEvent& evt);
|
||||
void _onRightUp(wxMouseEvent& evt);
|
||||
void _onRightDown(wxMouseEvent& evt);
|
||||
void _onMiddleUp(wxMouseEvent& evt);
|
||||
void _onMiddleDown(wxMouseEvent& evt);
|
||||
|
||||
template <typename T1, typename T2, typename T3>
|
||||
void _dispatchEvent(const char* sName, T1 a1, T2 a2, T3 a3)
|
||||
{
|
||||
if(m_Lthread)
|
||||
{
|
||||
lua_State *L = lua_tothread(m_Lthread, 1);
|
||||
lua_pushstring(L, sName);
|
||||
luaT_push(L, a1);
|
||||
luaT_push(L, a2);
|
||||
luaT_push(L, a3);
|
||||
_resume(L, 4, 0);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
void _dispatchEvent(const char* sName, T1 a1, T2 a2, T3 a3, T4 a4)
|
||||
{
|
||||
if(m_Lthread)
|
||||
{
|
||||
lua_State *L = lua_tothread(m_Lthread, 1);
|
||||
lua_pushstring(L, sName);
|
||||
luaT_push(L, a1);
|
||||
luaT_push(L, a2);
|
||||
luaT_push(L, a3);
|
||||
luaT_push(L, a4);
|
||||
_resume(L, 5, 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool _resume(lua_State *L, int iNArgs, int iNRes);
|
||||
|
||||
DECLARE_EVENT_TABLE();
|
||||
};
|
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2009 Peter "Corsix" Cawley
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "frmLog.h"
|
||||
|
||||
BEGIN_EVENT_TABLE(frmLog, wxFrame)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
frmLog::frmLog()
|
||||
: wxFrame(NULL, wxID_ANY, L"CorsixTH Lua Log Window", wxDefaultPosition,
|
||||
wxSize(400, 480), wxCAPTION | wxRESIZE_BORDER)
|
||||
{
|
||||
m_pTextCtrl = new wxTextCtrl(this, wxID_ANY, L"", wxDefaultPosition,
|
||||
wxDefaultSize, wxTE_READONLY | wxTE_MULTILINE);
|
||||
|
||||
wxSizer *pTopSizer = new wxBoxSizer(wxVERTICAL);
|
||||
pTopSizer->Add(m_pTextCtrl, 1, wxEXPAND);
|
||||
SetSizer(pTopSizer);
|
||||
|
||||
Show();
|
||||
}
|
||||
|
||||
frmLog::~frmLog()
|
||||
{
|
||||
}
|
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2009 Peter "Corsix" Cawley
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
// For compilers that support precompilation, includes "wx/wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
// for all others, include the necessary headers (this file is usually all you
|
||||
// need because it includes almost all "standard" wxWidgets headers)
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif
|
||||
// ----------------------------
|
||||
|
||||
class frmLog : public wxFrame
|
||||
{
|
||||
public:
|
||||
frmLog();
|
||||
~frmLog();
|
||||
|
||||
wxTextCtrl* getTextControl() {return m_pTextCtrl;}
|
||||
|
||||
protected:
|
||||
wxTextCtrl* m_pTextCtrl;
|
||||
|
||||
DECLARE_EVENT_TABLE();
|
||||
};
|
@@ -1,761 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2009 Peter "Corsix" Cawley
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "frmMain.h"
|
||||
#include "th_map_wrapper.h"
|
||||
#include <wx/file.h>
|
||||
#include <wx/filename.h>
|
||||
|
||||
BEGIN_EVENT_TABLE(frmMain, wxFrame)
|
||||
EVT_RIBBONBAR_PAGE_CHANGED(wxID_ANY, frmMain::_onRibbonPageChanged)
|
||||
EVT_RIBBONGALLERY_SELECTED(ID_GALLERY_FLOOR1, frmMain::_onFloorGallery1Select)
|
||||
EVT_RIBBONGALLERY_SELECTED(ID_GALLERY_FLOOR2, frmMain::_onFloorGallery2Select)
|
||||
EVT_RIBBONGALLERY_SELECTED(ID_GALLERY_WALL1, frmMain::_onWallGallery1Select)
|
||||
EVT_RIBBONGALLERY_SELECTED(ID_GALLERY_WALL2, frmMain::_onWallGallery2Select)
|
||||
EVT_RIBBONGALLERY_SELECTED(ID_GALLERY_PARCELS, frmMain::_onParcelGallerySelect)
|
||||
EVT_RIBBONBUTTONBAR_CLICKED(wxID_NEW, frmMain::_onNew)
|
||||
EVT_RIBBONBUTTONBAR_CLICKED(wxID_OPEN, frmMain::_onOpen)
|
||||
EVT_RIBBONBUTTONBAR_CLICKED(wxID_SAVE, frmMain::_onSave)
|
||||
EVT_RIBBONBUTTONBAR_CLICKED(wxID_UNDO, frmMain::_onUndo)
|
||||
EVT_RIBBONBUTTONBAR_CLICKED(wxID_REDO, frmMain::_onRedo)
|
||||
EVT_RIBBONBUTTONBAR_DROPDOWN_CLICKED(wxID_SAVE, frmMain::_onSaveMenu)
|
||||
EVT_MENU(ID_SAVE_IN_DROPDOWN, frmMain::_onSaveMenuSave)
|
||||
EVT_MENU(ID_SAVEAS, frmMain::_onSaveMenuSaveAs)
|
||||
EVT_RIBBONBUTTONBAR_CLICKED(ID_VIEW_WALLS, frmMain::_onViewWalls)
|
||||
EVT_RIBBONBUTTONBAR_CLICKED(ID_VIEW_FLAGS, frmMain::_onViewFlags)
|
||||
EVT_RIBBONBUTTONBAR_CLICKED(ID_VIEW_PARCELS, frmMain::_onViewParcels)
|
||||
EVT_RIBBONBUTTONBAR_CLICKED(ID_VIEW_POSITIONS, frmMain::_onViewPositions)
|
||||
EVT_SIZE(frmMain::_onResize)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
frmMain::frmMain()
|
||||
: wxFrame(NULL, wxID_ANY, L"CorsixTH Map Editor",
|
||||
wxDefaultPosition, wxSize(800, 600))
|
||||
{
|
||||
m_sFrameCaption = wxFrame::GetTitle();
|
||||
_setFilename(wxEmptyString);
|
||||
|
||||
wxSizer *pMainSizer = new wxBoxSizer(wxVERTICAL);
|
||||
wxSplitterWindow* pSplitter = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3D);
|
||||
pSplitter->SetMinimumPaneSize(250);
|
||||
wxPanel *pLeftPanel = new wxPanel(pSplitter, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||
wxPanel *pRightPanel = new wxPanel(pSplitter, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||
wxSizer *pLeftSizer = new wxBoxSizer(wxVERTICAL);
|
||||
wxSizer *pRightSizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_pRibbon = new wxRibbonBar(pLeftPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxRIBBON_BAR_FLOW_VERTICAL | wxRIBBON_BAR_SHOW_PAGE_LABELS);
|
||||
m_pRibbon->SetArtProvider(new wxRibbonMSWArtProvider);
|
||||
m_pRibbon->SetTabCtrlMargins(0, 0);
|
||||
m_pHomePage = new wxRibbonPage(m_pRibbon, wxID_ANY, L"Home");
|
||||
wxRibbonPage* pFloorPage = new wxRibbonPage(m_pRibbon, wxID_ANY, L"Floors");
|
||||
wxRibbonPanel* pFloorSimplePanel = new wxRibbonPanel(pFloorPage, wxID_ANY, L"Simple Tiles");
|
||||
m_pFloorGallery1 = new RibbonBlockGallery(pFloorSimplePanel, ID_GALLERY_FLOOR1);
|
||||
wxRibbonPanel* pFloorDecoratedPanel = new wxRibbonPanel(pFloorPage, wxID_ANY, L"Decorated Tiles");
|
||||
m_pFloorGallery2 = new RibbonBlockGallery(pFloorDecoratedPanel, ID_GALLERY_FLOOR2);
|
||||
wxRibbonPage* pWallPage = new wxRibbonPage(m_pRibbon, wxID_ANY, L"Walls");
|
||||
wxRibbonPanel* pWallWestPanel = new wxRibbonPanel(pWallPage, wxID_ANY, L"West");
|
||||
m_pWallGallery1 = new RibbonBlockGallery(pWallWestPanel, ID_GALLERY_WALL1);
|
||||
wxRibbonPanel* pWallNorthPanel = new wxRibbonPanel(pWallPage, wxID_ANY, L"North");
|
||||
m_pWallGallery2 = new RibbonBlockGallery(pWallNorthPanel, ID_GALLERY_WALL2);
|
||||
m_pRibbon->Realize();
|
||||
|
||||
m_pGamePanel = new ScrollableGamePanel(pRightPanel);
|
||||
m_pGamePanel->setExtraLuaInitFunction(_l_init, this);
|
||||
m_pGamePanel->setLogWindow(m_pLogWindow = new frmLog);
|
||||
wxPoint ptLogWindow = GetPosition();
|
||||
ptLogWindow.x += GetSize().GetWidth();
|
||||
m_pLogWindow->SetPosition(ptLogWindow);
|
||||
|
||||
pLeftSizer->Add(m_pRibbon, 1, wxALL | wxEXPAND);
|
||||
pRightSizer->Add(m_pGamePanel, 1, wxALL | wxEXPAND);
|
||||
pLeftPanel->SetSizer(pLeftSizer);
|
||||
pRightPanel->SetSizer(pRightSizer);
|
||||
pSplitter->SplitVertically(pLeftPanel,pRightPanel);
|
||||
pSplitter->SetSashPosition(250);
|
||||
pMainSizer->Add(pSplitter, 1, wxEXPAND);
|
||||
|
||||
SetSizer(pMainSizer);
|
||||
}
|
||||
|
||||
void frmMain::_setFilename(const wxString& sFilename)
|
||||
{
|
||||
m_sFilename = sFilename;
|
||||
wxString sShortName("Untitled");
|
||||
wxFileName oFilename(sFilename);
|
||||
if(!oFilename.GetFullName().empty())
|
||||
sShortName = oFilename.GetFullName();
|
||||
SetTitle(m_sFrameCaption + wxT(" - ") + sShortName);
|
||||
}
|
||||
|
||||
frmMain::~frmMain()
|
||||
{
|
||||
m_pLogWindow->Close();
|
||||
}
|
||||
|
||||
void frmMain::_onRibbonPageChanged(wxRibbonBarEvent& evt)
|
||||
{
|
||||
switch(m_pRibbon->GetActivePage())
|
||||
{
|
||||
case 0:
|
||||
if(m_bViewParcels)
|
||||
_setLuaParcelBrush(m_iParcelBrush);
|
||||
break;
|
||||
case 1:
|
||||
_setLuaBlockBrushFloorTab();
|
||||
break;
|
||||
case 2:
|
||||
_setLuaBlockBrushWallsTab();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct do_load_level_t
|
||||
{
|
||||
const char* sData;
|
||||
size_t iLength;
|
||||
frmMain* pThis;
|
||||
};
|
||||
|
||||
void frmMain::_onNew(wxRibbonButtonBarEvent& evt)
|
||||
{
|
||||
do_load_level_t oParams = {NULL, 0, this};
|
||||
lua_State* L = m_pGamePanel->getLua();
|
||||
if(lua_cpcall(L, _l_do_load, reinterpret_cast<void*>(&oParams)) != 0)
|
||||
lua_pop(L, 1);
|
||||
_setFilename(wxEmptyString);
|
||||
m_pGamePanel->Refresh();
|
||||
}
|
||||
|
||||
wxString frmMain::_getMapsDirectory()
|
||||
{
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
wxString frmMain::_getMapsFilter()
|
||||
{
|
||||
wxString sFilter = wxT("Theme Hospital maps (*.L[0-9]+)|");
|
||||
// *.L[0-9]* isn't quite the right filter, but it is as close as reasonably
|
||||
// possible to *.L[0-9]+ which file filters can reasonably get
|
||||
wxString sTHMapEndings = wxT("");
|
||||
char cSep = ';';
|
||||
for(int i = 0; i < 10; ++i)
|
||||
{
|
||||
if(i == 9) cSep = '|';
|
||||
sTHMapEndings += wxString::Format(L"*.L%i*%c", i, cSep);
|
||||
}
|
||||
sFilter += sTHMapEndings;
|
||||
sFilter += wxT("CorsixTH maps (*.map)|*.map|");
|
||||
sFilter += wxT("All maps (*.map, *.L[0-9]+)|*.map;");
|
||||
sFilter += sTHMapEndings;
|
||||
sFilter += wxT("All files (*.*)|*.*");
|
||||
return sFilter;
|
||||
}
|
||||
|
||||
void frmMain::_onOpen(wxRibbonButtonBarEvent& evt)
|
||||
{
|
||||
wxString sDirectory = _getMapsDirectory();
|
||||
wxString sFilter = _getMapsFilter();
|
||||
wxFileDialog oOpenDialog(this, wxFileSelectorPromptStr, sDirectory,
|
||||
wxEmptyString, sFilter, wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
||||
oOpenDialog.SetFilterIndex(2);
|
||||
if(oOpenDialog.ShowModal() != wxID_OK)
|
||||
return;
|
||||
wxFile fFile;
|
||||
if(!fFile.Open(oOpenDialog.GetPath()))
|
||||
return;
|
||||
size_t iLength = static_cast<size_t>(fFile.Length());
|
||||
char* sData = new (std::nothrow) char[iLength];
|
||||
if(!sData)
|
||||
return;
|
||||
if(fFile.Read(sData, iLength) != iLength)
|
||||
{
|
||||
delete[] sData;
|
||||
return;
|
||||
}
|
||||
do_load_level_t oParams = {sData, iLength, this};
|
||||
lua_State* L = m_pGamePanel->getLua();
|
||||
if(lua_cpcall(L, _l_do_load, reinterpret_cast<void*>(&oParams)) != 0)
|
||||
lua_pop(L, 1);
|
||||
delete[] sData;
|
||||
_setFilename(oOpenDialog.GetPath());
|
||||
m_pGamePanel->Refresh();
|
||||
}
|
||||
|
||||
int frmMain::_l_do_load(lua_State *L)
|
||||
{
|
||||
lua_getglobal(L, "TheApp");
|
||||
lua_getfield(L, -1, "loadLevel");
|
||||
lua_insert(L, -2);
|
||||
do_load_level_t *pParams = reinterpret_cast<do_load_level_t*>(lua_touserdata(L, 1));
|
||||
size_t iLength = pParams->iLength;
|
||||
const char* sData = pParams->sData;
|
||||
lua_pushlstring(L, sData, iLength);
|
||||
if(iLength >= 3 && sData[0] == 'R' && sData[1] == 'N' && sData[2] == 'C')
|
||||
{
|
||||
lua_getglobal(L, "require");
|
||||
lua_pushliteral(L, "rnc");
|
||||
lua_call(L, 1, 1);
|
||||
lua_getfield(L, -1, "decompress");
|
||||
lua_insert(L, -3);
|
||||
lua_call(L, 2, 1);
|
||||
}
|
||||
lua_call(L, 2, 0);
|
||||
|
||||
pParams->pThis->_applyViewWalls();
|
||||
pParams->pThis->_applyViewOverlay();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void frmMain::_onSave(wxRibbonButtonBarEvent& evt)
|
||||
{
|
||||
wxCommandEvent dummy;
|
||||
_onSaveMenuSave(dummy);
|
||||
}
|
||||
|
||||
void frmMain::_onSaveMenu(wxRibbonButtonBarEvent& evt)
|
||||
{
|
||||
wxMenu mnuPopup;
|
||||
mnuPopup.Append(ID_SAVE_IN_DROPDOWN, "Save");
|
||||
mnuPopup.Append(ID_SAVEAS, "Save As");
|
||||
evt.PopupMenu(&mnuPopup);
|
||||
}
|
||||
|
||||
void frmMain::_onUndo(wxRibbonButtonBarEvent& evt)
|
||||
{
|
||||
_doLuaUndo();
|
||||
}
|
||||
void frmMain::_onRedo(wxRibbonButtonBarEvent& evt)
|
||||
{
|
||||
_doLuaRedo();
|
||||
}
|
||||
|
||||
|
||||
struct map_save_t
|
||||
{
|
||||
wxFile fFile;
|
||||
|
||||
static void writer(void* pThis_, const unsigned char* pData, size_t iLen)
|
||||
{
|
||||
map_save_t* pThis = reinterpret_cast<map_save_t*>(pThis_);
|
||||
pThis->fFile.Write(reinterpret_cast<const void*>(pData), iLen);
|
||||
}
|
||||
};
|
||||
|
||||
void frmMain::_onSaveMenuSave(wxCommandEvent& evt)
|
||||
{
|
||||
if(m_sFilename.empty())
|
||||
{
|
||||
_onSaveMenuSaveAs(evt);
|
||||
return;
|
||||
}
|
||||
|
||||
map_save_t oSave;
|
||||
if(oSave.fFile.Open(m_sFilename, wxFile::write))
|
||||
{
|
||||
lua_State* L = m_pGamePanel->getLua();
|
||||
luaT_execute(L, "return TheApp.world.map.th");
|
||||
THMap *pMap = reinterpret_cast<THMap*>(lua_touserdata(L, -1));
|
||||
lua_pop(L, 1);
|
||||
THMapWrapper::autoSetHelipad(pMap);
|
||||
luaT_execute(L, "return TheApp.ui:ScreenToWorld(...)",
|
||||
m_pGamePanel->GetSize().GetWidth() / 2,
|
||||
m_pGamePanel->GetSize().GetHeight() / 2);
|
||||
int iCameraX = (int)lua_tointeger(L, -2);
|
||||
int iCameraY = (int)lua_tointeger(L, -1);
|
||||
lua_pop(L, 2);
|
||||
pMap->setPlayerCameraTile(0, iCameraX, iCameraY);
|
||||
pMap->save(map_save_t::writer, reinterpret_cast<void*>(&oSave));
|
||||
::wxMessageBox(wxT("Map saved."), wxT("Save"), wxOK | wxCENTER |
|
||||
wxICON_INFORMATION, this);
|
||||
}
|
||||
}
|
||||
|
||||
void frmMain::_onSaveMenuSaveAs(wxCommandEvent& evt)
|
||||
{
|
||||
wxString sDirectory = _getMapsDirectory();
|
||||
wxString sFilter = _getMapsFilter();
|
||||
wxFileDialog oSaveDialog(this, wxFileSelectorPromptStr, sDirectory,
|
||||
m_sFilename, sFilter, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
|
||||
oSaveDialog.SetFilterIndex(2);
|
||||
if(oSaveDialog.ShowModal() != wxID_OK)
|
||||
return;
|
||||
_setFilename(oSaveDialog.GetPath());
|
||||
_onSaveMenuSave(evt);
|
||||
}
|
||||
|
||||
void frmMain::_onViewWalls(wxRibbonButtonBarEvent& evt)
|
||||
{
|
||||
m_bViewWalls = evt.IsChecked();
|
||||
_applyViewWalls();
|
||||
m_pGamePanel->Refresh();
|
||||
}
|
||||
|
||||
void frmMain::_onViewFlags(wxRibbonButtonBarEvent& evt)
|
||||
{
|
||||
m_bViewFlags = evt.IsChecked();
|
||||
_applyViewOverlay();
|
||||
m_pGamePanel->Refresh();
|
||||
}
|
||||
|
||||
void frmMain::_onViewParcels(wxRibbonButtonBarEvent& evt)
|
||||
{
|
||||
m_bViewParcels = evt.IsChecked();
|
||||
_applyViewOverlay();
|
||||
m_pGamePanel->Refresh();
|
||||
|
||||
if(evt.IsChecked())
|
||||
{
|
||||
wxRibbonPanel* pParcelPanel = new wxRibbonPanel(m_pHomePage,
|
||||
ID_PARCEL_PANEL, L"Parcels");
|
||||
wxRibbonGallery* pParcelGallery = new wxRibbonGallery(pParcelPanel,
|
||||
ID_GALLERY_PARCELS);
|
||||
_populateParcelGallery(pParcelGallery);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxWindow* pParcelPanel = m_pHomePage->FindWindow(ID_PARCEL_PANEL);
|
||||
if(pParcelPanel)
|
||||
pParcelPanel->Destroy();
|
||||
}
|
||||
m_pRibbon->Realize();
|
||||
}
|
||||
|
||||
void frmMain::_onViewPositions(wxRibbonButtonBarEvent& evt)
|
||||
{
|
||||
m_bViewPositions = evt.IsChecked();
|
||||
_applyViewOverlay();
|
||||
m_pGamePanel->Refresh();
|
||||
}
|
||||
|
||||
wxBitmap frmMain::_asBitmap(THSpriteSheet* pSheet, unsigned int iSprite)
|
||||
{
|
||||
unsigned int iWidth, iHeight;
|
||||
pSheet->getSpriteSize(iSprite, &iWidth, &iHeight);
|
||||
wxImage imgSprite;
|
||||
imgSprite.Create(iWidth, iHeight);
|
||||
if(!imgSprite.HasAlpha())
|
||||
imgSprite.InitAlpha();
|
||||
pSheet->wxDrawSprite(iSprite, imgSprite.GetData(), imgSprite.GetAlpha());
|
||||
return wxBitmap(imgSprite);
|
||||
}
|
||||
|
||||
void frmMain::_populateParcelGallery(wxRibbonGallery* pGallery)
|
||||
{
|
||||
THSpriteSheet *pBlocksSheet;
|
||||
THSpriteSheet *pOutlineSheet;
|
||||
THSpriteSheet *pFontSheet;
|
||||
{
|
||||
lua_State *L = m_pGamePanel->getLua();
|
||||
luaT_execute(L, "return TheApp.map.blocks");
|
||||
pBlocksSheet = reinterpret_cast<THSpriteSheet*>(lua_touserdata(L, -1));
|
||||
luaT_execute(L, "return TheApp.map.cell_outline");
|
||||
pOutlineSheet = reinterpret_cast<THSpriteSheet*>(lua_touserdata(L, -1));
|
||||
luaT_execute(L, "return TheApp.gfx:loadBuiltinFont()");
|
||||
pFontSheet = reinterpret_cast<THBitmapFont*>(lua_touserdata(L, -1))
|
||||
->getSpriteSheet();
|
||||
lua_pop(L, 3);
|
||||
}
|
||||
|
||||
wxBitmap bmOutline(_asBitmap(pBlocksSheet, 74));
|
||||
wxMemoryDC dcMem;
|
||||
dcMem.SelectObject(bmOutline);
|
||||
for(int i = 0; i < 4; ++i)
|
||||
{
|
||||
dcMem.DrawBitmap(_asBitmap(pOutlineSheet, 18 + i), 0, 0);
|
||||
}
|
||||
dcMem.SelectObject(wxNullBitmap);
|
||||
|
||||
wxBitmap bmNumbers[10];
|
||||
for(int i = 0; i < 10; ++i)
|
||||
{
|
||||
bmNumbers[i] = _asBitmap(pFontSheet, '0' + i - 31);
|
||||
}
|
||||
|
||||
for(intptr_t iParcel = 0; iParcel < 32; ++iParcel)
|
||||
{
|
||||
wxBitmap bmParcel(bmOutline);
|
||||
dcMem.SelectObject(bmParcel);
|
||||
|
||||
char sMsg[8];
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4996)
|
||||
#endif
|
||||
sprintf(sMsg, "%i", iParcel);
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
int iX = 0, iY = 0;
|
||||
for(char* s = sMsg; *s; ++s)
|
||||
{
|
||||
wxBitmap& bm = bmNumbers[*s - '0'];
|
||||
iX += bm.GetWidth();
|
||||
iY = std::max(iY, bm.GetHeight());
|
||||
}
|
||||
iX = (bmParcel.GetWidth() - iX) / 2;
|
||||
iY = (bmParcel.GetHeight() - iY) / 2;
|
||||
|
||||
for(char* s = sMsg; *s; ++s)
|
||||
{
|
||||
wxBitmap& bm = bmNumbers[*s - '0'];
|
||||
dcMem.DrawBitmap(bm, iX, iY);
|
||||
iX += bm.GetWidth();
|
||||
}
|
||||
|
||||
dcMem.SelectObject(wxNullBitmap);
|
||||
pGallery->SetItemClientData(pGallery->Append(bmParcel, iParcel),
|
||||
reinterpret_cast<void*>(iParcel));
|
||||
}
|
||||
}
|
||||
|
||||
void frmMain::_onResize(wxSizeEvent& evt)
|
||||
{
|
||||
wxRect rcLogWindow = wxRect(GetPosition(), m_pLogWindow->GetSize());
|
||||
rcLogWindow.x += evt.GetSize().GetWidth();
|
||||
rcLogWindow.height = evt.GetSize().GetHeight();
|
||||
m_pLogWindow->SetSize(rcLogWindow);
|
||||
evt.Skip();
|
||||
}
|
||||
|
||||
int frmMain::_l_init(lua_State *L)
|
||||
{
|
||||
frmMain *pThis = reinterpret_cast<frmMain*>(lua_touserdata(L, 1));
|
||||
|
||||
THMapWrapper::wrap(L);
|
||||
|
||||
// Create a new environment table: {
|
||||
// [1] = <light userdata pThis>,
|
||||
// }
|
||||
lua_newtable(L);
|
||||
lua_insert(L, 1);
|
||||
lua_rawseti(L, 1, 1);
|
||||
lua_replace(L, LUA_ENVIRONINDEX);
|
||||
// NB: Following functions registered with above environment table
|
||||
|
||||
luaT_execute(L, "MapEditorSetBlocks = ...", _l_set_blocks);
|
||||
luaT_execute(L, "MapEditorSetBlockBrush = ...", _l_set_block_brush);
|
||||
luaT_execute(L, "MapEditorInitWithLuaApp = ...", _l_init_with_lua_app);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
class FullSizeButtonBar : public wxRibbonButtonBar
|
||||
{
|
||||
public:
|
||||
FullSizeButtonBar(wxWindow* parent, wxWindowID id)
|
||||
: wxRibbonButtonBar(parent, id)
|
||||
{
|
||||
}
|
||||
|
||||
virtual wxSize GetMinSize() const
|
||||
{
|
||||
return DoGetBestSize();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual wxSize DoGetNextSmallerSize(wxOrientation direction,
|
||||
wxSize relative_to) const
|
||||
{
|
||||
return relative_to;
|
||||
}
|
||||
};
|
||||
|
||||
int frmMain::_l_init_with_lua_app(lua_State *L)
|
||||
{
|
||||
lua_rawgeti(L, LUA_ENVIRONINDEX, 1);
|
||||
frmMain *pThis = reinterpret_cast<frmMain*>(lua_touserdata(L, -1));
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, 1, "getBitmapDir");
|
||||
lua_pushvalue(L, 1);
|
||||
lua_call(L, 1, 1);
|
||||
wxString sBitmapDir = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
wxRibbonPage* pHomePage = pThis->m_pHomePage;
|
||||
wxRibbonPanel* pFilePanel = new wxRibbonPanel(pHomePage, wxID_ANY, wxT("File"));
|
||||
wxRibbonButtonBar* pFileButtons = new FullSizeButtonBar(pFilePanel, wxID_ANY);
|
||||
#define BITMAP(name) wxBitmap(sBitmapDir + (wxT(name) wxT("32.png")), wxBITMAP_TYPE_PNG)
|
||||
pFileButtons->AddButton(wxID_NEW, wxT("New"), BITMAP("new"));
|
||||
pFileButtons->AddButton(wxID_OPEN, wxT("Load"), BITMAP("open"));
|
||||
pFileButtons->AddHybridButton(wxID_SAVE, wxT("Save"), BITMAP("save"));
|
||||
pFileButtons->AddButton(wxID_UNDO, wxT("Undo"), BITMAP("undo"));
|
||||
pFileButtons->AddButton(wxID_REDO, wxT("Redo"), BITMAP("redo"));
|
||||
|
||||
|
||||
wxRibbonPanel* pViewPanel = new wxRibbonPanel(pHomePage, wxID_ANY, wxT("View"));
|
||||
wxRibbonButtonBar* pViewButtons = new FullSizeButtonBar(pViewPanel, wxID_ANY);
|
||||
pViewButtons->AddToggleButton(ID_VIEW_WALLS, wxT("Walls"), BITMAP("transparent_walls"));
|
||||
pViewButtons->ToggleButton(ID_VIEW_WALLS, pThis->m_bViewWalls = true);
|
||||
pViewButtons->AddToggleButton(ID_VIEW_FLAGS, wxT("Flags"), BITMAP("flags"));
|
||||
pViewButtons->ToggleButton(ID_VIEW_FLAGS, pThis->m_bViewFlags = false);
|
||||
pViewButtons->AddToggleButton(ID_VIEW_PARCELS, wxT("Parcels"), BITMAP("parcels"));
|
||||
pViewButtons->ToggleButton(ID_VIEW_PARCELS, pThis->m_bViewParcels = false);
|
||||
pViewButtons->AddToggleButton(ID_VIEW_POSITIONS, wxT("Positions"), BITMAP("positions"));
|
||||
pViewButtons->ToggleButton(ID_VIEW_POSITIONS, pThis->m_bViewPositions = false);
|
||||
|
||||
|
||||
#undef BITMAP
|
||||
pThis->m_pRibbon->Realise();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void frmMain::_applyViewWalls()
|
||||
{
|
||||
m_pGamePanel->getMap()->setAllWallDrawFlags(m_bViewWalls ? 0 : THDF_Alpha50);
|
||||
}
|
||||
|
||||
void frmMain::_applyViewOverlay()
|
||||
{
|
||||
if(m_bViewFlags || m_bViewParcels || m_bViewPositions)
|
||||
{
|
||||
lua_State *L = m_pGamePanel->getLua();
|
||||
luaT_execute(L, "return TheApp.gfx:loadBuiltinFont(), TheApp.map.cell_outline");
|
||||
THFont *pFont = reinterpret_cast<THFont*>(lua_touserdata(L, -2));
|
||||
THSpriteSheet *pSprites = reinterpret_cast<THSpriteSheet*>(lua_touserdata(L, -1));
|
||||
lua_pop(L, 2);
|
||||
|
||||
THMapTypicalOverlay *pFlags = NULL;
|
||||
THMapTypicalOverlay *pParcels = NULL;
|
||||
THMapPositionsOverlay *pPositions = NULL;
|
||||
if(m_bViewFlags)
|
||||
{
|
||||
pFlags = new THMapFlagsOverlay;
|
||||
pFlags->setFont(pFont, false);
|
||||
pFlags->setSprites(pSprites, false);
|
||||
}
|
||||
if(m_bViewParcels)
|
||||
{
|
||||
pParcels = new THMapParcelsOverlay;
|
||||
pParcels->setFont(pFont, false);
|
||||
pParcels->setSprites(pSprites, false);
|
||||
}
|
||||
if(m_bViewPositions)
|
||||
{
|
||||
pPositions = new THMapPositionsOverlay;
|
||||
pPositions->setFont(pFont, false);
|
||||
pPositions->setSprites(pSprites, false);
|
||||
pPositions->setBackgroundSprite(2);
|
||||
}
|
||||
THMapOverlayPair *pOverlays = new THMapOverlayPair;
|
||||
pOverlays->setFirst(pParcels, true);
|
||||
pOverlays->setSecond(pFlags, true);
|
||||
THMapOverlayPair *pOverlays2 = new THMapOverlayPair;
|
||||
pOverlays2->setFirst(pOverlays, true);
|
||||
pOverlays2->setSecond(pPositions, true);
|
||||
m_pGamePanel->getMap()->setOverlay(pOverlays2, true);
|
||||
}
|
||||
else
|
||||
m_pGamePanel->getMap()->setOverlay(NULL, false);
|
||||
}
|
||||
|
||||
int frmMain::_l_set_blocks(lua_State *L)
|
||||
{
|
||||
lua_rawgeti(L, LUA_ENVIRONINDEX, 1);
|
||||
frmMain *pThis = reinterpret_cast<frmMain*>(lua_touserdata(L, -1));
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_checktype(L, 1, LUA_TUSERDATA);
|
||||
luaL_checktype(L, 2, LUA_TTABLE);
|
||||
|
||||
pThis->m_iFloorTabBrushF = 0;
|
||||
pThis->m_iFloorTabBrushW1 = 0;
|
||||
pThis->m_iFloorTabBrushW2 = 0;
|
||||
pThis->m_iWallsTabBrushF = 0;
|
||||
pThis->m_iWallsTabBrushW1 = 0;
|
||||
pThis->m_iWallsTabBrushW2 = 0;
|
||||
|
||||
THSpriteSheet *pSheet = reinterpret_cast<THSpriteSheet*>(lua_touserdata(L, 1));
|
||||
pThis->m_pFloorGallery1->Populate(pSheet, "floor", "simple", L, 2);
|
||||
pThis->m_pFloorGallery2->Populate(pSheet, "floor", "decorated", L, 2);
|
||||
pThis->m_pWallGallery1->Populate(pSheet, "wall", "west", L, 2);
|
||||
pThis->m_pWallGallery2->Populate(pSheet, "wall", "north", L, 2);
|
||||
pThis->m_pRibbon->Realize();
|
||||
pThis->Layout();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int frmMain::_l_set_block_brush(lua_State *L)
|
||||
{
|
||||
lua_rawgeti(L, LUA_ENVIRONINDEX, 1);
|
||||
frmMain *pThis = reinterpret_cast<frmMain*>(lua_touserdata(L, -1));
|
||||
lua_pop(L, 1);
|
||||
|
||||
int iBlock;
|
||||
|
||||
if(pThis->m_pRibbon->GetActivePage() == 0)
|
||||
pThis->m_pRibbon->SetActivePage(1);
|
||||
|
||||
wxRibbonGalleryEvent evt(wxEVT_COMMAND_RIBBONGALLERY_SELECTED);
|
||||
if(pThis->m_pRibbon->GetActivePage() == 1)
|
||||
{
|
||||
// Floor
|
||||
iBlock = luaL_checkint(L, 1);
|
||||
if(pThis->m_pFloorGallery1->SelectAndMakeVisible(iBlock))
|
||||
{
|
||||
pThis->m_pFloorGallery2->SetSelection(NULL);
|
||||
evt.SetGallery(pThis->m_pFloorGallery1);
|
||||
}
|
||||
else if(pThis->m_pFloorGallery2->SelectAndMakeVisible(iBlock))
|
||||
{
|
||||
pThis->m_pFloorGallery1->SetSelection(NULL);
|
||||
evt.SetGallery(pThis->m_pFloorGallery2);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wall
|
||||
iBlock = luaL_checkint(L, 2);
|
||||
if(pThis->m_pWallGallery1->SelectAndMakeVisible(iBlock))
|
||||
{
|
||||
pThis->m_pWallGallery2->SetSelection(NULL);
|
||||
evt.SetGallery(pThis->m_pWallGallery1);
|
||||
}
|
||||
else if(pThis->m_pWallGallery2->SelectAndMakeVisible(iBlock))
|
||||
{
|
||||
pThis->m_pWallGallery1->SetSelection(NULL);
|
||||
evt.SetGallery(pThis->m_pWallGallery2);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
evt.SetId(evt.GetGallery()->GetId());
|
||||
evt.SetGalleryItem(evt.GetGallery()->GetSelection());
|
||||
pThis->ProcessEvent(evt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void frmMain::_onFloorGallery1Select(wxRibbonGalleryEvent& evt)
|
||||
{
|
||||
if(evt.GetGalleryItem() != NULL)
|
||||
{
|
||||
m_pFloorGallery2->SetSelection(NULL);
|
||||
int iBaseBlock;
|
||||
int iBlock = m_pFloorGallery1->GetBlock(evt.GetGalleryItem(), &iBaseBlock);
|
||||
if(iBaseBlock != 0)
|
||||
_setLuaBlockBrushFloorTab(iBaseBlock, iBlock, 0);
|
||||
else
|
||||
_setLuaBlockBrushFloorTab(iBlock, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void frmMain::_onFloorGallery2Select(wxRibbonGalleryEvent& evt)
|
||||
{
|
||||
if(evt.GetGalleryItem() != NULL)
|
||||
{
|
||||
m_pFloorGallery1->SetSelection(NULL);
|
||||
int iBaseBlock;
|
||||
int iBlock = m_pFloorGallery2->GetBlock(evt.GetGalleryItem(), &iBaseBlock);
|
||||
if(iBaseBlock != 0)
|
||||
_setLuaBlockBrushFloorTab(iBaseBlock, iBlock, 0);
|
||||
else
|
||||
_setLuaBlockBrushFloorTab(iBlock, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void frmMain::_onParcelGallerySelect(wxRibbonGalleryEvent& evt)
|
||||
{
|
||||
if(evt.GetGalleryItem() != NULL)
|
||||
{
|
||||
_setLuaParcelBrush(static_cast<int>(reinterpret_cast<intptr_t>(
|
||||
evt.GetGallery()->GetItemClientData(evt.GetGalleryItem()))));
|
||||
}
|
||||
}
|
||||
|
||||
void frmMain::_setLuaParcelBrush(int iParcel)
|
||||
{
|
||||
m_iParcelBrush = iParcel;
|
||||
lua_State *L = m_pGamePanel->getLua();
|
||||
luaT_execute(L, "_MAP_EDITOR:setBlockBrushParcel(...)", iParcel);
|
||||
}
|
||||
|
||||
void frmMain::_onWallGallery1Select(wxRibbonGalleryEvent& evt)
|
||||
{
|
||||
if(evt.GetGalleryItem() != NULL)
|
||||
{
|
||||
m_pWallGallery2->SetSelection(NULL);
|
||||
int iBlock = m_pWallGallery1->GetBlock(evt.GetGalleryItem(), NULL);
|
||||
_setLuaBlockBrushWallsTab(0, 0, iBlock);
|
||||
}
|
||||
}
|
||||
|
||||
void frmMain::_onWallGallery2Select(wxRibbonGalleryEvent& evt)
|
||||
{
|
||||
if(evt.GetGalleryItem() != NULL)
|
||||
{
|
||||
m_pWallGallery1->SetSelection(NULL);
|
||||
int iBlock = m_pWallGallery2->GetBlock(evt.GetGalleryItem(), NULL);
|
||||
_setLuaBlockBrushWallsTab(0, iBlock, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void frmMain::_setLuaBlockBrushFloorTab(int iBlockF, int iBlockW1, int iBlockW2)
|
||||
{
|
||||
m_iFloorTabBrushF = iBlockF;
|
||||
m_iFloorTabBrushW1 = iBlockW1;
|
||||
m_iFloorTabBrushW2 = iBlockW2;
|
||||
_setLuaBlockBrushFloorTab();
|
||||
}
|
||||
|
||||
void frmMain::_setLuaBlockBrushWallsTab(int iBlockF, int iBlockW1, int iBlockW2)
|
||||
{
|
||||
m_iWallsTabBrushF = iBlockF;
|
||||
m_iWallsTabBrushW1 = iBlockW1;
|
||||
m_iWallsTabBrushW2 = iBlockW2;
|
||||
_setLuaBlockBrushWallsTab();
|
||||
}
|
||||
|
||||
void frmMain::_setLuaBlockBrushFloorTab()
|
||||
{
|
||||
_setLuaBlockBrush(m_iFloorTabBrushF, m_iFloorTabBrushW1, m_iFloorTabBrushW2);
|
||||
}
|
||||
|
||||
void frmMain::_setLuaBlockBrushWallsTab()
|
||||
{
|
||||
_setLuaBlockBrush(m_iWallsTabBrushF, m_iWallsTabBrushW1, m_iWallsTabBrushW2);
|
||||
}
|
||||
|
||||
void frmMain::_setLuaBlockBrush(int iBlockF, int iBlockW1, int iBlockW2)
|
||||
{
|
||||
lua_State *L = m_pGamePanel->getLua();
|
||||
luaT_execute(L, "_MAP_EDITOR:setBlockBrush(...)",
|
||||
iBlockF, iBlockW1, iBlockW2);
|
||||
}
|
||||
|
||||
void frmMain::_doLuaUndo()
|
||||
{
|
||||
lua_State *L = m_pGamePanel->getLua();
|
||||
luaT_execute(L, "_MAP_EDITOR:undo()");
|
||||
m_pGamePanel->Refresh();
|
||||
}
|
||||
|
||||
void frmMain::_doLuaRedo()
|
||||
{
|
||||
lua_State *L = m_pGamePanel->getLua();
|
||||
luaT_execute(L, "_MAP_EDITOR:redo()");
|
||||
m_pGamePanel->Refresh();
|
||||
}
|
@@ -1,129 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2009 Peter "Corsix" Cawley
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
// For compilers that support precompilation, includes "wx/wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
// for all others, include the necessary headers (this file is usually all you
|
||||
// need because it includes almost all "standard" wxWidgets headers)
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif
|
||||
// ----------------------------
|
||||
#include "scrollable_game.h"
|
||||
#include <wx/ribbon/bar.h>
|
||||
#include <wx/ribbon/buttonbar.h>
|
||||
#include <wx/splitter.h>
|
||||
#include "block_gallery.h"
|
||||
|
||||
class frmMain : public wxFrame
|
||||
{
|
||||
public:
|
||||
frmMain();
|
||||
~frmMain();
|
||||
|
||||
enum
|
||||
{
|
||||
ID_GALLERY_FLOOR1 = wxID_HIGHEST + 1,
|
||||
ID_GALLERY_FLOOR2,
|
||||
ID_GALLERY_WALL1,
|
||||
ID_GALLERY_WALL2,
|
||||
ID_GALLERY_PARCELS,
|
||||
ID_VIEW_WALLS,
|
||||
ID_VIEW_FLAGS,
|
||||
ID_VIEW_PARCELS,
|
||||
ID_VIEW_POSITIONS,
|
||||
ID_PARCEL_PANEL,
|
||||
ID_SAVE_IN_DROPDOWN,
|
||||
ID_SAVEAS
|
||||
};
|
||||
|
||||
protected:
|
||||
wxRibbonBar* m_pRibbon;
|
||||
wxRibbonPage* m_pHomePage;
|
||||
frmLog* m_pLogWindow;
|
||||
ScrollableGamePanel* m_pGamePanel;
|
||||
RibbonBlockGallery* m_pFloorGallery1;
|
||||
RibbonBlockGallery* m_pFloorGallery2;
|
||||
RibbonBlockGallery* m_pWallGallery1;
|
||||
RibbonBlockGallery* m_pWallGallery2;
|
||||
wxString m_sFrameCaption;
|
||||
wxString m_sFilename;
|
||||
bool m_bViewFlags;
|
||||
bool m_bViewParcels;
|
||||
bool m_bViewPositions;
|
||||
bool m_bViewWalls;
|
||||
int m_iFloorTabBrushF;
|
||||
int m_iFloorTabBrushW1;
|
||||
int m_iFloorTabBrushW2;
|
||||
int m_iWallsTabBrushF;
|
||||
int m_iWallsTabBrushW1;
|
||||
int m_iWallsTabBrushW2;
|
||||
int m_iParcelBrush;
|
||||
|
||||
void _applyViewWalls();
|
||||
void _applyViewOverlay();
|
||||
wxString _getMapsDirectory();
|
||||
wxString _getMapsFilter();
|
||||
void _setFilename(const wxString& sFilename);
|
||||
void _onFloorGallery1Select(wxRibbonGalleryEvent& evt);
|
||||
void _onFloorGallery2Select(wxRibbonGalleryEvent& evt);
|
||||
void _onWallGallery1Select(wxRibbonGalleryEvent& evt);
|
||||
void _onWallGallery2Select(wxRibbonGalleryEvent& evt);
|
||||
void _onParcelGallerySelect(wxRibbonGalleryEvent& evt);
|
||||
void _onNew(wxRibbonButtonBarEvent& evt);
|
||||
void _onOpen(wxRibbonButtonBarEvent& evt);
|
||||
void _onSave(wxRibbonButtonBarEvent& evt);
|
||||
void _onUndo(wxRibbonButtonBarEvent& evt);
|
||||
void _onRedo(wxRibbonButtonBarEvent& evt);
|
||||
void _onSaveMenu(wxRibbonButtonBarEvent& evt);
|
||||
void _onSaveMenuSave(wxCommandEvent& evt);
|
||||
void _onSaveMenuSaveAs(wxCommandEvent& evt);
|
||||
void _onResize(wxSizeEvent& evt);
|
||||
void _onViewWalls(wxRibbonButtonBarEvent& evt);
|
||||
void _onViewFlags(wxRibbonButtonBarEvent& evt);
|
||||
void _onViewParcels(wxRibbonButtonBarEvent& evt);
|
||||
void _onViewPositions(wxRibbonButtonBarEvent& evt);
|
||||
void _onRibbonPageChanged(wxRibbonBarEvent& evt);
|
||||
void _populateParcelGallery(wxRibbonGallery* pGallery);
|
||||
static wxBitmap _asBitmap(THSpriteSheet* pSheet, unsigned int iSprite);
|
||||
static int _l_init(lua_State *L);
|
||||
static int _l_init_with_lua_app(lua_State *L);
|
||||
static int _l_set_blocks(lua_State *L);
|
||||
static int _l_set_block_brush(lua_State *L);
|
||||
static int _l_do_load(lua_State *L);
|
||||
void _setLuaBlockBrushFloorTab(int iBlockF, int iBlockW1, int iBlockW2);
|
||||
void _setLuaBlockBrushWallsTab(int iBlockF, int iBlockW1, int iBlockW2);
|
||||
void _setLuaBlockBrushFloorTab();
|
||||
void _setLuaBlockBrushWallsTab();
|
||||
void _setLuaBlockBrush(int iBlockF, int iBlockW1, int iBlockW2);
|
||||
void _setLuaParcelBrush(int iParcel);
|
||||
void _doLuaUndo();
|
||||
void _doLuaRedo();
|
||||
|
||||
DECLARE_EVENT_TABLE();
|
||||
};
|
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2009 Peter "Corsix" Cawley
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "config.h"
|
||||
#ifndef CORSIX_TH_USE_OGL_RENDERER
|
||||
#error To compile the map editor, the OpenGL rendering engine must be used
|
||||
#endif
|
||||
#include "../../CorsixTH/Src/th_gfx.h"
|
||||
#include "../../CorsixTH/Src/th_lua.h"
|
||||
#include "../../CorsixTH/Src/th_map.h"
|
||||
#include "../../CorsixTH/Src/th_map_overlays.h"
|
@@ -1,304 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2009 Peter "Corsix" Cawley
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include <algorithm>
|
||||
#include "scrollable_game.h"
|
||||
|
||||
BEGIN_EVENT_TABLE(ScrollableGamePanel, wxPanel)
|
||||
EVT_SIZE(ScrollableGamePanel::_onResize)
|
||||
EVT_COMMAND_SCROLL(ID_X_SCROLL, ScrollableGamePanel::_onScroll)
|
||||
EVT_COMMAND_SCROLL(ID_Y_SCROLL, ScrollableGamePanel::_onScroll)
|
||||
EVT_TIMER(wxID_ANY, ScrollableGamePanel::_onTimer)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
ScrollableGamePanel::ScrollableGamePanel(wxWindow *pParent)
|
||||
: wxPanel(pParent)
|
||||
, m_pGamePanel(NULL)
|
||||
, m_pMapScrollX(NULL)
|
||||
, m_pMapScrollY(NULL)
|
||||
, m_bShouldRespondToScroll(true)
|
||||
{
|
||||
wxFlexGridSizer *pSizer = new wxFlexGridSizer(2, 2, 0, 0);
|
||||
pSizer->AddGrowableRow(0, 1);
|
||||
pSizer->AddGrowableCol(0, 1);
|
||||
|
||||
pSizer->Add(m_pGamePanel = new EmbeddedGamePanel(this), 1, wxEXPAND);
|
||||
m_pGamePanel->setExtraLuaInitFunction(_l_extra_init,
|
||||
reinterpret_cast<void*>(this));
|
||||
pSizer->Add(m_pMapScrollY = new wxScrollBar(this, ID_Y_SCROLL,
|
||||
wxDefaultPosition, wxDefaultSize, wxVERTICAL), 0, wxEXPAND);
|
||||
pSizer->Add(m_pMapScrollX = new wxScrollBar(this, ID_X_SCROLL,
|
||||
wxDefaultPosition, wxDefaultSize, wxHORIZONTAL), 0, wxEXPAND);
|
||||
pSizer->AddSpacer(0);
|
||||
|
||||
m_pTimer = new wxTimer(this, wxID_ANY);
|
||||
m_pTimer->Start(100, false);
|
||||
|
||||
SetSizer(pSizer);
|
||||
}
|
||||
|
||||
ScrollableGamePanel::~ScrollableGamePanel()
|
||||
{
|
||||
m_pTimer->Stop();
|
||||
}
|
||||
|
||||
void ScrollableGamePanel::setExtraLuaInitFunction(lua_CFunction fn, void* arg)
|
||||
{
|
||||
m_fnExtraInit = fn;
|
||||
m_pExtraInitArg = arg;
|
||||
}
|
||||
|
||||
void ScrollableGamePanel::setLogWindow(frmLog *pLogWindow)
|
||||
{
|
||||
m_pGamePanel->setLogWindow(pLogWindow);
|
||||
}
|
||||
|
||||
bool ScrollableGamePanel::loadLua()
|
||||
{
|
||||
return m_pGamePanel->loadLua();
|
||||
}
|
||||
|
||||
lua_State* ScrollableGamePanel::getLua()
|
||||
{
|
||||
return m_pGamePanel->getLua();
|
||||
}
|
||||
|
||||
THMap* ScrollableGamePanel::getMap()
|
||||
{
|
||||
return m_pGamePanel->getMap();
|
||||
}
|
||||
|
||||
void ScrollableGamePanel::_onResize(wxSizeEvent& evt)
|
||||
{
|
||||
lua_State *L = m_pGamePanel->getLua();
|
||||
if(!L)
|
||||
goto default_resize;
|
||||
|
||||
// Get old world-coordinates of window center
|
||||
lua_Number fX, fY;
|
||||
lua_getglobal(L, "TheApp");
|
||||
if(lua_isnil(L, -1))
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
goto default_resize;
|
||||
}
|
||||
lua_getfield(L, -1, "ui");
|
||||
if(lua_isnil(L, -1))
|
||||
{
|
||||
lua_pop(L, 2);
|
||||
goto default_resize;
|
||||
}
|
||||
lua_getfield(L, -1, "ScreenToWorld");
|
||||
lua_pushvalue(L, -2);
|
||||
lua_pushinteger(L, m_pGamePanel->GetSize().GetWidth() / 2);
|
||||
lua_pushinteger(L, m_pGamePanel->GetSize().GetHeight() / 2);
|
||||
lua_call(L, 3, 2);
|
||||
fX = lua_tonumber(L, -2) - 1.0;
|
||||
fY = lua_tonumber(L, -1) - 1.0;
|
||||
lua_pop(L, 2);
|
||||
|
||||
// Change window center
|
||||
Layout();
|
||||
|
||||
// Move window center to same world co-ordinates
|
||||
THMap::worldToScreen(fX, fY);
|
||||
lua_getfield(L, -1, "scrollMapTo");
|
||||
lua_insert(L, -2);
|
||||
lua_pushnumber(L, fX);
|
||||
lua_pushnumber(L, fY);
|
||||
lua_call(L, 3, 0);
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
default_resize:
|
||||
evt.Skip();
|
||||
}
|
||||
|
||||
int ScrollableGamePanel::_l_extra_init(lua_State *L)
|
||||
{
|
||||
ScrollableGamePanel* pThis = reinterpret_cast<ScrollableGamePanel*>(
|
||||
lua_touserdata(L, 1));
|
||||
|
||||
// Perform the original extra initialisation
|
||||
if(pThis->m_fnExtraInit != NULL)
|
||||
{
|
||||
if(lua_cpcall(L, pThis->m_fnExtraInit, pThis->m_pExtraInitArg) != 0)
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
// Hook around the MapEditorInitWithLuaApp function
|
||||
lua_getglobal(L, "MapEditorInitWithLuaApp");
|
||||
lua_pushvalue(L, 1);
|
||||
lua_pushcclosure(L, _l_init_with_app, 2);
|
||||
lua_setglobal(L, "MapEditorInitWithLuaApp");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ScrollableGamePanel::_l_init_with_app(lua_State *L)
|
||||
{
|
||||
// Call the original MapEditorInitWithLuaApp function
|
||||
lua_pushvalue(L, lua_upvalueindex(1));
|
||||
if(lua_type(L, -1) == LUA_TNIL)
|
||||
lua_pop(L, 1);
|
||||
else
|
||||
{
|
||||
lua_insert(L, 1);
|
||||
lua_call(L, lua_gettop(L) - 1, LUA_MULTRET);
|
||||
}
|
||||
|
||||
// Wrap our _l_on_ui_scroll_map function around GameUI:scrollMap()
|
||||
// 1st upvalue: original GameUI:scrollMap() function
|
||||
// 2nd upvalue: light userdata this
|
||||
// This has to be done with the Lua App initialisation as we need for
|
||||
// dofile() to be the custom dofile() used by CorsixTH, rather than the
|
||||
// default one present at Lua initialisation time.
|
||||
luaT_execute(L, "dofile [[game_ui]]");
|
||||
lua_getglobal(L, "GameUI");
|
||||
lua_getfield(L, -1, "scrollMap");
|
||||
lua_pushvalue(L, lua_upvalueindex(2));
|
||||
lua_pushcclosure(L, _l_on_ui_scroll_map, 2);
|
||||
lua_setfield(L, -2, "scrollMap");
|
||||
|
||||
return lua_gettop(L);
|
||||
}
|
||||
|
||||
int ScrollableGamePanel::_l_on_ui_scroll_map(lua_State *L)
|
||||
{
|
||||
ScrollableGamePanel *pThis = reinterpret_cast<ScrollableGamePanel*>(
|
||||
lua_touserdata(L, lua_upvalueindex(2)));
|
||||
|
||||
// Make a copy of the "self" parameter at the bottom of the stack
|
||||
lua_pushvalue(L, 1);
|
||||
lua_insert(L, 1);
|
||||
|
||||
// Call original GameUI:scrollMap() function
|
||||
lua_pushvalue(L, lua_upvalueindex(1));
|
||||
lua_insert(L, 2);
|
||||
lua_call(L, lua_gettop(L) - 2, LUA_MULTRET);
|
||||
|
||||
if(pThis->m_bShouldRespondToScroll)
|
||||
{
|
||||
int iPanelW, iPanelH;
|
||||
pThis->m_pGamePanel->GetSize(&iPanelW, &iPanelH);
|
||||
|
||||
// Get world co-ordinates of window center
|
||||
lua_checkstack(L, 4);
|
||||
lua_getfield(L, 1, "ScreenToWorld");
|
||||
lua_pushvalue(L, 1);
|
||||
lua_pushinteger(L, iPanelW / 2);
|
||||
lua_pushinteger(L, iPanelH / 2);
|
||||
lua_call(L, 3, 2);
|
||||
lua_Number fX = lua_tonumber(L, -2) - 1.0;
|
||||
lua_Number fY = lua_tonumber(L, -1) - 1.0;
|
||||
lua_pop(L, 2);
|
||||
|
||||
// Get map extents
|
||||
THMap* pMap = pThis->m_pGamePanel->getMap();
|
||||
int iMapH = pMap->getHeight();
|
||||
int iTemp = pMap->getWidth();
|
||||
pMap->worldToScreen(iTemp, iMapH);
|
||||
int iMapW = pMap->getWidth();
|
||||
iTemp = 0;
|
||||
pMap->worldToScreen(iMapW, iTemp);
|
||||
|
||||
// Get screen co-ordinates of window center
|
||||
// We could get these directly from the GameUI, but we'd be delving into
|
||||
// its member variables, and also perhaps not properly accounting for zoom.
|
||||
pMap->worldToScreen(fX, fY);
|
||||
int iX = (int)fX;
|
||||
int iY = (int)fY;
|
||||
|
||||
// Update scrollbars
|
||||
pThis->m_pMapScrollX->SetScrollbar(iX + iMapW, iPanelW, iMapW * 2 + iPanelW, iPanelW);
|
||||
pThis->m_pMapScrollY->SetScrollbar(iY , iPanelH, iMapH + iPanelH, iPanelH);
|
||||
}
|
||||
|
||||
// Return results from original call
|
||||
return lua_gettop(L) - 1;
|
||||
}
|
||||
|
||||
void ScrollableGamePanel::_onScroll(wxScrollEvent& evt)
|
||||
{
|
||||
_positionMap();
|
||||
}
|
||||
|
||||
void ScrollableGamePanel::_onTimer(wxTimerEvent& evt)
|
||||
{
|
||||
const int KEY_SENSITIVITY = 20;
|
||||
int x = m_pMapScrollX->GetThumbPosition();
|
||||
int y = m_pMapScrollY->GetThumbPosition();
|
||||
bool bChanges = false;
|
||||
|
||||
if(wxGetKeyState(WXK_LEFT))
|
||||
{
|
||||
m_pMapScrollX->SetThumbPosition(std::max(0, x - KEY_SENSITIVITY));
|
||||
bChanges = true;
|
||||
}
|
||||
if(wxGetKeyState(WXK_RIGHT))
|
||||
{
|
||||
m_pMapScrollX->SetThumbPosition(std::min(m_pMapScrollX->GetRange(), x + KEY_SENSITIVITY));
|
||||
bChanges = true;
|
||||
}
|
||||
if(wxGetKeyState(WXK_UP))
|
||||
{
|
||||
m_pMapScrollY->SetThumbPosition(std::max(0, y - KEY_SENSITIVITY));
|
||||
bChanges = true;
|
||||
}
|
||||
if(wxGetKeyState(WXK_DOWN))
|
||||
{
|
||||
m_pMapScrollY->SetThumbPosition(std::min(m_pMapScrollY->GetRange(), y + KEY_SENSITIVITY));
|
||||
bChanges = true;
|
||||
}
|
||||
if (bChanges)
|
||||
{
|
||||
_positionMap();
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollableGamePanel::_positionMap()
|
||||
{
|
||||
lua_State *L = getLua();
|
||||
if(!L)
|
||||
{
|
||||
return;
|
||||
}
|
||||
lua_getglobal(L, "TheApp");
|
||||
if(lua_isnil(L, -1))
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
return;
|
||||
}
|
||||
lua_getfield(L, -1, "ui");
|
||||
if(lua_isnil(L, -1))
|
||||
{
|
||||
lua_pop(L, 2);
|
||||
return;
|
||||
}
|
||||
lua_replace(L, -2);
|
||||
lua_getfield(L, -1, "scrollMapTo");
|
||||
lua_insert(L, -2);
|
||||
lua_pushinteger(L, m_pMapScrollX->GetThumbPosition() - m_pMapScrollX->GetRange() / 2 + m_pMapScrollX->GetThumbSize() / 2);
|
||||
lua_pushinteger(L, m_pMapScrollY->GetThumbPosition());
|
||||
m_bShouldRespondToScroll = false;
|
||||
lua_call(L, 3, 1);
|
||||
m_bShouldRespondToScroll = true;
|
||||
m_pGamePanel->Refresh(false);
|
||||
}
|
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2010 Peter "Corsix" Cawley
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
// For compilers that support precompilation, includes "wx/wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
// for all others, include the necessary headers (this file is usually all you
|
||||
// need because it includes almost all "standard" wxWidgets headers)
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif
|
||||
// ----------------------------
|
||||
#include "embedded_game.h"
|
||||
|
||||
class ScrollableGamePanel : public wxPanel, public IEmbeddedGamePanel
|
||||
{
|
||||
public:
|
||||
ScrollableGamePanel(wxWindow *pParent);
|
||||
~ScrollableGamePanel();
|
||||
|
||||
void setExtraLuaInitFunction(lua_CFunction fn, void* arg);
|
||||
void setLogWindow(frmLog *pLogWindow);
|
||||
bool loadLua();
|
||||
|
||||
lua_State* getLua();
|
||||
THMap* getMap();
|
||||
|
||||
enum
|
||||
{
|
||||
ID_X_SCROLL = wxID_HIGHEST + 1,
|
||||
ID_Y_SCROLL
|
||||
};
|
||||
|
||||
protected:
|
||||
EmbeddedGamePanel* m_pGamePanel;
|
||||
wxScrollBar* m_pMapScrollX;
|
||||
wxScrollBar* m_pMapScrollY;
|
||||
lua_CFunction m_fnExtraInit;
|
||||
void* m_pExtraInitArg;
|
||||
bool m_bShouldRespondToScroll;
|
||||
wxTimer* m_pTimer;
|
||||
|
||||
void _onResize(wxSizeEvent& evt);
|
||||
void _onScroll(wxScrollEvent& evt);
|
||||
void _onTimer(wxTimerEvent& evt);
|
||||
|
||||
static int _l_extra_init(lua_State *L);
|
||||
static int _l_init_with_app(lua_State *L);
|
||||
static int _l_on_ui_scroll_map(lua_State *L);
|
||||
|
||||
DECLARE_EVENT_TABLE();
|
||||
|
||||
private:
|
||||
void _positionMap();
|
||||
};
|
@@ -1,391 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2010 Peter "Corsix" Cawley
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "th_map_wrapper.h"
|
||||
#include <stack>
|
||||
#include <utility>
|
||||
|
||||
void THMapWrapper::autoSetHelipad(THMap *pMap)
|
||||
{
|
||||
// Search the map for a "H" pattern made up from two ground tiles.
|
||||
// xxxxx
|
||||
// xHxHx
|
||||
// xHHHx
|
||||
// xHxHx
|
||||
// xxxxx
|
||||
for(int iX = 2; iX < pMap->getWidth() - 2; ++iX)
|
||||
{
|
||||
for(int iY = 2; iY < pMap->getHeight() - 2; ++iY)
|
||||
{
|
||||
THMapNode *pNode = pMap->getNodeUnchecked(iX, iY);
|
||||
if((pNode->iBlock[1] | pNode->iBlock[2]) & 0xFF)
|
||||
continue;
|
||||
uint16_t iFloor1 = pNode->iBlock[0] & 0xFF;
|
||||
uint16_t iFloor2 = pNode[-2].iBlock[0] & 0xFF;
|
||||
if(iFloor1 == iFloor2)
|
||||
continue;
|
||||
for(int iDX = -2; iDX <= 2; ++iDX)
|
||||
{
|
||||
for(int iDY = -2; iDY <= 2; ++iDY)
|
||||
{
|
||||
pNode = pMap->getNodeUnchecked(iX + iDX, iY + iDY);
|
||||
if(-1 <= iDX && iDX <= 1 && -1 <= iDY && iDY <= 1)
|
||||
{
|
||||
if((iDX | iDY) == 0)
|
||||
continue;
|
||||
if((pNode->iBlock[1] | pNode->iBlock[2]) & 0xFF)
|
||||
goto next_xy;
|
||||
if((pNode->iBlock[0] & 0xFF) !=
|
||||
(iDX == 0 ? iFloor2 : iFloor1))
|
||||
{
|
||||
goto next_xy;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if((pNode->iBlock[0] & 0xFF) != iFloor2)
|
||||
goto next_xy;
|
||||
}
|
||||
}
|
||||
}
|
||||
pMap->setPlayerHeliportTile(0, iX, iY);
|
||||
return;
|
||||
next_xy:;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void THMapWrapper::wrap(lua_State *L)
|
||||
{
|
||||
luaT_execute(L, "require[[TH]].map.setCell = ...", _l_set_cell);
|
||||
}
|
||||
|
||||
int THMapWrapper::_l_set_cell(lua_State *L)
|
||||
{
|
||||
// Perform same argument handling as normal setCell function
|
||||
THMap* pMap = reinterpret_cast<THMap*>(lua_touserdata(L, 1));
|
||||
int iX = luaL_checkint(L, 2) - 1; // Lua arrays start at 1 - pretend
|
||||
int iY = luaL_checkint(L, 3) - 1; // the map does too.
|
||||
THMapNode* pNode = pMap->getNode(iX, iY);
|
||||
if(pNode == NULL)
|
||||
return luaL_argerror(L, 2, "Map co-ordinates out of bounds");
|
||||
uint16_t iNewBlocks[4] = {
|
||||
pNode->iBlock[0],
|
||||
pNode->iBlock[1],
|
||||
pNode->iBlock[2],
|
||||
pNode->iBlock[3]
|
||||
};
|
||||
if(lua_gettop(L) >= 7)
|
||||
{
|
||||
iNewBlocks[0] = (uint16_t)luaL_checkint(L, 4);
|
||||
iNewBlocks[1] = (uint16_t)luaL_checkint(L, 5);
|
||||
iNewBlocks[2] = (uint16_t)luaL_checkint(L, 6);
|
||||
iNewBlocks[3] = (uint16_t)luaL_checkint(L, 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
int iLayer = luaL_checkint(L, 4) - 1;
|
||||
if(iLayer < 0 || iLayer >= 4)
|
||||
return luaL_argerror(L, 4, "Layer index is out of bounds (1-4)");
|
||||
int iBlock = luaL_checkint(L, 5);
|
||||
iNewBlocks[iLayer] = (uint16_t)iBlock;
|
||||
}
|
||||
|
||||
// Dispatch the call
|
||||
_do_set_cell(L, pMap, iX, iY, iNewBlocks);
|
||||
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool THMapWrapper::_isDoorframe(int iTile)
|
||||
{
|
||||
return ms_iDoorframeWallFirst <= iTile && iTile <= ms_iDoorframeWallLast;
|
||||
}
|
||||
|
||||
bool THMapWrapper::_isPassable(int iTile)
|
||||
{
|
||||
iTile &= 0xFF;
|
||||
if(iTile <= 5)
|
||||
return iTile >= 4;
|
||||
else if(iTile <= 0x17)
|
||||
return iTile >= 0xF;
|
||||
else if(iTile <= 0x3A)
|
||||
return iTile >= 0x29;
|
||||
else
|
||||
return iTile == 0x42 || iTile == 0x46 || iTile == 0x4C;
|
||||
}
|
||||
|
||||
bool THMapWrapper::_isWall(int iTile)
|
||||
{
|
||||
iTile &= 0xFF;
|
||||
if(82 <= iTile && iTile <= 155)
|
||||
return true;
|
||||
// NB: 157 through 160 are walls, but not the purposes of defining
|
||||
// hospital tiles.
|
||||
if(161 <= iTile && iTile <= 164)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool THMapWrapper::_isCertainlyHospital(THMap* pMap, int iX, int iY)
|
||||
{
|
||||
THMapNode *pNode = pMap->getNode(iX, iY);
|
||||
if(pNode && (pNode->iFlags & THMN_Passable))
|
||||
{
|
||||
if(_isWall(pNode->iBlock[1]) || _isWall(pNode->iBlock[2]))
|
||||
return true;
|
||||
THMapNode *pNeighbour = pMap->getNode(iX, iY + 1);
|
||||
if(pNeighbour && _isWall(pNeighbour->iBlock[1]))
|
||||
return true;
|
||||
pNeighbour = pMap->getNode(iX + 1, iY);
|
||||
if(pNeighbour && _isWall(pNeighbour->iBlock[2]))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void THMapWrapper::_do_set_cell(lua_State *L, THMap* pMap, int iX, int iY, uint16_t iNewBlocks[4])
|
||||
{
|
||||
THMapNode *pNode = pMap->getNodeUnchecked(iX, iY);
|
||||
|
||||
bool bShouldCheckHospitality = false;
|
||||
bool bWasCertainlyHospital = _isCertainlyHospital(pMap, iX, iY);
|
||||
|
||||
// Check for wall blocks which should have sliding doors
|
||||
bool bShouldCheckNeighbourDoors = false;
|
||||
bool bShouldCheckOwnDoor = false;
|
||||
for(int iDir = 0; iDir <= 1; ++iDir)
|
||||
{
|
||||
uint16_t iOld = pNode->iBlock[1 + iDir] & 0xFF;
|
||||
uint16_t iNew = iNewBlocks[1 + iDir] & 0xFF;
|
||||
if(iOld == iNew)
|
||||
continue;
|
||||
|
||||
bShouldCheckHospitality = true;
|
||||
if(_isDoorframe(iOld) || _isDoorframe(iNew))
|
||||
bShouldCheckNeighbourDoors = true;
|
||||
if((iOld == 0) != (iNew == 0))
|
||||
bShouldCheckOwnDoor = true;
|
||||
}
|
||||
|
||||
uint32_t iOldFlags = pNode->iFlags;
|
||||
if(_isPassable(iNewBlocks[0]))
|
||||
pNode->iFlags |= THMN_Passable;
|
||||
else
|
||||
pNode->iFlags &=~ THMN_Passable;
|
||||
if(pNode->iFlags != iOldFlags)
|
||||
bShouldCheckHospitality = true;
|
||||
|
||||
pNode->iBlock[0] = iNewBlocks[0];
|
||||
pNode->iBlock[1] = iNewBlocks[1];
|
||||
pNode->iBlock[2] = iNewBlocks[2];
|
||||
pNode->iBlock[3] = iNewBlocks[3];
|
||||
|
||||
if(bShouldCheckOwnDoor)
|
||||
{
|
||||
_check_door(L, pMap, iX, iY, 1, 0) ||
|
||||
_check_door(L, pMap, iX, iY, 0, 1);
|
||||
}
|
||||
if(bShouldCheckNeighbourDoors)
|
||||
{
|
||||
_check_door(L, pMap, iX - 1, iY , 1, 0);
|
||||
_check_door(L, pMap, iX , iY - 1, 0, 1);
|
||||
_check_door(L, pMap, iX + 1, iY , 1, 0);
|
||||
_check_door(L, pMap, iX , iY + 1, 0, 1);
|
||||
}
|
||||
|
||||
std::stack<std::pair<int, int> > stkToCheckHospitality;
|
||||
if(bWasCertainlyHospital && !_isCertainlyHospital(pMap, iX, iY))
|
||||
{
|
||||
std::stack<std::pair<int, int> > stkToRemoveHospitality;
|
||||
stkToRemoveHospitality.push(std::make_pair(iX, iY));
|
||||
while(!stkToRemoveHospitality.empty())
|
||||
{
|
||||
int iX = stkToRemoveHospitality.top().first;
|
||||
int iY = stkToRemoveHospitality.top().second;
|
||||
stkToRemoveHospitality.pop();
|
||||
THMapNode *pNode = pMap->getNode(iX, iY);
|
||||
if(pNode && (pNode->iFlags & THMN_Hospital) != 0
|
||||
&& !_isCertainlyHospital(pMap, iX, iY))
|
||||
{
|
||||
stkToCheckHospitality.push(std::make_pair(iX, iY));
|
||||
pNode->iFlags &=~ THMN_Hospital;
|
||||
for(int iDir = 0; iDir <= 1; ++iDir)
|
||||
{
|
||||
for(int iDelta = -1; iDelta <= 1; iDelta += 2)
|
||||
{
|
||||
stkToRemoveHospitality.push(std::make_pair(
|
||||
iX + iDelta * iDir, iY + iDelta * (1 - iDir)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(bShouldCheckHospitality)
|
||||
{
|
||||
stkToCheckHospitality.push(std::make_pair(iX, iY));
|
||||
stkToCheckHospitality.push(std::make_pair(iX - 1, iY ));
|
||||
stkToCheckHospitality.push(std::make_pair(iX , iY - 1));
|
||||
}
|
||||
if(!stkToCheckHospitality.empty())
|
||||
pMap->updatePathfinding();
|
||||
while(!stkToCheckHospitality.empty())
|
||||
{
|
||||
int iX = stkToCheckHospitality.top().first;
|
||||
int iY = stkToCheckHospitality.top().second;
|
||||
stkToCheckHospitality.pop();
|
||||
THMapNode *pNode = pMap->getNode(iX, iY);
|
||||
if(!pNode)
|
||||
continue;
|
||||
bool bShouldBeHospital = false;
|
||||
if(pNode->iFlags & THMN_Passable)
|
||||
{
|
||||
bShouldBeHospital = _isCertainlyHospital(pMap, iX, iY);
|
||||
int iNumHospitalNeighbours = 0;
|
||||
#define CHECK(dir_flag, dx, dy) \
|
||||
if(pNode->iFlags & dir_flag) \
|
||||
{ \
|
||||
iNumHospitalNeighbours += (pMap->getNode(iX + dx, iY + dy) \
|
||||
->iFlags & THMN_Hospital) >> THMN_Hospital_Shift; \
|
||||
}
|
||||
CHECK(THMN_CanTravelN, 0, -1);
|
||||
CHECK(THMN_CanTravelE, 1, 0);
|
||||
CHECK(THMN_CanTravelS, 0, 1);
|
||||
CHECK(THMN_CanTravelW, -1, 0);
|
||||
#undef CHECK
|
||||
if(iNumHospitalNeighbours >= 2)
|
||||
bShouldBeHospital = true;
|
||||
}
|
||||
if(bShouldBeHospital != ((pNode->iFlags & THMN_Hospital) != 0))
|
||||
{
|
||||
if(bShouldBeHospital)
|
||||
{
|
||||
pNode->iFlags |= THMN_Hospital;
|
||||
_check_door_unbuildability(pMap, iX, iY);
|
||||
}
|
||||
else
|
||||
pNode->iFlags &=~ (THMN_Hospital | THMN_Buildable);
|
||||
for(int iDir = 0; iDir <= 1; ++iDir)
|
||||
{
|
||||
for(int iDelta = -1; iDelta <= 1; iDelta += 2)
|
||||
{
|
||||
stkToCheckHospitality.push(std::make_pair(
|
||||
iX + iDelta * iDir, iY + iDelta * (1 - iDir)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void THMapWrapper::_check_door_unbuildability(THMap* pMap, int iX, int iY)
|
||||
{
|
||||
THMapNode *pNode = pMap->getNode(iX, iY);
|
||||
if(!pNode)
|
||||
return;
|
||||
bool bBuildable = (pNode->iFlags & THMN_Hospital) != 0;
|
||||
for(int iDX = -1; iDX <= 1; ++iDX)
|
||||
{
|
||||
for(int iDY = -1; iDY <= 1; ++iDY)
|
||||
{
|
||||
THMapNode *pNode = pMap->getNode(iX + iDX, iY + iDY);
|
||||
if(!pNode || (pNode->iFlags >> 24) != THOB_EntranceRightDoor)
|
||||
continue;
|
||||
bool bIsNorthFacing = (pNode[-1].iFlags >> 24) == THOB_EntranceLeftDoor;
|
||||
if(bIsNorthFacing)
|
||||
{
|
||||
if(iDY != -1)
|
||||
bBuildable = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(iDX != -1)
|
||||
bBuildable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(bBuildable)
|
||||
pNode->iFlags |= THMN_Buildable;
|
||||
else
|
||||
pNode->iFlags &=~ THMN_Buildable;
|
||||
}
|
||||
|
||||
bool THMapWrapper::_check_door(lua_State *L, THMap* pMap, int iX, int iY, int iDX, int iDY)
|
||||
{
|
||||
bool bShouldHaveDoor = false;
|
||||
THMapNode *pNode = pMap->getNode(iX, iY);
|
||||
if(pNode && !(pNode->iBlock[1] & 0xFF) && !(pNode->iBlock[2] & 0xFF))
|
||||
{
|
||||
THMapNode *pFarNode = pMap->getNode(iX - iDX, iY - iDY);
|
||||
THMapNode *pNearNode = pMap->getNode(iX + iDX, iY + iDY);
|
||||
if(pFarNode && pNearNode)
|
||||
{
|
||||
int iFarBlock = pFarNode->iBlock[1 + iDY] & 0xFF;
|
||||
int iNearBlock = pNearNode->iBlock[1 + iDY] & 0xFF;
|
||||
if(iFarBlock == ms_iDoorframeFarExternal + iDY
|
||||
|| iFarBlock == ms_iDoorframeFarInternal + iDY)
|
||||
{
|
||||
if(iNearBlock == ms_iDoorframeNearExternal + iDY
|
||||
|| iNearBlock == ms_iDoorframeNearInternal + iDY)
|
||||
{
|
||||
bShouldHaveDoor = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
THObjectType eNodeThob = (THObjectType)(pNode->iFlags >> 24);
|
||||
bool bGotDoor = eNodeThob == THOB_EntranceLeftDoor ||
|
||||
eNodeThob == THOB_EntranceRightDoor;
|
||||
if(bGotDoor == bShouldHaveDoor)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if(bShouldHaveDoor)
|
||||
{
|
||||
for(int i = 1; i >= 0; --i)
|
||||
{
|
||||
luaT_execute(L, "TheApp.world:newObject(...)",
|
||||
i == 1 ? "entrance_left_door" : "entrance_right_door",
|
||||
iX + 1 - i * iDX,
|
||||
iY + 1 - i * iDY,
|
||||
iDX == 1 ? "north" : "west");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
luaT_execute(L,
|
||||
"local world = TheApp.world\n"
|
||||
"local door = world:getObject(...)\n"
|
||||
"if door then world:destroyEntity(door)\n"
|
||||
"if door.slave then world:destroyEntity(door.slave) end end\n",
|
||||
iX + 1,
|
||||
iY + 1);
|
||||
}
|
||||
for(int iDX = -1; iDX <= 1; ++iDX)
|
||||
{
|
||||
for(int iDY = -1; iDY <= 1; ++iDY)
|
||||
{
|
||||
_check_door_unbuildability(pMap, iX + iDX, iY + iDY);
|
||||
}
|
||||
}
|
||||
return bShouldHaveDoor;
|
||||
}
|
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2010 Peter "Corsix" Cawley
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
// For compilers that support precompilation, includes "wx/wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
// for all others, include the necessary headers (this file is usually all you
|
||||
// need because it includes almost all "standard" wxWidgets headers)
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif
|
||||
// ----------------------------
|
||||
#include "game.h"
|
||||
|
||||
class THMapWrapper
|
||||
{
|
||||
public:
|
||||
//! Wrap around the Map class of a Lua state
|
||||
/*!
|
||||
This should be called at the initialisation time of a Lua state (after
|
||||
luaopen_th has been registered to package.preload, but before any map
|
||||
instances have been created). After calling, all map instances created
|
||||
by the state will have this wrapper around them.
|
||||
*/
|
||||
static void wrap(lua_State *L);
|
||||
|
||||
static void autoSetHelipad(THMap *pMap);
|
||||
|
||||
protected:
|
||||
static int _l_set_cell(lua_State *L);
|
||||
static void _do_set_cell(lua_State *L, THMap* pMap, int iX, int iY, uint16_t iNewBlocks[4]);
|
||||
static bool _check_door(lua_State *L, THMap* pMap, int iX, int iY, int iDX, int iDY);
|
||||
static void _check_door_unbuildability(THMap* pMap, int iX, int iY);
|
||||
|
||||
static const int ms_iDoorframeWallFirst = 157;
|
||||
static const int ms_iDoorframeNearExternal = 157;
|
||||
static const int ms_iDoorframeFarExternal = 159;
|
||||
static const int ms_iDoorframeNearInternal = 161;
|
||||
static const int ms_iDoorframeFarInternal = 163;
|
||||
static const int ms_iDoorframeWallLast = 164;
|
||||
|
||||
static bool _isDoorframe(int iTile);
|
||||
static bool _isPassable(int iTile);
|
||||
static bool _isWall(int iTile);
|
||||
static bool _isCertainlyHospital(THMap* pMap, int iX, int iY);
|
||||
};
|