Skip to content

Instantly share code, notes, and snippets.

@furrtek
Last active May 5, 2024 21:02
Show Gist options
  • Save furrtek/36816e29565e6fd1626392e1f07e5f43 to your computer and use it in GitHub Desktop.
Save furrtek/36816e29565e6fd1626392e1f07e5f43 to your computer and use it in GitHub Desktop.
NGP Horoscope simulator
# NGP Horoscope simulator v1.1
# furrtek 2021
# Based on algorithm found in ngp_bios.bin
import sys
from datetime import datetime
if len(sys.argv) == 1:
print(sys.argv[0] + " DD/MM/YYYY")
exit()
dob = datetime.strptime(sys.argv[1], '%d/%m/%Y')
current_date = datetime.today()
current_day = current_date.day
current_month = current_date.month
current_year = current_date.year
dob_day = dob.day
dob_month = dob.month
dob_year = dob.year
# 0 is Sunday
weekday = (datetime(current_year, current_month, current_day).weekday() + 1) % 7
#print("Weekday: %d" % weekday)
# January to December
zodiac_days = [20, 19, 21, 20, 21, 22, 23, 23, 23, 24, 23, 22]
zodiac_signs = [
"Aquarius",
"Pisces",
"Aries",
"Taurus",
"Gemini",
"Cancer",
"Leo",
"Virgo",
"Libra",
"Scorpio",
"Sagittarius",
"Capricorn"]
sign_remap = [11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
lookupA = [1, 7, 6, 5, 4, 3, 2,
2, 1, 7, 6, 5, 4, 3,
3, 2, 1, 7, 6, 5, 4,
4, 3, 2, 1, 7, 6, 5,
5, 4, 3, 2, 1, 7, 6,
6, 5, 4, 3, 2, 1, 7,
7, 6, 5, 4, 3, 2, 1]
lookupB = [0, 2, 1, 1, 2, 0, 3, 2, 3, 3, 0, 0, 1, 0, 1, 0]
lookupC = [3, 4, 4, 5, 4, 4, 3, 3, 2, 2, 1, 2, 2, 3, 3, 4, 5, 3, 1, 2, 3, 3, 2, 1, 3, 5, 4, 3]
e = current_year % 10 # Lowest digit in BCD
# ffcc00
dob_month -= 1
zodiac_sign = dob_month
if dob_day < zodiac_days[dob_month]:
zodiac_sign = dob_month - 1
if zodiac_sign < 0:
zodiac_sign = 11 # Warp
print("Sign: %s" % zodiac_signs[zodiac_sign])
# ffcde6
zodiac_sign = sign_remap[zodiac_sign]
# ffce2c
d = current_day % 7
if d == 0:
d = 7
if d <= weekday: #ffce4b
if dob_month == 0:
dob_month = 12
b = 7 - d
if dob_month in [4, 6, 9, 11]:
a = 30
if dob_month != 2:
a = 31
else:
if leap_year: #ffce7a - TODO
a = 28
else:
a = 29
d = (a - b) % 7 #ffce86
b = zodiac_sign
if b < 8:
b -= 1
else:
b -= 8
a = d - 1
xsp6 = a
a += b
h = a if (a < 7) else (d + b) - 8
wa = lookupA[h * 7 + weekday]
h = (wa * wa) & 255
b = (zodiac_sign + e + current_month + h) & 3
var40c2 = b
d = (zodiac_sign * 2 + e + current_month + h) & 3
var40c4 = d
a = (zodiac_sign * 3 + e + current_month + h) & 3
var40c6 = a
if (b == d) and (b == a):
if b == 2:
var40c4 = 3
var40c6 = 0
elif a == 1:
var40c4 = 2
var40c6 = 3
elif a != 0:
var40c4 = 0
var40c6 = 1
else:
var40c4 = 1
var40c6 = 2
else:
# ffcf6a
hl = b * 4
if b == d:
var40c4 = lookupB[hl + a]
else:
if b == a:
var40c6 = lookupB[hl + d]
else:
if d == a:
var40c2 = lookupB[hl + d * 4]
# ffcfb7
d = lookupA[(xsp6 * 7) + weekday]
if current_day >= d + 7:
b = (current_day - d) // 7
var40c2 += b
if var40c2 >= 4:
var40c2 -= 4
var40c4 += b
if var40c4 >= 4:
var40c4 -= 4
var40c6 += b
if var40c6 >= 4:
var40c6 -= 4
# ffd049
zodiac_sign += weekday
level_money = lookupC[var40c2 * 7 + (zodiac_sign - 1 + b) % 7]
level_health = lookupC[var40c4 * 7 + (zodiac_sign + b * 2) % 7]
level_romance = lookupC[var40c6 * 7 + (zodiac_sign + 1 + b * 3) % 7]
sum = level_money + level_health + level_romance
level_general = sum // 3
if sum % 3 == 2:
level_general += 1
print("MONEY: %d" % level_money)
print("HEALTH: %d" % level_health)
print("ROMANCE: %d" % level_romance)
print("GENERAL: %d" % level_general)
@furrtek
Copy link
Author

furrtek commented May 5, 2024

All I was able to find from that time is a partially commented disassembly of the NGPC bios: https://file.io/07BvQGXxmt5n
The horoscope stuff starts around FFCC00.

@city41
Copy link

city41 commented May 5, 2024

This is great, thanks! If I succeed in fully figuring it out I'll post a link to the repo here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment