aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--3p/ms/getopt.c51
-rw-r--r--3p/ms/getopt.h36
-rw-r--r--Makefile2
-rw-r--r--main.c106
-rw-r--r--opt.h23
5 files changed, 81 insertions, 137 deletions
diff --git a/3p/ms/getopt.c b/3p/ms/getopt.c
deleted file mode 100644
index 307baf2..0000000
--- a/3p/ms/getopt.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/* *****************************************************************
-*
-* Copyright 2016 Microsoft
-*
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*
-******************************************************************/
-
-#include "getopt.h"
-#include <windows.h>
-
-char* optarg = NULL;
-int optind = 1;
-
-int getopt(int argc, char *const argv[], const char *optstring)
-{
- if ((optind >= argc) || (argv[optind][0] != '-') || (argv[optind][0] == 0))
- {
- return -1;
- }
-
- int opt = argv[optind][1];
- const char *p = strchr(optstring, opt);
-
- if (p == NULL)
- {
- return '?';
- }
- if (p[1] == ':')
- {
- optind++;
- if (optind >= argc)
- {
- return '?';
- }
- optarg = argv[optind];
- optind++;
- }
- return opt;
-}
diff --git a/3p/ms/getopt.h b/3p/ms/getopt.h
deleted file mode 100644
index 33de8ad..0000000
--- a/3p/ms/getopt.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* *****************************************************************
-*
-* Copyright 2016 Microsoft
-*
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*
-******************************************************************/
-
-#ifndef GETOPT_H__
-#define GETOPT_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern char *optarg;
-extern int optind;
-
-int getopt(int argc, char *const argv[], const char *optstring);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/Makefile b/Makefile
index 94bf072..40fe2a6 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ WARNINGS=-Wall -Wpedantic -Wextra -Wno-gnu-zero-variadic-macro-arguments \
override CFLAGS+=-m32 -flto -I3p -std=c23
override LDFLAGS+=-lmf -lmfplat -lmfuuid -lmfreadwrite -lstrmiids
-OBJS = main.o api.o 3p/sst/x86.o 3p/ms/getopt.o hook.o render.o
+OBJS = main.o api.o 3p/sst/x86.o hook.o render.o
all: rt.exe
rt.exe: $(OBJS)
diff --git a/main.c b/main.c
index 3d89c08..4775b48 100644
--- a/main.c
+++ b/main.c
@@ -19,8 +19,7 @@
#include "log.h"
#include "render.h"
#include "os.h"
-
-#include "ms/getopt.h"
+#include "opt.h"
#include <stddef.h>
#define WIN32_LEAN_AND_MEAN
@@ -29,13 +28,13 @@
struct {
int width;
int height;
- char *game;
+ const char *game;
int fps;
int quality;
int bitrate;
int qvs;
- char *out;
- char **demo;
+ const char *out;
+ const char **demo;
bool combine;
} args = {0};
@@ -81,45 +80,57 @@ void WINAPI *hook_LoadLibraryExA(const char *filename, void *hfile, int flags) {
typedef int (*LauncherMain_t)(void *instance, void *prev_inst, char *cmdline,
int cmd_show);
-int main(int argc, char **argv) {
+void usage() {
+ const char *usage =
+ "usage:\n"
+ " rt [-w <width>] [-h <height>] [-g <game>] [-r <fps>] [-s <qvs>]"
+ "[-1] [-q <quality>] OR [-b <bitrate>]\n"
+ " path/to/video.mp4 path/to/demo1.dem...";
+ puts(usage);
+}
+
+int main(int argc, const char **argv) {
SetDllDirectoryA("bin/");
- int c;
+
char *strend;
- while ((c = getopt(argc, argv, "w:h:g:r:q:b:s:")) != -1) {
- switch (c) {
- case 'w':
- args.width = strtol(optarg, &strend, 10);
- if (strend == optarg) die("width must be a number");
- break;
- case 'h':
- args.height = strtol(optarg, &strend, 10);
- if (strend == optarg) die("height must be a number");
- break;
- case 'r':
- args.fps = strtol(optarg, &strend, 10);
- if (strend == optarg) die("fps must be a number");
- break;
- case 'q':
- args.quality = strtol(optarg, &strend, 10);
- if (strend == optarg || args.quality < 1 || args.quality > 100)
- die("quality must be a number 1-100");
- break;
- case 's':
- args.qvs = strtol(optarg, &strend, 10);
- if (strend == optarg || args.qvs < 1 || args.qvs > 100)
- die("qvs must be a number 1-100");
- break;
- case 'b':
- args.bitrate = strtol(optarg, &strend, 10);
- if (strend == optarg) die("bitrate must be a number");
- break;
- case 'g':
- args.game = optarg;
- case '1':
- args.combine = true;
- case '?':
- break;
- }
+ const char *arg;
+ FOR_OPTS(argc, argv) {
+ case 'w':
+ arg = OPTARG(argc, argv);
+ args.width = strtol(arg, &strend, 10);
+ if (strend == arg) die("width must be a number");
+ break;
+ case 'h':
+ arg = OPTARG(argc, argv);
+ args.height = strtol(arg, &strend, 10);
+ if (strend == arg) die("height must be a number");
+ break;
+ case 'r':
+ arg = OPTARG(argc, argv);
+ args.fps = strtol(arg, &strend, 10);
+ if (strend == arg) die("fps must be a number");
+ break;
+ case 'q':
+ arg = OPTARG(argc, argv);
+ args.quality = strtol(arg, &strend, 10);
+ if (strend == arg || args.quality < 1 || args.quality > 100)
+ die("quality must be a number 1-100");
+ break;
+ case 's':
+ arg = OPTARG(argc, argv);
+ args.qvs = strtol(arg, &strend, 10);
+ if (strend == arg || args.qvs < 1 || args.qvs > 100)
+ die("qvs must be a number 1-100");
+ break;
+ case 'b':
+ arg = OPTARG(argc, argv);
+ args.bitrate = strtol(arg, &strend, 10);
+ if (strend == arg) die("bitrate must be a number");
+ break;
+ case 'g':
+ args.game = OPTARG(argc, argv);
+ case '1':
+ args.combine = true;
}
if (!args.width) args.width = 1280;
@@ -129,15 +140,12 @@ int main(int argc, char **argv) {
if (!args.quality) args.quality = 75;
if (!args.qvs) args.qvs = 100;
- if (argc - optind < 2) {
- printf(
- "usage:\n"
- " rt [-w <width>] [-h <height>] [-g <game>] [-r <fps>] [-s <qvs>] [-1] [-q <quality>] OR [-b <bitrate>]\n"
- " path/to/video.mp4 path/to/demo1.dem...\n");
+ if (argc < 2) {
+ usage();
exit(1);
}
- args.out = argv[optind++];
- args.demo = argv + optind;
+ args.out = argv[0];
+ args.demo = argv + 1;
sprintf(cmdline, "hl2.exe -game %s -w %d -h %d -window -console",
args.game, args.width, args.height);
diff --git a/opt.h b/opt.h
new file mode 100644
index 0000000..0492226
--- /dev/null
+++ b/opt.h
@@ -0,0 +1,23 @@
+// Mike wrote this.
+
+#define FOR_OPTS(argc, argv) \
+ for ( \
+ const char *_p = (--(argc), *++(argv)), *_p1; \
+ argc && *_p == '-' && *++_p && \
+ (*_p != '-' || _p[1] || (++(argv), --(argc), 0)); \
+ _p = *++(argv), --(argc), (void)(_p1) /* suppress unused warning */ \
+ ) \
+ while (*_p) \
+ switch (*_p++) \
+ if (0) default: { \
+ fprintf(stderr, "invalid option: -%c\n", _p[-1]); \
+ usage(); \
+ } \
+ else /* { cases/code here } */
+
+#define OPTARG(argc, argv) \
+ (*_p ? (_p1 = _p, _p = "", _p1) : (*(--(argc), ++(argv)) ? *(argv) : \
+ (fprintf(stderr, "missing argument for option -%c\n", _p[-1]), \
+ usage(), (char *)0)))
+
+// vi: sw=4 ts=4 noet tw=80 cc=80