Skip to content
This repository has been archived by the owner on Apr 15, 2024. It is now read-only.

Commit

Permalink
Merge branch 'release/3.2.0' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
neogeographica committed Jul 10, 2022
2 parents 9165dde + 2991672 commit 0787fad
Show file tree
Hide file tree
Showing 29 changed files with 604 additions and 86,491 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
*.pyc
devtools/release.*
devtools/engine-staging/
quakestarter-*.zip
*_results/
_build/
Expand Down
125 changes: 100 additions & 25 deletions devtools/release.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python3

import contextlib
import filecmp
import os
import shutil
import subprocess
Expand All @@ -24,10 +25,14 @@

RELEASE_FOLDER = "release." + str(os.getpid())
QUAKE_FOLDER = os.path.join(RELEASE_FOLDER, "Quake")
QSS_VERSION = "2021-10-14"
QSS_URL = "https://triptohell.info/moodles/qss/quakespasm_spiked_win64_dev.zip"
QSS_LOCALFILE = "qss-temp.zip"
ENGINE_STAGING_FOLDER = "engine-staging"
VKQ_VERSION = "1.20.3"
IW_VERSION = "0.6.0"
SQL_VERSION = "2.5"
VKQ_URL = "https://github.com/Novum/vkQuake/releases/download/{0}/vkquake-{0}_win64.zip".format(VKQ_VERSION)
VKQ_LOCALFILE = "vkq-temp.zip"
IW_URL = "https://github.com/andrei-drexler/ironwail/releases/download/v{0}/ironwail-{0}-win64.zip".format(IW_VERSION)
IW_LOCALFILE = "iw-temp.zip"
SQL_URL = "https://github.com/m-x-d/Simple-Quake-Launcher-2/releases/download/{0}/SQLauncher_{0}.zip".format(SQL_VERSION)
SQL_LOCALFILE = "sql-temp.zip"
EXCLUSIONS = [
Expand All @@ -39,20 +44,19 @@
"README.md"
]

def handle_zip(url, localfile):
def handle_zip(url, localfile, destdir):
with contextlib.closing(urllib.request.urlopen(url)) as instream:
with open(localfile, 'wb') as outstream:
outstream.write(instream.read())
latest_year = 1970
latest_month = 1
timestamp = "???"
with zipfile.ZipFile(localfile, 'r') as zf:
zip_contents = zf.namelist()
for i in zf.infolist():
zf.extract(i, QUAKE_FOLDER)
zf.extract(i, destdir)
time_tuple = i.date_time + (0, 0, -1)
date_time = time.mktime(time_tuple)
os.utime(os.path.join(QUAKE_FOLDER, i.filename), (date_time, date_time))
os.utime(os.path.join(destdir, i.filename), (date_time, date_time))
year = i.date_time[0]
month = i.date_time[1]
if year > latest_year:
Expand All @@ -64,7 +68,7 @@ def handle_zip(url, localfile):
latest_month = month
timestamp = time.strftime("%B %Y", time_tuple)
os.remove(localfile)
return zip_contents, timestamp
return timestamp

def gen_toplevel_readme():
with open(os.path.join(RELEASE_FOLDER, "how_to_use_quakestarter.txt"), 'w', newline='\r\n') as f:
Expand All @@ -81,15 +85,19 @@ def gen_toplevel_readme():
all sorts of topics about Quake singleplayer.
""")

def gen_readme(readme_contents, qss_timestamp, sql_timestamp, timestamp):
def gen_readme(readme_contents, vkq_timestamp, iw_timestamp, sql_timestamp, timestamp):
new_readme_contents= []
for line in readme_contents:
if (qss_timestamp == "") and ("###QSS_VERSION###" in line):
if (vkq_timestamp == "") and ("###VKQ_VERSION###" in line):
pass
elif (iw_timestamp == "") and ("###IW_VERSION###" in line):
pass
else:
new_line = line.replace(
"###QSS_VERSION###", QSS_VERSION).replace(
"###QSS_TIMESTAMP###", qss_timestamp).replace(
"###VKQ_VERSION###", VKQ_VERSION).replace(
"###VKQ_TIMESTAMP###", vkq_timestamp).replace(
"###IW_VERSION###", IW_VERSION).replace(
"###IW_TIMESTAMP###", iw_timestamp).replace(
"###SQL_VERSION###", SQL_VERSION).replace(
"###SQL_TIMESTAMP###", sql_timestamp).replace(
"###TIMESTAMP###", timestamp)
Expand All @@ -113,9 +121,13 @@ def patch_autoexec():
for line in autoexec_contents:
if line.lower().startswith("host_maxfps "):
new_autoexec_contents.append(
"// Since this package does not include Quakespasm-Spiked, this setting is\r\n")
"// Since this package does not include any particular Quake engine, this\r\n")
new_autoexec_contents.append(
"// setting is commented out for safety. If you know that your chosen Quake\r\n")
new_autoexec_contents.append(
"// commented out for safety. Remove the leading doubleslash to activate it.\r\n")
"// engine can support high framerates without errors, you can remove the\r\n")
new_autoexec_contents.append(
"// leading doubleslash before this setting to activate it.\r\n")
new_autoexec_contents.append("//" + line)
else:
new_autoexec_contents.append(line)
Expand All @@ -127,37 +139,100 @@ def unpatch_autoexec():
autoexec_path = os.path.join(QUAKE_FOLDER, "id1", "autoexec.cfg.example")
shutil.move("autoexec.cfg.example.bak", autoexec_path)

def merge_files(source_a_name, source_a_dir, source_b_name, source_b_dir):
def extracted_files(source_dir):
source_files = os.listdir(source_dir)
if len(source_files) == 0:
print("WARNING: {} is empty!".format(source_dir))
elif len(source_files) == 1:
new_root = os.path.join(source_dir, source_files[0])
if os.path.isdir(new_root):
return extracted_files(new_root)
return [os.path.join(source_dir, f) for f in source_files]
source_a_files = extracted_files(source_a_dir)
source_b_files = extracted_files(source_b_dir)
for f in source_a_files:
shutil.copy2(f, QUAKE_FOLDER)
for f in source_b_files:
f_base = os.path.basename(f)
f_dest = os.path.join(QUAKE_FOLDER, f_base)
if os.path.exists(f_dest):
if filecmp.cmp(f, f_dest, shallow=False):
continue
if os.stat(f).st_mtime < os.stat(f_dest).st_mtime:
print("NOTE: file {} taken from {} since it is newer".format(f_base, source_a_name))
continue
print("NOTE: file {} taken from {} since it is newer".format(f_base, source_b_name))
shutil.copy2(f, QUAKE_FOLDER)
source_a_set = set([os.path.basename(f) for f in source_a_files])
source_b_set = set([os.path.basename(f) for f in source_b_files])
common_set = source_a_set & source_b_set
source_a_unique_set = source_a_set - common_set
source_b_unique_set = source_b_set - common_set
manifest_lines = [
"files unique to {}:\r\n".format(source_a_name),
"\r\n"
]
manifest_lines += [f + "\r\n" for f in source_a_unique_set]
manifest_lines += [
"\r\n"
"files unique to {}:\r\n".format(source_b_name),
"\r\n"
]
manifest_lines += [f + "\r\n" for f in source_b_unique_set]
manifest_lines += [
"\r\n"
"files used in both {} and {}:\r\n".format(source_a_name, source_b_name),
"\r\n"
]
manifest_lines += [f + "\r\n" for f in common_set]
return manifest_lines

def gen_release():
try:
shutil.rmtree(RELEASE_FOLDER)
except FileNotFoundError:
pass
try:
shutil.rmtree(ENGINE_STAGING_FOLDER)
except FileNotFoundError:
pass
os.mkdir(RELEASE_FOLDER)
os.mkdir(ENGINE_STAGING_FOLDER)
vkq_staging = os.path.join(ENGINE_STAGING_FOLDER, "vkq")
iw_staging = os.path.join(ENGINE_STAGING_FOLDER, "iw")
os.mkdir(vkq_staging)
os.mkdir(iw_staging)
def exclusions_for_copy(dir, contents):
if os.path.realpath(dir) != SRC_PATH:
return []
return EXCLUSIONS
shutil.copytree(SRC_PATH, QUAKE_FOLDER, ignore=exclusions_for_copy)
gen_toplevel_readme()
gen_docs()
_, sql_timestamp = handle_zip(SQL_URL, SQL_LOCALFILE)
sql_timestamp = handle_zip(SQL_URL, SQL_LOCALFILE, QUAKE_FOLDER)
print("SQL2 version: {}".format(SQL_VERSION))
print("SQL2 timestamp: {}".format(sql_timestamp))
timestamp = time.strftime("%B %Y")
print("Quakestarter release: {}".format(RELEASE))
print("Quakestarter timestamp: {}".format(timestamp))
with open(os.path.join(QUAKE_FOLDER, "quakestarter_readme.html"), 'r') as f:
readme_contents = f.readlines()
gen_readme(readme_contents, "", sql_timestamp, timestamp)
gen_readme(readme_contents, "", "", sql_timestamp, timestamp)
release_name = "quakestarter-noengine-" + RELEASE
patch_autoexec()
shutil.make_archive(release_name, "zip", root_dir=RELEASE_FOLDER, base_dir=".")
unpatch_autoexec()
qss_zip_contents, qss_timestamp = handle_zip(QSS_URL, QSS_LOCALFILE)
print("QSS version: {}".format(QSS_VERSION))
print("QSS timestamp: {}".format(qss_timestamp))
gen_readme(readme_contents, qss_timestamp, sql_timestamp, timestamp)
qss_manifest = [ l + '\r\n' for l in qss_zip_contents ]
qss_manifest.insert(0, "\r\n")
qss_manifest.insert(0, "manifest of Quakespasm-Spiked files:\r\n")
with open(os.path.join(QUAKE_FOLDER, "qss_manifest.txt"), 'w') as f:
f.writelines(qss_manifest)
vkq_timestamp = handle_zip(VKQ_URL, VKQ_LOCALFILE, vkq_staging)
print("VKQ version: {}".format(VKQ_VERSION))
print("VKQ timestamp: {}".format(vkq_timestamp))
iw_timestamp = handle_zip(IW_URL, IW_LOCALFILE, iw_staging)
print("IW version: {}".format(IW_VERSION))
print("IW timestamp: {}".format(iw_timestamp))
gen_readme(readme_contents, vkq_timestamp, iw_timestamp, sql_timestamp, timestamp)
manifest_lines = merge_files("vkQuake", vkq_staging, "ironwail", iw_staging)
with open(os.path.join(QUAKE_FOLDER, "engines_manifest.txt"), 'w') as f:
f.writelines(manifest_lines)
release_name = "quakestarter-" + RELEASE
shutil.make_archive(release_name, "zip", root_dir=RELEASE_FOLDER, base_dir=".")
shutil.rmtree(RELEASE_FOLDER)
Expand Down
16 changes: 9 additions & 7 deletions docsource/basic/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ Configuration
Using the Quake menus
---------------------

It's good to run Quake at least once before playing any custom content, to set up your desired Quake configuration. You can do this from the third option of the main Quakestarter menu. Or you can just run your Quake executable (e.g. "quakespasm-spiked-win64.exe") from Windows.
It's good to run Quake at least once before playing any custom content, to set up your desired Quake configuration. You can do this from the fourth option of the main Quakestarter menu. Or you can just run your Quake executable (e.g. "vkQuake.exe" or "ironwail.exe") from Windows.

If this fails with an error dialog about "W_LoadWadFile: couldn't load gfx.wad" then your pak files (game data) are not present. You might need to go back to the :ref:`"Game data"<basic/installation:game data>` section of the Installation chapter.

(If Quake fails to start because you have a 32-bit OS, you're going to need to use a different, 32-bit Quake engine. Changing your Quake engine is covered in the :doc:`Advanced Configuration<../other_stuff/advanced_quakestarter_cfg>` chapter. Note that Quakespasm-Spiked does have a 32-bit version if you want to use that.)
(If Quake fails to start because you have a 32-bit OS, you're going to need to use a different, 32-bit Quake engine. Adding a new Quake engine is covered in the :doc:`Advanced Configuration<../other_stuff/advanced_quakestarter_cfg>` chapter. Both vkQuake_ and Ironwail_ do have 32-bit versions that you can download from their sites.)

Any settings that you configure in the default Quake game will be used as a starting point when you later launch custom content.
Note that vkQuake and Ironwail store their menu-controlled settings in different files, so any changes you through the menus of one of these engines will *not* automatically apply if you switch to using the other one.

The menus in Quakespasm-Spiked and many other Quake engines are fairly bare-bones, but you can get your video settings, movement keys, mouse sensitivity, and a few other fundamental things configured there.
The most important point though is that any settings you configure for the original Quake campaign will be used as a starting point when you later launch custom content (with the same Quake engine). So now is the time to get your controls, graphics settings, volume, etc. set up the way you like it!


Using autoexec.cfg
Expand All @@ -28,13 +28,13 @@ If you don't already have your own "autoexec.cfg" file, you can rename the "auto

A summary of what you can do with the settings shown in those files: unlock a higher framerate, disable autoaim, get a crosshair, configure "pixely textures", adjust weapon position to be more "authentic", configure old-style square particles, change the amount of water transparency, and/or revert to old-style jerky animations.

Note that if you use the in-game menus to affect some setting that you also have in your "autoexec.cfg" file, the "autoexec.cfg" value is the one that will be restored next time Quake starts.
Note that if you use the in-game menus to affect some setting that you also have in your "autoexec.cfg" file, the "autoexec.cfg" value is the one that will be restored next time Quake starts... the contents of "autoexec.cfg" always take priority over anything set through the menus. This is true regardless of which Quake engine you are using.


Using the Quake console and config files
----------------------------------------

Many other settings are available. You can also keybind other actions beyond what the menus allow -- for example if you want to have a special key for selecting the rocket launcher. There's a few ways you can edit these other settings and keybindings, including changing them interactively using the Quake console or by editing config files.
Many other settings are available. You can also keybind other actions beyond what the menus allow. There's a few ways you can edit these other settings and keybindings, including changing them interactively using the Quake console or by editing config files.

The "about Quake config files" section of "autoexec-cfg-example-annotated.txt" discusses the config file situation a bit more. Beyond that, these docs won't get into a lot of detail about Quake configuration; if you're interested there are lots of Web resources such as:

Expand All @@ -46,11 +46,13 @@ The "about Quake config files" section of "autoexec-cfg-example-annotated.txt" d
Quakestarter configuration
--------------------------

Besides configuring Quake itself, you may also want to change the behavior of Quakestarter. This includes changing what Quake engine you want to use (if you don't want to use Quakespasm-Spiked) and several other things about how addons are downloaded, installed, and launched.
Besides configuring Quake itself, you may also want to change the behavior of Quakestarter. This includes adding a new Quake engine to use (if you don't want to use vkQuake or Ironwail) and several other things about how addons are downloaded, installed, and launched.

Quakestarter should work fine out-of-the-box without changing any of that configuration, but if you want to dig in, see the :doc:`Advanced Configuration<../other_stuff/advanced_quakestarter_cfg>` chapter (under Other Topics).


.. _vkQuake: https://github.com/Novum/vkQuake
.. _Ironwail: https://github.com/andrei-drexler/ironwail
.. _keybinding guide: https://quake.fandom.com/wiki/Quick_Weapon_Selection
.. _a complete list of settings/commands: https://www.quakewiki.net/archives/console/commands/quake.html
.. _this Steam guide: https://steamcommunity.com/sharedfiles/filedetails/?id=120426294
Loading

0 comments on commit 0787fad

Please sign in to comment.