Coder Social home page Coder Social logo

brianpugh / game-and-watch-patch Goto Github PK

View Code? Open in Web Editor NEW
136.0 13.0 21.0 1.36 MB

CFW for the Nintendo Game and Watch

License: BSD 3-Clause "New" or "Revised" License

C 97.80% Makefile 0.10% Python 1.68% Dockerfile 0.01% Assembly 0.41%
nintendo game-and-watch gnw cfw custom hack mod retro-go zelda firmware

game-and-watch-patch's Introduction

Custom firmware for the newer Nintendo Game and Watch consoles.

Click to play demo

What is this?

This repo contains custom code as well as a patching utility to add additional functionality to the stock Game and Watch firmware. In short, this project allows you to run the firmware your game and watch came with along side retro-go.

Features

  • Works correctly with retro-go in internal flash bank 2.
  • Press button combination (LEFT + GAME) to launch retro-go from internal flash bank 2.
  • Run make help to see all configuration options.

Mario (PATCH_PARAMS="--device=mario")

  • Ability to store the entire firmware in internal flash! No external flash required!
    • Option to remove the "Mario Song" easter egg.
    • Option to remove the 5 sleeping illustrations.
    • LZMA compressed data.
    • Intelligently move as much data to internal firmware as possible.
  • Configurable timeouts.
  • Ability to play SMB1 ROM hacks via --smb1=path-to-patched-smb1-rom.nes
  • Ability to dynamically load SMB1 ROM hack sprites for the clock via --smb1-graphics=path-to-patch.ips
    • Can add up to 8 additional graphics sets.
    • Cycle through via the down button on the clock screen.
    • Add all your ips files to ips/ and have the patcher automatically discover them via the flag --smb1-graphics-glob
  • Dumps SMB1 and SMB2 ROMs that are playable by other emulators.
  • See the mario document for more information.

Zelda (PATCH_PARAMS="--device=zelda")

Usage

This repo uses the gnwmanager cli tool. See it's instructions on how to install.

Install game-and-watch-patch python dependencies (>=python3.6 required) via:

pip3 install -r requirements.txt

Place your internal_flash_backup_${DEVICE}.bin and flash_backup_${DEVICE}.bin in the root of this repo. To extract these from your gnw system, see the gnwmanager unlock tutorial. For example, if we are patching the mario game and watch, we need the files internal_flash_backup_mario.bin and flash_backup_mario.bin in the root directory of this project.

See the appropriate section below for your device model.

For additional configuration options, run make help.

Retro Go (Mario)

Since most people are going to be using this with retro-go, want the minimum amount of external storage used, and don't care about the sleeping images or the mario song easter egg, here are the recommend commands. Note that this uses an undocumented 128KB of internal Bank 1 and requires a patched version of openocd installed.

# in this repo
make clean
make PATCH_PARAMS="--device=mario --internal-only" flash

# in the retro-go repo
make clean
make -j8 INTFLASH_BANK=2 flash

Retro Go (Zelda)

This assumes you have upgraded the external flash to something larger than 4MB. See the zelda document for using retro-go with the stock 4MB flash chip.

# in this repo
make clean
make PATCH_PARAMS="--device=zelda" flash

# in the retro-go repo
make clean
# In this example, I'm assuming you have a 64MB flash chip (60 = 64 - 4)
make -j8 EXTFLASH_SIZE_MB=60 EXTFLASH_OFFSET=4194304 INTFLASH_BANK=2 flash

Build and flash using Docker

If you are familiar with Docker and prefer a solution where you don't have to manually install toolchains and so on, expand this section and read on. To reduce the number of potential pitfalls in installation of various software, a Dockerfile is provided containing everything needed to compile and flash Custom Firmware (CFW) to your Nintendo® Game & Watch™ system. This Dockerfile is written tageting an x86-64 machine running Linux.

Steps to flash from a docker container (running on Linux, e.g. Archlinux or Ubuntu):

# Go into the docker directory of this repo.
cd docker/

# Pull the pre-built docker image.
docker pull brianpugh/game-and-watch-patch:latest

# When done, use the image to create a container with the attached docker-compose.yaml file.
# You have to edit the compose file and set the path to the directory with your firmware backup (volumes section of the file).
docker compose up -d

# This will create and run a container game-and-watch-patch.
# The firmware backup files will be mounted into /tmp/firmware of the container.
# Now, go inside the container copy the backup files and proceed as described above in the Usage section.
docker exec -it game-and-watch-patch /bin/bash

If you run into permission issues, ensure that your user is in the docker group.

Troubleshooting/FAQ:

Unable to install python dependency keystone-engine on rpi3

If you are unable to install keystone-engine on a raspberry pi 3, try:

  1. Update the GPU RAM to 16MB from raspi-config
  2. Build and install keystone-engine from source (should take ~15 minutes):
git clone https://github.com/keystone-engine/keystone
cd keystone/bindings/python/
python3 -m pip install .

Development

Main stages to developing a feature:

  1. Find a place to take control in the stock rom (usually function calls).
  2. Add the stock function and its address to Core/Inc/stock_firmware.h.
  3. Implement your own function, possibly in Core/Src/main.c. There's a good chance your custom function will call the function in (2). You will also probably have to add -Wl,--undefined=my_custom_function to LDFLAGS in the Makefile so that it doesn't get optimized out as unreachable code.
  4. Add a patch definition to patches/patches.py.

Journal

This is my first time ever developing patches for a closed source binary. I documented my journey in hopes that it helps other people. If you have any recommendations, tips, tricks, or anything like that, please leave a github issue and I'll update the documentation!

Acknowledgement

Thanks to the community that made this possible! This repo was built with the help of others. Repos referenced during the development of this project:

I would also like to thank the stacksmashing discord for all the help (special shoutout to @cyanic)!

game-and-watch-patch's People

Contributors

benjaminsoelberg avatar brianpugh avatar chunter789 avatar luisfcorreia avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

game-and-watch-patch's Issues

gw_retro_go.elf section doesn't fit using Zelda documentation - Stock 4MB Flash Chip

Hi,
I installed game-and-watch-noob-installer to patch my Game and Watch Zelda (Stock).

All steps under backup (also restore) go fine.
Also step:
make PATCH_PARAMS="--device=zelda --no-la --no-sleep-images" flash
goes fine (and I saw that Link's Awakening from start menu didn't work as I expected)

Using
make -j8 INTFLASH_BANK=2 EXTFLASH_SIZE=1794336 EXTFLASH_OFFSET=860160 ADAPTER=stlink GNW_TARGET=zelda flash

I obtain

/opt/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld: build/gw_retro_go.elf section ._saveflash' will not fit in region SAVEFLASH' /opt/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld: build/gw_retro_go.elf section ._fbflash' will not fit in region FBFLASH' /opt/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld: region SAVEFLASH' overflowed by 3808 bytes
/opt/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld: region FBFLASH' overflowed by 3808 bytes

If you are interested I'm using windows with WSL2 and STLink2 Clone (connected to wsl2 using usbipd.exe)

embedded:startup.tcl:1225: Error:

Hello Brian

hope you are doing great!

Despite what flashing command I use I always get this error at the end. The flash works, device boots though

Info : starting gdb server for stm32h7x.cpu0 on 3333
Info : Listening on port 3333 for gdb connections
Error executing event reset-end on target stm32h7x.cpu0:
embedded:startup.tcl:1225: Error:
in procedure 'ocd_process_reset'
in procedure 'ocd_process_reset_inner' called at file "embedded:startup.tcl", line 1225

Also when using following command

make PATCH_PARAMS="--device=zelda --no-la --no-sleep-images --triple-boot" flash

the flash External Firmware still shows 419.... bytes instead of expected reduced size of 330... bytes.

    Internal Firmware Used:  121352 bytes
        Free: 9720 bytes
    Compressed Memory Used: 0 bytes
        Free: 0 bytes
    External Firmware Used: 4194304 bytes

Dual stock firmware (Zelda+Mario) in a single device.

Hello! Thank you for your hard work, this project is really magnificent!
One question though. Could we have triple-firmware (Zelda+Mario+RetroGo) working in a single Zelda device assuming that SPI is changed to something bigger? I tried to flash Mario internal-only binary to both 8020000 (second 128kb of bank1) or bank2 - it just gives black screen when switching with Game+</>, so I assuming some patching needs to be done.
Please let me know if this is possible somehow, thanks!

PY_SSIZE_T_CLEAN macro must be defined for '#' formats

I tried to use script on the Ubuntu with installed Python 3.10.4
and I got error:

Traceback (most recent call last):
  File "/home/up/opt/game-and-watch-patch/patch.py", line 178, in <module>
    main()
  File "/home/up/opt/game-and-watch-patch/patch.py", line 104, in main
    device.crypt()  # Decrypt the external firmware
  File "/home/up/opt/game-and-watch-patch/patches/firmware.py", line 492, in crypt
    self.external.crypt(self.internal.key, self.internal.nonce)
  File "/home/up/opt/game-and-watch-patch/patches/firmware.py", line 414, in crypt
    aes = AES.new(key, AES.MODE_ECB)
  File "/home/up/.local/lib/python3.10/site-packages/Crypto/Cipher/AES.py", line 95, in new
    return AESCipher(key, *args, **kwargs)
  File "/home/up/.local/lib/python3.10/site-packages/Crypto/Cipher/AES.py", line 59, in __init__
    blockalgo.BlockAlgo.__init__(self, _AES, key, *args, **kwargs)
  File "/home/up/.local/lib/python3.10/site-packages/Crypto/Cipher/blockalgo.py", line 141, in __init__
    self._cipher = factory.new(key, *args, **kwargs)
SystemError: PY_SSIZE_T_CLEAN macro must be defined for '#' formats
make: *** [Makefile:264: build/internal_flash_patched.bin] Error 1

I'm not a specialist in python. Google tells that some define should be used to compile modules. Probably some module is deprecated.

Raspberry 3 cant compile ?!

Hi,
Having trouble to compile the image according to the manual.

basically it fails during install of the keystone-engine package.
also maybe a point was to extende the swap which froze the pi at 43% during keystone engine compile.

pip3 install -r requirements.txt

keystone-engine-0.9.2.tar.gz
output is

  -- Generating done
  -- Build files have been written to: /tmp/pip-install-9fldl7ig/keystone-engine_aec0dce891ea4b8b811b9b772471acf2/src/build
  [ 67%] Built target keystone
  [ 68%] Built target fuzz_asm_ppc32be
  [ 70%] Built target fuzz_asm_mips
  [ 71%] Built target fuzz_asm_arm_thumb
  [ 73%] Built target fuzz_asm_mips64
  [ 73%] Built target fuzz_asm_hex
  [ 77%] Built target fuzz_asm_arm_thumbv8be
  [ 77%] Built target fuzz_asm_armv8_arm
  [ 77%] Built target fuzz_asm_arm_thumbv8
  [ 78%] Built target fuzz_asm_systemz
  [ 79%] Built target fuzz_asm_x86_64
  [ 80%] Built target fuzz_asm_arm_armv8be
  [ 81%] Built target fuzz_asm_evm
  [ 82%] Built target fuzz_asm_x86_16
  [ 83%] Built target fuzz_asm_arm_arm
  [ 85%] Built target fuzz_asm_x86_32
  [ 87%] Built target fuzz_asm_arm_thumbbe
  [ 88%] Built target fuzz_asm_arm64_arm
  [ 89%] Built target fuzz_asm_ppc64
  [ 91%] Built target fuzz_asm_ppc64be
  [ 93%] Built target fuzz_asm_mipsbe
  [ 94%] Built target fuzz_asm_mips64be
  [ 96%] Built target fuzz_asm_sparcbe
  [ 97%] Built target fuzz_asm_sparc
  [ 98%] Built target fuzz_asm_sparc64be
  [100%] Built target fuzz_asm_arm_armbe
  error: [Errno 2] No such file or directory: '/tmp/pip-install-9fldl7ig/keystone-engine_aec0dce891ea4b8b811b9b772471acf2/src/build/llvm/lib64/libkeystone.so'
  [end of output]

note: This error originates from a subprocess, and is likely not a problem with pip.
error: legacy-install-failure

× Encountered error while trying to install package.
╰─> keystone-engine

OS Rasbian 32bit release from 22.9.22
any hints?

--watchonly feature suggestion

First of all many thanks for your awesome work on this project! In case you want to keep pushing it further, one feature that I personally would love to see is having something like a --watchonly option that strips SMB1, SMB2 & Ball and only leaves the watch, so that when you press GAME it would jump directly into Retro-go (as SMB1, SMB2 & original Ball can run emulated anyway).

最新更新的版本有系统bug

最新更新的双系统刷进去后最后显示
Info : clock speed 1800 kHz
Info : STLINK V2J17S4 (API v2) VID:PID 0483:3748
Info : Target voltage: 2.757715
Info : [stm32h7x.cpu0] Cortex-M7 r1p1 processor detected
Info : [stm32h7x.cpu0] target has 8 breakpoints, 4 watchpoints
Error executing event examine-end on target stm32h7x.cpu0:
read_memory: failed to read memory
Info : starting gdb server for stm32h7x.cpu0 on 3333
Info : Listening on port 3333 for gdb connections
Warn : target was in unknown state when halt was requested
Info : Halt timed out, wake up GDB.
Error: timed out while waiting for target halted

然后机器是黑屏不能开机,任何按钮都没反应。重置电池后乍眼看好像是能用,实际按game+Right会死机,按任何按钮都不能重置,只能重新重置电池,用旧版本就没问题。

Patch OG Firmware to support MX25U51245GZ4I54

MX25U51245GZ4I54 difers to the MX25U51245GZ4I00 in the number of dummy cycles that must be inserted for READ operations (always 10 instead of between 6 to 8 depending on the frequency) and the addressing mode (it is always 32bit).

Tim had added the required patches to his software for the Mario G&W. Firmware Patcher but then discontinued the development. I was hoping you would be willing to "port" the support for special Flash chips to the Zelda G&W. I did diff his changes back in spring. What I know so far is that he patches/replaces 5 functions of original firmware:

  • Flash Init, called from:
    • 0x080061a4
    • 0x08006378
  • SPI Command, called from:
    • 0x08007422
    • 0x0800749a
    • 0x0800751a
    • 0x0800759c
    • 0x08007604
    • 0x08007684
    • 0x08007762
    • 0x080077d0
    • 0x08007852
    • 0x08007888
  • Read Flash Status Register, called from:
    • 0x08004f98
    • 0x08004ff6
  • Write Flash Status Register, called from:
    • 0x08004fd8
  • Reset Flash, called from:
    • 0x08004828

[ZELDA] GB games resets retro-go config (and sometimes BSOD)

Hello @BrianPugh, I'm experimenting to take a little more advantage of the stock zelda, I hope you still have the disassembly at hand 👯

I have seen that if you run GB zeldas several times, changing the language, running and resetting the game. It deletes a code area supposedly available. We should not allow to run the gameboy emulator, to avoid problems if --no-la is used.

Sometimes its corrupt the retro-go config and when you load any rom... BSODs 💥

imagen

If you tell me some NOP to avoid it I'll upload it as PR.

Thanks for your great work 👍

Error: Target not halted

Hi,

Thanks for your works!

I replaced external Flash Rom with a 64MB chip and followed instructions to program the patch.
But I got following error message:

make PATCH_PARAMS="--device=zelda" LARGE_FLASH=1 flash_patched

python3 scripts/check_env_vars.py "flash_patched" build/env "--device=zelda"
/usr/local/bin/openocd -f openocd/interface_"stlink".cfg
-c "init; halt;"
-c "program build/internal_flash_patched.bin 0x08000000 "";"
-c "reset; exit;"
Open On-Chip Debugger 0.12.0+dev-00440-ge8e09b1b5 (2023-12-20-14:08)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
none separate
Info : clock speed 1800 kHz
Info : STLINK V2J29S7 (API v2) VID:PID 0483:3748
Info : Target voltage: 3.124936
Info : [stm32h7x.cpu0] Cortex-M7 r1p1 processor detected
Info : [stm32h7x.cpu0] target has 8 breakpoints, 4 watchpoints
Info : [stm32h7x.cpu0] Examination succeed
Info : starting gdb server for stm32h7x.cpu0 on 3333
Info : Listening on port 3333 for gdb connections
Warn : target was in unknown state when halt was requested
[stm32h7x.cpu0] halted due to debug-request, current mode: Thread
xPSR: 0x81000000 pc: 0x08013652 msp: 0x2001ff78
[stm32h7x.cpu0] halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x0801368c msp: 0x20020000
Info : Device: STM32H7Ax/7Bx
Info : flash size probed value 128k
Info : STM32H7 flash has a single bank
Info : Bank (0) size is 128 kb, base address is 0x08000000
Initializing Octo-SPI interface
Info : device has to be switched to 4-byte addresses
Info : 4-byte address parameter table
Info : valid SFDP detected
Info : flash1 'sfdp' id = 0x3a25c2 size = 65536 KiB
Error: FSIZE in DCR(1) doesn't match actual capacity.
** Programming Started **
** Programming Finished **
Info : Device: STM32H7Ax/7Bx
Info : flash size probed value 128k
Info : STM32H7 flash has a single bank
Info : Bank (0) size is 128 kb, base address is 0x08000000
Initializing Octo-SPI interface
Error: Target not halted
Error executing event reset-end on target stm32h7x.cpu0:
embedded:startup.tcl:1225: Error:
in procedure 'ocd_process_reset'
in procedure 'ocd_process_reset_inner' called at file "embedded:startup.tcl", line 1225
if [ -s build/external_flash_patched.bin ]; then
/usr/local/bin/openocd -f "openocd/interface_stlink.cfg"
-c "init; halt;"
-c "program build/external_flash_patched.bin 0x90000000 "";"
-c "exit;"
&& make reset;
fi
Open On-Chip Debugger 0.12.0+dev-00440-ge8e09b1b5 (2023-12-20-14:08)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
none separate
Info : clock speed 1800 kHz
Info : STLINK V2J29S7 (API v2) VID:PID 0483:3748
Info : Target voltage: 3.124936
Info : [stm32h7x.cpu0] Cortex-M7 r1p1 processor detected
Info : [stm32h7x.cpu0] target has 8 breakpoints, 4 watchpoints
Info : [stm32h7x.cpu0] Examination succeed
Info : starting gdb server for stm32h7x.cpu0 on 3333
Info : Listening on port 3333 for gdb connections
Warn : target was in unknown state when halt was requested
[stm32h7x.cpu0] halted due to debug-request, current mode: Thread
xPSR: 0x81000000 pc: 0x08001ab6 msp: 0x2001b610
[stm32h7x.cpu0] halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x0801b42c msp: 0x2001b620
Info : Device: STM32H7Ax/7Bx
Info : flash size probed value 128k
Info : STM32H7 flash has a single bank
Info : Bank (0) size is 128 kb, base address is 0x08000000
Initializing Octo-SPI interface
Info : device has to be switched to 4-byte addresses
Info : 4-byte address parameter table
Info : valid SFDP detected
Info : flash1 'sfdp' id = 0x3a25c2 size = 65536 KiB
Error: FSIZE in DCR(1) doesn't match actual capacity.
** Programming Started **
** Programming Finished **
make[1]: Entering directory '/home/wells/game_watch/game-and-watch-patch'
/usr/local/bin/openocd -f openocd/interface_stlink.cfg -c "init; reset; exit"
Open On-Chip Debugger 0.12.0+dev-00440-ge8e09b1b5 (2023-12-20-14:08)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
none separate
Info : clock speed 1800 kHz
Info : STLINK V2J29S7 (API v2) VID:PID 0483:3748
Info : Target voltage: 3.124936
Info : [stm32h7x.cpu0] Cortex-M7 r1p1 processor detected
Info : [stm32h7x.cpu0] target has 8 breakpoints, 4 watchpoints
Info : [stm32h7x.cpu0] Examination succeed
Info : starting gdb server for stm32h7x.cpu0 on 3333
Info : Listening on port 3333 for gdb connections
Info : Device: STM32H7Ax/7Bx
Info : flash size probed value 128k
Info : STM32H7 flash has a single bank
Info : Bank (0) size is 128 kb, base address is 0x08000000
Initializing Octo-SPI interface
Error: Target not halted
Error executing event reset-end on target stm32h7x.cpu0:
embedded:startup.tcl:1225: Error:
in procedure 'ocd_process_reset'
in procedure 'ocd_process_reset_inner' called at file "embedded:startup.tcl", line 1225
make[1]: Leaving directory '/home/wells/game_watch/game-and-watch-patch'

=============================================

I also tried to program retro-go only and it sucessfully programmed. So I don't know where is the problem.

Thanks!

BR.
Wells.

issues flashing MX25U51245GZ4I00

Hello,

Im trying to flash a MX25U51245GZ4I00, but its not working.

i used the following cmds

in this repo

make clean
make PATCH_PARAMS="--device=zelda" flash_patched

in the retro-go repo

make clean

In this example, I'm assuming you have a 64MB flash chip (60 = 64 - 4)

make -j8 EXTFLASH_SIZE_MB=60 EXTFLASH_OFFSET=4194304 INTFLASH_BANK=2 flash

im not sure if i need to modify the make file before running cmd, i do get to the erase part but when it tries to do the next step i goes to another screen….see attachment, at first i kept getting cannot communicate with external flash, i reflowed the chip then the following message started to appear.

thanks in advance

D0B36B2B-6C5C-4601-B237-7AE06211345B

Extract more roms

Is it possible to extract the other language roms? And get the non-working roms working?

I do know my way around a hex-editor, but i don't know how to identify roms.

RIGHT+GAME return

I pressed RIGHT+GAME, the console turned off. How do I turn it back on without taking the console apart?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.