5.1.1 release #62

Merged
coolestskinnieinthejungle merged 96 commits from 5.1.1 into master 2021-07-21 18:45:22 +00:00
2 changed files with 87 additions and 71 deletions
Showing only changes of commit 3441dbdbf5 - Show all commits

View File

@ -609,46 +609,6 @@ style main_menu_text:
style main_menu_title:
properties gui.text_properties("title")
## Gallery screen ################################################################
##
## This screen holds the Gallery.
##
screen gallery():
tag menu
## This use statement includes the game_menu screen inside this one. The
## vbox child is then included inside the viewport inside the game_menu
## screen.
style_prefix "main_menu"
add gui.main_menu_background
add gui.extras_submenu_panel
frame:
pass
vbox:
xpos 500
yalign 0.2
textbutton "Back to Extras" action ShowMenu("extras")
vbox:
viewport id "gallery":
xpos 700
ypos 1000
style_prefix "gallery"
use images
text _("") ## Not sure why, but this keeps the vbox below working ... Renpy quirk? Does it kill scrolling in the viewport? Tune in when we have the gallery populated in the images screen.
vbox:
xpos 1942
# xalign 1.0
yalign 0.95
use extrasnavigation
style main_menu_frame is empty
style main_menu_vbox is vbox
style main_menu_text is gui_text
@ -675,21 +635,6 @@ style main_menu_title:
properties gui.text_properties("title")
## Images Screen ################################################################
##
## This is the screen that actually houses the images of the gallery
screen images():
tag menu
style_prefix "main_menu"
frame:
pass
vbox:
xpos 600
ypos 600
text _("Placeholder for gallery.")
## Updates screen ################################################################
##
@ -1247,7 +1192,7 @@ screen extrasnavigation():
imagebutton auto "gui/button/menubuttons/helpbutton_%s.png" action ShowMenu("help")
imagebutton auto "gui/button/menubuttons/aboutbutton_%s.png" action ShowMenu("about")
imagebutton auto "gui/button/menubuttons/updatesbutton_%s.png" action ShowMenu("updates")
imagebutton auto "gui/button/menubuttons/gallerybutton_%s.png" action ShowMenu("gallery")
imagebutton auto "gui/button/menubuttons/gallerybutton_%s.png" action ShowMenu("cg_gallery")
imagebutton auto "gui/button/menubuttons/returnbutton_%s.png" action ShowMenu("main_menu")

View File

@ -9,35 +9,47 @@ init python:
# CONST PARAMS
GALLERY_COLS = 3
GALLERY_CGS_PER_PAGE = 6
NOT_UNLOCKED_COVER = im.FactorScale("gui/gallery/unlocked_cg_button_cover.png", 0.225, 0.225)
PREFERRED_WIDTH = 432 #px (1920 * 0.225)
PREFERRED_HEIGHT = 243 #px (1080 * 0.225)
DEFAULT_WIDTH_SCALE_RATIO = round(float(PREFERRED_WIDTH) / float(1920), 5)
DEFAULT_HEIGHT_SCALE_RATIO = round(float(PREFERRED_HEIGHT) / float(1080), 5)
NOT_UNLOCKED_COVER = im.FactorScale("gui/gallery/unlocked_cg_button_cover.png", DEFAULT_WIDTH_SCALE_RATIO, DEFAULT_HEIGHT_SCALE_RATIO)
ACCEPTED_EXTENSIONS = ["jpg", "png"]
# GALLERY ITEMS
# Data structure that holds the data for each cg and button
# item is the key in the Gallery
# { item: string; cg: Displayable; }[]
# ext is the file extension
# { item: string; cg: Displayable; ext: string }[]
galleryItems = []
# Which page of the gallery is shown
galleryPage = 1
# Global function to unlock a cg
# fname should be a key used in galleryItems
# (fname: string): None
def unlockCg(fname):
unlocked = fname in persistent.cggallery
if not unlocked:
persistent.cggallery.append(fname)
renpy.persistent.save()
for i in range(0, len(galleryItems) - 1):
# TODO: raise Exception(galleryItems[i])
# Make a scaled cg button
# (cg: string, unlocked?: boolean): Displayable
def cg(fname, unlocked = False):
# (cg: string; ext: string; w: float; h: float; unlocked?: boolean): Displayable
def cg(fname, ext, w, h, unlocked = False):
if not unlocked:
return NOT_UNLOCKED_COVER
return im.FactorScale("images/cgs/" + fname + ".png", 0.225, 0.225)
scaleFactor = getBoxNormalizerRatio(w, h)
return im.FactorScale("images/cgs/" + fname + "." + ext, scaleFactor["x"], scaleFactor["y"])
# Create an object in g:Gallery, add to galleryItems
# (imageName: string; unlocked?: boolean): None
def addGalleryItem(imageName, unlocked = False):
# (imageName: string; ext: string; w: float; h: float; unlocked?: boolean): None
def addGalleryItem(imageName, ext, w, h, unlocked = False):
g.button(imageName)
g.image(imageName)
@ -49,7 +61,7 @@ init python:
galleryItems.append({
"item": imageName,
"cg": cg(imageName, unlocked)
"cg": cg(imageName, ext, w, h, unlocked)
})
# Reads /images/cgs dir for all .png files
@ -64,24 +76,83 @@ init python:
workingDirPath = getcwd().replace("\\", "/")
cgDirPath = workingDirPath + "/game/" + cgPath
# Add each .png to the gallery
# TODO: make case insensitive
# Add each image to the gallery
galleryItems = []
for cgFile in listdir(cgDirPath):
if isfile(join(cgDirPath, cgFile)):
if (cgFile[-4:] == '.png'):
filePath = join(cgDirPath, cgFile)
if isfile(filePath):
ext = cgFile[-3:].lower()
if (ext in ACCEPTED_EXTENSIONS):
attr = getImageFileAttributes(filePath)
fname = str(cgFile[0:-4])
unlocked = fname in persistent.cggallery
addGalleryItem(fname, unlocked)
addGalleryItem(fname, ext, attr["w"], attr["h"], unlocked)
# Add empty items to fill grid after last cg button
extraSpaces = GALLERY_COLS - (len(galleryItems) % GALLERY_COLS)
for i in range(0, extraSpaces):
galleryItems.append({
"item": None,
"cg": None
"cg": None,
"ext": None
})
# Get width/height of image by absolute path
# based on https://stackoverflow.com/questions/8032642/how-to-obtain-image-size-using-standard-python-class-without-using-external-lib
# (filePath: string) -> { w: int; h: int } | None
def getImageFileAttributes(filePath):
try:
from struct import unpack
from imghdr import what
w, h = 0, 0
with open(filePath, "rb") as file:
ext = what(filePath)
header = file.read(24)
if (len(header) != 24):
raise Exception("File header invalid for " + filePath)
if (ext == 'png'):
checksum = unpack('>i', header[4:8])[0]
if (checksum != 0x0d0a1a0a):
raise Exception("File checksum invalid for " + filePath)
w, h = unpack('>ii', head[16:24])
if (ext == 'jpeg' or ext == 'jpg'):
file.seek(0)
size = 2
ftype = 0
while not 0xc0 <= ftype <= 0xcf:
file.seek(size, 1)
byte = file.read(1)
while ord(byte) == 0xff:
byte = file.read(1)
ftype = ord(byte)
size = unpack('>H', file.read(2))[0] - 2
file.seek(1, 1)
h, w = unpack('>HH', file.read(4))
return { "w": w, "h": h }
except Exception:
#TODO: log error
return None
# Returns what params to call im.FactorScale with for cg button size
# Basically the delta diff dimensions
# (w: int; h: int) -> { x: float; y: float }
def getBoxNormalizerRatio(w, h):
x = round(float(PREFERRED_WIDTH) / float(w), 4)
y = round(float(PREFERRED_HEIGHT) / float(h), 4)
return { "x": x, "y": y }
# Returns the pageth slice from galleryItems
# (page: int): Partial<typeof galleryItems>
def getGalleryPage(page):
@ -98,7 +169,7 @@ init python:
## A screen that shows the image gallery
screen cg_gallery():
tag menu
use game_menu(_("Gallery")):
use game_menu(_("Gallery"), scroll="viewport"):
fixed:
$ pageItems = getGalleryPage(galleryPage)