"Initial" commit. Move to tbuild build system.

Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
Slendi 2023-03-21 21:56:04 +02:00
commit 7baec828c4
No known key found for this signature in database
GPG Key ID: D4F62D3533AB5EA1
13 changed files with 1359 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
build
output

27
LICENSE.md Normal file
View File

@ -0,0 +1,27 @@
# DON'T BE A DICK PUBLIC LICENSE
> Version 1.1, December 2016
> Copyright (C) 2022 Slendi <slendi@socopon.com>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document.
> DON'T BE A DICK PUBLIC LICENSE
> TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
1. Do whatever you like with the original work, just don't be a dick.
Being a dick includes - but is not limited to - the following instances:
1a. Outright copyright infringement - Don't just copy this and change the name.
1b. Selling the unmodified original with no work done what-so-ever, that's REALLY being a dick.
1c. Modifying the original work to contain hidden harmful content. That would make you a PROPER dick.
2. If you become rich through modifications, related works/services, or supporting the original work,
share the love. Only a dick would make loads off this work and not buy the original work's
creator(s) a pint.
3. Code is provided with no warranty. Using somebody else's code and bitching when it goes wrong makes
you a DONKEY dick. Fix the problem yourself. A non-dick would submit the fix back.

16
README.md Normal file
View File

@ -0,0 +1,16 @@
TempleOS Wordle
===============
What's this?
------------
This is a TempleOS and ZealOS exclusive guessing game.
Where do I get this from?
-------------------------
You can download one of the latest releases from (here)[https://git.templeos.me/slendi/wordletos/releases] or you can build it yourself using (tbuilld)[https://git.templeos.me/slendi/tbuild].
LICENSE
-------
This software is licensed under the DBAD license. Click [here](LICENSE.md) for more details.

39
src/HolyC.HC Normal file
View File

@ -0,0 +1,39 @@
// This file contains utility functions
U0 GrChar(CDC *dc=gr.dc, U8 ch, I64 x, I64 y, I64 scale=1)
{
I64 i,j,k=0;
for (i=0; i<FONT_HEIGHT; i++) {
for (j=0; j<FONT_WIDTH; j++) {
if (Bt(&text.font[ch],k++)) {
GrRect(dc, x+j*scale, y+i*scale, scale, scale);
}
}
}
}
U0 GrRndRect(CDC *dc=gr.dc, I64 x, I64 y, I64 w, I64 h, I64 rad)
{ // Draw a rounded rectangle, rad is the radius
GrFillCircle(dc, x, y, , rad*2);
GrFillCircle(dc, x+w, y, , rad*2);
GrFillCircle(dc, x, y+h,, rad*2);
GrFillCircle(dc, x+w, y+h,, rad*2);
GrRect(dc, x, y-rad, w, h+(rad*2));
GrRect(dc, x-rad, y, w+(rad*2), h);
}
I64 RandRng(I64 min=0, I64 max)
{
return min+(Rand() * (max-min-1));
}
Bool U8InStr(U8 ch, U8 *str)
{
I64 i;
for (i=0; i<StrLen(str); i++) {
if (ch == str[i]) {
return TRUE;
}
}
return FALSE;
}

8
src/Install.HC Normal file
View File

@ -0,0 +1,8 @@
// TODO: Add support for multiple partitions, not just C:
if (!FileFind("C:/Apps/Wordle",,FUF_JUST_DIRS)) {
"Installing...\n";
DirMk("C:/Apps/Wordle");
} else "Updating...\n";
CopyTree("T:/", "C:/Apps/Wordle");
Del("C:/Apps/Wordle/RunCD.*");
"Done!\n";

6
src/Load.HC Normal file
View File

@ -0,0 +1,6 @@
#help_index "Games"
Cd(__DIR__);;
#include "Wordle"
#help_index ""

19
src/Palette.HC Normal file
View File

@ -0,0 +1,19 @@
U0 WordleDark()
{
GrPaletteColorSet(WHITE, 0x222222222222);
GrPaletteColorSet(BLACK, 0xffffffffffff);
GrPaletteColorSet(LTGRAY, 0x3a3a3a3a3a3a);
GrPaletteColorSet(BLUE, 0x0f0f0f0f0f0f);
GrPaletteColorSet(GREEN, 0x000061610a0a);
GrPaletteColorSet(YELLOW, 0x91916f6f0000);
}
U0 WordleLight()
{
GrPaletteColorSet(WHITE, 0xffffffffffff);
GrPaletteColorSet(BLACK, 0x222222222222);
GrPaletteColorSet(LTGRAY, 0xc0c0c0c0c0c0);
GrPaletteColorSet(BLUE, 0xe3e3e3e3e3e3);
GrPaletteColorSet(GREEN, 0x8383ffff7d7d);
GrPaletteColorSet(YELLOW, 0xfffff2f27d7d);
}

24
src/PaletteZeal.ZC Normal file
View File

@ -0,0 +1,24 @@
U0 GrPaletteColorSet(I32 idx, CBGR24 col)
{
gr_palette[idx] = col;
}
U0 WordleDark()
{
GrPaletteColorSet(WHITE, 0x222222);
GrPaletteColorSet(BLACK, 0xffffff);
GrPaletteColorSet(LTGRAY, 0x3a3a3a);
GrPaletteColorSet(BLUE, 0x0f0f0f);
GrPaletteColorSet(GREEN, 0x00610a);
GrPaletteColorSet(YELLOW, 0x916f00);
}
U0 WordleLight()
{
GrPaletteColorSet(WHITE, 0xffffff);
GrPaletteColorSet(BLACK, 0x222222);
GrPaletteColorSet(LTGRAY, 0xc0c0c0);
GrPaletteColorSet(BLUE, 0xe3e3e3);
GrPaletteColorSet(GREEN, 0x83ff7d);
GrPaletteColorSet(YELLOW, 0xfff27d);
}

4
src/Run.HC Normal file
View File

@ -0,0 +1,4 @@
Cd(__DIR__);;
#include "Load"
"Running...\n";
Wordle;

3
src/RunCD.HC Normal file
View File

@ -0,0 +1,3 @@
#include "Wordle"
"Running from CD...\n";
Wordle;

875
src/Vocab.TXT Normal file
View File

@ -0,0 +1,875 @@
abase
abhor
abide
abler
abode
about
above
abuse
abyss
aches
acted
actor
acute
adapt
added
admit
afric
after
again
agito
agony
agree
ahead
aided
alike
alive
allay
allow
alloy
aloft
alone
along
aloud
altar
alter
amend
amiss
among
ample
angel
anger
angry
apart
apply
aptly
arise
armed
arose
array
ascii
ashes
aside
asked
aught
avail
avert
avoid
awake
aware
awful
awoke
babes
backs
badge
balls
bands
bared
based
bathe
baths
beams
bears
beast
began
begat
beget
begin
begun
being
belly
below
bends
beset
bible
birds
birth
black
blade
blame
bless
blest
blind
blood
bloom
blunt
blush
boast
boils
bonds
bones
books
borne
bosom
bound
bowed
brain
bread
break
bribe
bride
bring
broad
broke
brows
brute
built
bulky
burnt
burst
cakes
calls
canst
cared
cares
carry
cases
casts
catch
cause
caves
cease
chain
chair
chant
cheap
check
cheer
chest
chief
child
chill
chose
claim
clasp
class
clave
clean
clear
climb
cloak
close
cloud
coals
coats
codes
comes
costs
couch
could
count
court
cover
cower
creep
crept
cried
cries
crime
cross
crown
cruel
cubit
cured
daily
danae
dared
dares
dates
david
dealt
death
debts
decay
deeds
deeps
deity
delay
depth
devil
didst
dieth
doest
doing
doors
doted
doubt
drank
drawn
draws
dread
dream
dried
drink
drive
drops
drove
drunk
dully
durst
dwell
dwelt
dying
eager
eagle
early
earth
eased
eaten
edged
edify
egypt
eight
elder
elect
email
empty
enact
ended
enemy
enjoy
enter
equal
erred
error
essay
etext
every
evils
exact
excel
exist
extol
exude
exult
fable
faced
faces
facio
facts
faint
faith
falls
false
fancy
fared
fault
fears
feast
feeds
feels
fence
fever
field
fifth
fifty
fight
files
filth
final
finds
fired
fires
first
fixed
flame
flash
flesh
flies
fling
flock
flood
flour
flown
flows
flung
folks
folly
fools
force
forge
forms
forth
forum
fouls
found
fowls
frame
fraud
freed
fresh
front
fruit
fully
fumed
fumes
gains
gales
games
gates
ghost
giant
gifts
girls
given
giver
gives
glass
gleam
glide
glory
glows
goads
godly
goest
goeth
going
goods
grace
grant
grasp
grass
grave
great
greek
green
greet
grief
groan
groat
gross
grown
guess
guide
guilt
habit
hadst
hairs
haled
hands
haply
happy
harsh
harts
haste
hated
haunt
heads
heaps
heard
hears
heart
heavy
hence
herbs
hills
holds
homer
honey
honor
hooks
hoped
hopes
horns
horse
hosts
hotly
hours
house
human
husks
hymns
idaho
ideas
idols
image
imbue
imply
infer
inner
irons
isaac
issue
italy
items
jacob
jests
jesus
joint
joyed
judge
keeps
kinds
kings
knees
knock
knots
known
knows
laden
lands
large
later
lathe
latin
laugh
laxly
leads
leaps
learn
least
leave
legal
lends
lieth
lifts
light
liked
liker
likes
limbs
limed
lined
lines
links
lists
lived
lives
loads
lofty
logic
login
longs
looks
loose
lords
loses
loved
lover
loves
lower
lowly
lucid
lucre
lungs
lures
lusts
lying
madly
maker
makes
manna
marks
marry
marts
mazes
means
meant
meats
medea
meets
mercy
merry
metre
might
milan
milky
mimic
minds
mirth
mists
modes
moist
monad
money
month
moral
moses
mould
mount
mourn
mouth
moved
muddy
music
nails
naked
named
names
needs
needy
nests
never
night
ninth
noble
noise
north
noted
notes
nurse
obeys
occur
ocean
odour
offer
often
ofthe
opens
order
ostia
other
ought
outer
owing
pages
pains
pairs
pangs
paper
pared
parts
party
paths
pause
peace
pearl
pears
penal
pence
peril
petty
piece
piety
piled
pines
pious
pitch
place
plain
plans
plant
plays
plead
plots
pluck
poems
poesy
poets
point
poise
power
press
price
pride
print
prior
prize
promo
proof
prose
proud
prove
psalm
pulse
purer
pusey
queen
quest
quick
quiet
quite
quoth
races
racks
raged
raise
range
rates
raven
reach
reads
ready
rebel
recur
refer
reins
renew
repay
repel
reply
right
riper
risen
rites
rocks
roman
rough
round
rouse
ruled
ruler
rules
safer
sails
saint
saith
sakes
sated
saved
scorn
seats
seeks
seems
seest
seeth
seize
sense
serve
seven
sever
shade
shady
shake
shall
shalt
shame
shape
share
sharp
sheep
shine
ships
shoes
shone
shook
shoot
shops
shore
short
shown
shows
shuns
sides
siege
sighs
sight
signs
silly
since
sings
sinks
sites
sixth
skies
skill
skins
slain
slave
sleep
slept
sloth
small
smell
smile
smoke
snare
sober
sodom
solid
solve
songs
sores
sorry
sorts
souls
sound
south
space
spake
spare
speak
speed
spend
spent
spoil
spoke
sport
spots
spurn
staff
stage
stand
stank
stars
start
state
stays
stead
steal
steep
steer
steps
stick
stiff
still
stole
stone
stood
stoop
store
storm
story
stuck
study
stuff
stung
style
subdu
sweat
sweet
swept
swift
swine
swoon
sword
table
taken
takes
tales
tamed
tamer
tardy
taste
taunt
taxes
teach
tears
teeth
tells
tempt
tends
tenet
tenor
terms
texas
texts
thank
theft
their
there
these
thick
thief
thine
thing
think
third
those
three
tides
tilde
times
tired
title
token
tones
total
touch
tower
trace
track
trade
tread
treat
trees
trial
tried
trine
troop
truer
truly
trust
truth
tully
turns
tutor
twice
twins
under
undid
union
unity
until
upper
urged
usage
users
useth
using
usual
usury
utter
value
vaunt
venus
verse
vexed
vices
villa
viper
virus
vital
vivid
vocal
voice
vowed
waged
wages
walks
walls
wants
waste
watch
water
waver
waves
weary
weeps
weigh
wheat
wheel
where
which
while
white
whole
whose
whoso
widow
wills
winds
windy
wings
wiser
wives
woman
women
wooed
words
wordy
works
world
worse
would
wound
wrath
wring
write
wrong
wrote
wroth
years
yield
young
youth

330
src/Wordle.HC Normal file
View File

@ -0,0 +1,330 @@
// I use () for empty functions because I want syntax highlighting on GitHub and my code editor.
// The Generate.ps1 script does a quick search and replace to remove those.
#include "HolyC"
#include "Palette"
U8 *version = "v1.0.0";
"Wordle by xSlendiX - %s\n", version;
"Defines ";
#define LT_EMP 0
#define LT_OK 1
#define LT_POS 2
#define LT_SEL 3
#define LT_SZ (20)
#define LT_RAD (10)
#define LT_CX ((LT_SZ+(LT_RAD*2))/2)
#define LT_CY ((LT_SZ+(LT_RAD*2))/2)
#define LT_FSCALE (3)
#define LT_OFFX (-1)
#define LT_OFFY (0)
#define LT_FHALF (LT_FSCALE/2)
#define LT_SPACING (2)
#define WDEPTH 5
#define WLEN 5
#define W_NONE 0
#define W_WIN 1
#define W_FAIL 2
#define DIALOGW (FONT_WIDTH*30)
#define DIALOGH (FONT_HEIGHT*7)
"Vars ";
U8 **wwords = NULL;
I64 wcnt = 0;
U8 *gameTable = NULL;
U8 *word;
I64 win=W_NONE;
I64 cdepth=0;
I64 gcheats=OFF;
U8 wdark=ON;
//#include "Settings"
"Funcs ";
// Adapted from GodInit
I64 WordInit(U8 *file="Vocab.TXT")
{
I64 i,ch,count;
U8 *buf,*ptr,*ptr2;
i=0;
if (buf=ptr=FileRead(file)) {
while (*ptr) {
while (*ptr && !Bt(char_bmp_word,*ptr))
ptr++;
if (*ptr) {
while (*ptr && Bt(char_bmp_word,*ptr))
ptr++;
i++;
}
}
Free(buf);
}
count=i;
wwords=MAlloc(count*sizeof(U8 *));
i=0;
if (buf=ptr=FileRead(file)) {
while (*ptr) {
while (*ptr && !Bt(char_bmp_word,*ptr))
ptr++;
if (*ptr) {
ptr2=ptr;
while (*ptr && Bt(char_bmp_word,*ptr))
ptr++;
ch=*ptr;
*ptr=0;
wwords[i]=StrNew(ptr2);
i++;
*ptr=ch;
}
}
Free(buf);
}
return count;
}
U0 DrawLetter(CDC *dc=gr.dc, U8 ch, I64 type, I64 x, I64 y)
{
I64 pcol=dc->color;
switch(type) {
case LT_OK: dc->color = GREEN; break;
case LT_POS: dc->color = YELLOW; break;
case LT_SEL: dc->color = BLUE; break;
case LT_EMP:
default: dc->color = LTGRAY;
}
GrRndRect(dc, LT_RAD+x, LT_RAD+y, LT_SZ, LT_SZ, LT_RAD);
dc->color=BLACK;
// FIXME: Buggy, needs better math
GrChar(dc, ch, x+LT_OFFX+(LT_CX-LT_FHALF)/2, y+LT_OFFY+(LT_CY-LT_FHALF)/2, LT_FSCALE);
dc->color=pcol;
}
U0 DrawWin(CDC *dc)
{
if (win == W_NONE) return;
I64 pcol=dc->color;
dc->color=BLACK;
GrRndRect(dc, dc->width/2-DIALOGW/2, dc->height/2-DIALOGH/2,
DIALOGW, DIALOGH, FONT_WIDTH);
dc->color=WHITE;
GrRndRect(dc, dc->width/2-DIALOGW/2, dc->height/2-DIALOGH/2,
DIALOGW, DIALOGH, FONT_WIDTH/2);
switch (win)
{
case W_WIN:
dc->color=GREEN;
GrPrint(dc, dc->width/2-4*FONT_WIDTH, dc->height/2-FONT_HEIGHT/2-FONT_HEIGHT, "You win!");
break;
case W_FAIL:
dc->color=RED;
GrPrint(dc, dc->width/2-4.5*FONT_WIDTH, dc->height/2-FONT_HEIGHT/2-FONT_HEIGHT, "You lose!");
break;
}
dc->color=BLACK;
GrPrint(dc, dc->width/2-13*FONT_WIDTH, dc->height/2-FONT_HEIGHT/2+FONT_HEIGHT, "Press ENTER to play again!");
dc->color=pcol;
}
U0 DrawTable(CDC *dc=gr.dc)
{
I64 i,j;
I64 type;
U8 ch;
I64 w=(LT_SZ+LT_RAD*2+LT_SPACING)*WLEN;
I64 h=(LT_SZ+LT_RAD*2+LT_SPACING)*WDEPTH;
I64 offx=dc->width/2-w/2;
I64 offy=dc->height/2-h/2;
for (i=0; i<WDEPTH; i++) {
for (j=0; j<WLEN; j++) {
ch=gameTable[j+WLEN*i];
type=LT_EMP;
if (cdepth <= i) {
type=LT_SEL;
goto draw_table_next;
}
if (ch == word[j]) {
type=LT_OK;
goto draw_table_next;
}
if (U8InStr(ch, word)) {
type=LT_POS;
goto draw_table_next;
}
draw_table_next:
DrawLetter(dc, ch, type, j*(LT_SZ+LT_SPACING+LT_RAD*2)+offx, i*(LT_SZ+LT_SPACING+LT_RAD*2)+offy);
}
if (cdepth == i && win == W_NONE)
GrArrow3(dc, w+LT_RAD*2+offx, LT_CY+(LT_SZ+LT_SPACING+LT_RAD*2)*i+offy, 0, w+LT_RAD+offx, LT_CY+(LT_SZ+LT_SPACING+LT_RAD*2)*i+offy, 0);
}
}
I64 CheckWin()
{
if (cdepth == 0) return W_NONE;
if (StrCmp(gameTable+(cdepth-1)*WLEN, word) == 0) return W_WIN;
if (cdepth == WDEPTH) return W_FAIL;
return W_NONE;
}
U0 WordleDrawIt(CTask *, CDC *dc)
{
DrawTable(dc);
if (gcheats==ON) {
GrPrint(dc, FONT_WIDTH, FONT_HEIGHT, "Cheats ON!\nWord: %s", word);
}
GrPrint(dc, dc->width-FONT_WIDTH*21, FONT_HEIGHT, "Toggle theme: CTRL-T\n Quit: CTRL-Q | ESC");
GrPrint(dc, dc->width-FONT_WIDTH*(StrLen(version)+1), dc->height-(FONT_HEIGHT*3), version);
DrawWin(dc);
}
U0 ResetGame()
{
I64 i;
I64 randomWord = RandRng(,wcnt);
word = wwords[randomWord];
if (word == NULL)
throw('WN');
cdepth=0;
for (i=0; i<WDEPTH*WLEN+1; i++) {
gameTable[i] = '\0';
}
win=W_NONE;
}
U0 Wordle()
{
U64 sc;
I64 i;
wcnt = WordInit();
if (wwords == NULL)
throw('WLN');
gameTable = MAlloc(sizeof(U8)*WDEPTH*WLEN+1);
ResetGame();
SettingsPush();
DocClear();
AutoComplete();
WinBorder();
WinMax();
DocCursor();
if (wdark)
WordleDark();
else
WordleLight();
Fs->draw_it = &WordleDrawIt;
I64 wbase,len;
U8 *cheatCode="elephants";
I64 cheatIdx=0;
try {
while (TRUE) {
wbase=cdepth*WLEN;
len=StrLen(gameTable+wbase);
U8 key = GetKey(&sc);
switch (key) { // FIXME: This can probably be optimized further
case 'a'...'z':
if (key == cheatCode[cheatIdx])
cheatIdx++;
else
cheatIdx=0;
if (cheatIdx == StrLen(cheatCode))
gcheats=!gcheats;
if (win != W_NONE) break;
if (wbase+len >= (cdepth+1)*WLEN) break;
if (cdepth != 0)
if (wbase+len <= (cdepth-1)*WLEN) break;
if (len <= WLEN) {
gameTable[wbase+len] = key;
}
break;
case CH_BACKSPACE:
if (win != W_NONE) break;
if (wbase+len > (cdepth+1)*WLEN) break;
if (cdepth != 0)
if (wbase+len <= (cdepth-1)*WLEN) break;
if (len > 0) {
gameTable[wbase+len-1] = '\0';
}
break;
case '\n':
if (win != W_NONE) {
ResetGame();
break;
}
if (len == 5)
cdepth++;
win = CheckWin();
break;
case CH_CTRLT:
if (wdark)
WordleLight();
else
WordleDark();
wdark=!wdark;
break;
case CH_CTRLQ:
case CH_SHIFT_ESC:
case CH_ESC:
goto wordle_done;
}
}
} catch PutExcept;
wordle_done:
Free(gameTable);
for (i=0; i<wcnt; i++)
Free(wwords[i]);
Free(wwords);
SettingsPop();
MenuPop();
}
"\n";

6
tos_project.toml Normal file
View File

@ -0,0 +1,6 @@
[General]
Name="wordletos"
Author="Slendi"
Version="0.1"
[Dependencies]